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/04/22 02:31:40 UTC

[james-project] branch master updated (2179ab3 -> 8f0c332)

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

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


    from 2179ab3  Merge remote-tracking branch 'mine/jdk-11'
     new 2844512  JAMES-2997 Move james-server-utils InputStream in a dedicated io package
     new b81e1fe  JAMES-2997 Provide an efficient 'size' input stream
     new 75e04cd  JAMES-2997 step #1 Rely on AttachmentContentLoader within scanning search
     new 8f286b5  JAMES-2997 step #2 Remove Attachment::toBlob method
     new a8e33ba  JAMES-2997 step #3 Rely on AttachmentContent loader for JMAP-draft message creation
     new 0d0607d  JAMES-2997 step #4 Implement AttachmentMapper::loadAttachmentContent
     new e3c4567  JAMES-2997 step #5 Implement AttachmentMapper::storeAttachmentForOwner
     new af96d34  JAMES-2997 step #6 Remove AttachmentManager::storeAttachmentsForMessage unused method
     new 93b7d28  JAMES-2997 step #7 Do not rely on properties to determine if a message has attachment
     new 431a8e1  JAMES-2997 step #8 Stop relying on Attachment byte array in AttachmentMapper::storeAttachmentsForMessage
     new 6a75ba7  JAMES-2997 step #9 CassandraAttachmentDAO should not rely on bytes field
     new 935e1f5  JAMES-2997 step #10 Mailbox backend is responsible of creating messageAttachments
     new 06d3b79  JAMES-2997 step #11 Remove bytes from attachment
     new 0f4142e  JAMES-2997 step #12 Attachment builder should require attachmentId
     new c75ecc3  JAMES-2997 step #13 StoreMessageIdManager should rely on StoreRightManager
     new 3d46590  JAMES-2997 Renable StoreBlobManagerTest
     new 2fc93a7  JAMES-2997 Renable AttachmentTest
     new 5ed32bf  JAMES-2997 Renable BlobTest
     new aad93eb  JAMES-2997 Renable AttachmentMapperTest
     new 09c2ebb  JAMES-2997 Renable BlobTest AbstractMailboxManagerAttachmentTest
     new 45ef5e4  JAMES-2997 Renable SetMessagesCreationProcessorTest
     new 7f7da1e  JAMES-2997 Renable MIMEMessageConverterTest
     new 18530db  JAMES-2997 Renable MessageParserTest
     new acf750d  JAMES-2997 Renable and relocate search tests
     new f6d9341  JAMES-2997 Renable SetMessagesMethodTest
     new 98e3719  [REFACTORING] Favor composition over inheritance in order to instantiate messages
     new f407fba  [REFACTORING] Favor composition over inheritance in order to parse and store attachments
     new d260409  JAMES-2997 step #8 Stop relying on Attachment byte array in AttachmentMapper::storeAttachmentsForMessage
     new e72c2cd  JAMES-2997 step #14 Abstract message storage
     new 7cdf09d  JAMES-2997 JPA and maildir should generate fix AttachmentId
     new a5ea96d  JAMES-2990 s/SizeInputStream/CurrentPositionInputStream/
     new ee9c1b5  JAMES-2997 Fix checkstyle in AttachmentMapper
     new 23725df  JAMES-2997 Store attachments sequentially with Cassandra
     new 4bc79a9  JAMES-2997 ReactorUtils::toChunk should be done on an elastic scheduler
     new be52477  JAMES-2997 step #10 Mailbox backend is responsible of creating messageAttachments
     new c6f8e0a  JAMES-2997 s/Attachment/AttachmentMetadata + s/MessageAttachment/MessageAttachmentMetadata
     new 8f0c332  JAMES-3151 HasMimeType matchers fails on empty charset

The 37 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../listeners/SetCustomFlagOnBigMessagesTest.java  |  12 +-
 mailbox/api/pom.xml                                |   1 -
 .../james/mailbox/AttachmentContentLoader.java     |  11 +-
 .../apache/james/mailbox/AttachmentManager.java    |  22 +-
 .../org/apache/james/mailbox/MessageManager.java   |  43 ++-
 .../mailbox/exception/BlobNotFoundException.java   |   5 +
 .../{Attachment.java => AttachmentMetadata.java}   |  80 +---
 .../java/org/apache/james/mailbox/model/Blob.java  |  38 +-
 ...achment.java => MessageAttachmentMetadata.java} |  31 +-
 .../apache/james/mailbox/model/MessageResult.java  |   2 +-
 .../james/mailbox/model/ParsedAttachment.java      | 136 +++++++
 .../mailbox/MailboxManagerStressContract.java      |   2 +-
 .../apache/james/mailbox/MailboxManagerTest.java   |  52 +--
 .../mailbox/manager/ManagerTestProvisionner.java   |   4 +-
 .../{BlobTest.java => AttachmentMetadataTest.java} |  72 ++--
 .../apache/james/mailbox/model/AttachmentTest.java | 155 --------
 .../org/apache/james/mailbox/model/BlobTest.java   |  13 +-
 ...est.java => MessageAttachmentMetadataTest.java} |  64 ++--
 .../mailbox/cassandra/CassandraMessageManager.java |  29 +-
 .../mailbox/cassandra/mail/AttachmentLoader.java   |  12 +-
 .../cassandra/mail/CassandraAttachmentDAOV2.java   |  12 +-
 .../cassandra/mail/CassandraAttachmentMapper.java  |  66 ++--
 .../cassandra/mail/CassandraMessageDAO.java        |   4 +-
 .../cassandra/mail/MessageRepresentation.java      |   4 +-
 .../cassandra/CassandraMailboxManagerProvider.java |   4 +-
 .../cassandra/CassandraTestSystemFixture.java      |   4 +-
 .../cassandra/mail/AttachmentLoaderTest.java       |  42 +--
 .../mail/CassandraAttachmentDAOV2Test.java         |   7 +-
 .../mail/CassandraAttachmentMapperTest.java        |   1 -
 .../CassandraMailboxManagerAttachmentTest.java     |   5 +-
 .../cassandra/mail/CassandraMessageDAOTest.java    |   8 +-
 .../MessageAttachmentRepresentationByIdTest.java   |   6 +-
 .../elasticsearch/json/IndexableMessage.java       |  13 +-
 .../ElasticSearchIntegrationTest.java              |  16 +-
 ...asticSearchListeningMessageSearchIndexTest.java |  12 +-
 .../elasticsearch/json/IndexableMessageTest.java   |  53 +--
 .../search/ElasticSearchSearcherTest.java          |   3 +-
 .../mailbox/jpa/JPAAttachmentContentLoader.java    |  20 +-
 .../james/mailbox/jpa/JPAMailboxManager.java       |  67 ----
 .../james/mailbox/jpa/JPAMessageManager.java       |  87 -----
 .../model/openjpa/AbstractJPAMailboxMessage.java   |  23 +-
 .../mailbox/jpa/openjpa/OpenJPAMailboxManager.java |  32 +-
 .../mailbox/jpa/openjpa/OpenJPAMessageFactory.java |  66 ++++
 .../mailbox/jpa/openjpa/OpenJPAMessageManager.java |  59 +--
 .../mailbox/jpa/JpaMailboxManagerProvider.java     |   2 +-
 .../lucene/search/LuceneMessageSearchIndex.java    |   5 +-
 .../mailbox/maildir/mail/model/MaildirMessage.java |  23 +-
 .../maildir/MaildirAttachmentContentLoader.java    |  29 +-
 .../maildir/MaildirMailboxManagerProvider.java     |   2 +-
 .../mailbox/inmemory/InMemoryMessageManager.java   |  26 +-
 .../inmemory/mail/InMemoryAttachmentMapper.java    |  75 +++-
 .../mail/InMemoryMailboxManagerAttachmentTest.java |   1 -
 .../inmemory/mail/MemoryAttachmentMapperTest.java  |   1 -
 .../manager/InMemoryIntegrationResources.java      |  74 ++--
 .../james/vault/DeletedMessageConverterTest.java   |  17 +-
 .../james/vault/DeletedMessageVaultHookTest.java   |   3 +-
 .../store/search/SimpleMessageSearchIndexTest.java |   3 +-
 .../apache/james/mailbox/store/MessageFactory.java |  50 +++
 .../james/mailbox/store/MessageResultImpl.java     |   4 +-
 .../apache/james/mailbox/store/MessageStorer.java  | 139 +++++++
 .../mailbox/store/StoreAttachmentManager.java      |  24 +-
 .../james/mailbox/store/StoreBlobManager.java      |  32 +-
 .../james/mailbox/store/StoreMailboxManager.java   |   4 +-
 .../james/mailbox/store/StoreMessageIdManager.java |  12 +-
 .../james/mailbox/store/StoreMessageManager.java   |  94 +----
 .../mailbox/store/StoreMessageResultIterator.java  |   4 +-
 .../james/mailbox/store/mail/AttachmentMapper.java |  16 +-
 .../store/mail/model/DelegatingMailboxMessage.java |   4 +-
 .../james/mailbox/store/mail/model/Message.java    |   4 +-
 .../store/mail/model/impl/MessageParser.java       |  29 +-
 .../store/mail/model/impl/PropertyBuilder.java     |  14 -
 .../mail/model/impl/SimpleMailboxMessage.java      |  12 +-
 .../store/mail/model/impl/SimpleMessage.java       |   8 +-
 .../mailbox/store/search/MessageSearches.java      |  43 ++-
 .../store/search/SimpleMessageSearchIndex.java     |   9 +-
 .../store/AbstractCombinationManagerTest.java      |  62 ++--
 .../AbstractMailboxManagerAttachmentTest.java      |  20 +-
 .../store/AbstractMessageIdManagerStorageTest.java |   1 +
 .../apache/james/mailbox/store/MessageBuilder.java |   4 +-
 .../mailbox/store/StoreAttachmentManagerTest.java  |  10 +-
 .../james/mailbox/store/StoreBlobManagerTest.java  |  55 +--
 .../mailbox/store/StoreMailboxManagerTest.java     |   4 +-
 .../store/mail/model/AttachmentMapperTest.java     | 295 ++++++---------
 .../model/MessageWithAttachmentMapperTest.java     |  69 ++--
 .../store/mail/model/impl/MessageParserTest.java   |  97 +++--
 .../store/mail/model/impl/PropertyBuilderTest.java |  18 +-
 .../mail/model/impl/SimpleMailboxMessageTest.java  |  12 +-
 .../search/AbstractMessageSearchIndexTest.java     |  52 +--
 .../SearchUtilsMultipartMixedTest.java             |  12 +-
 .../store/{ => search}/SearchUtilsRFC822Test.java  |  11 +-
 .../store/{ => search}/SearchUtilsTest.java        |  13 +-
 .../tools/indexer/MessageIdReIndexerImplTest.java  |   2 +-
 .../mailbox/tools/indexer/ReIndexerImplTest.java   |  12 +-
 .../james/transport/matchers/HasMimeType.java      |  32 +-
 .../james/transport/matchers/HasMimeTypeTest.java  |  35 +-
 .../cassandra/host/CassandraHostSystem.java        |  10 +-
 .../mpt/imapmailbox/jpa/host/JPAHostSystem.java    |   4 +-
 .../maildir/host/MaildirHostSystem.java            |   2 +-
 .../james/imap/processor/AppendProcessor.java      |   3 +-
 .../blob/cassandra/CassandraBlobStoreTest.java     |   2 +-
 .../apache/james/blob/mail/MimeMessageStore.java   |   2 +-
 .../core/MimeMessageInputStreamSourceTest.java     |   2 +-
 .../modules/mailbox/CassandraMailboxModule.java    |   2 +
 .../james/modules/mailbox/JPAMailboxModule.java    |   3 +
 .../org/apache/james/modules/MailboxProbeImpl.java |   4 +-
 .../james/modules/mailbox/MemoryMailboxModule.java |   2 +
 .../apache/james/jmap/draft/MessageIdProbe.java    |   4 +-
 .../james/util/{ => io}/BodyOffsetInputStream.java |   2 +-
 .../util/{ => io}/CountDownConsumeInputStream.java |   2 +-
 .../james/util/io/CurrentPositionInputStream.java  |  83 +++--
 .../james/util/io/InputStreamConsummer.java}       |  17 +-
 .../james/util/{ => io}/InputStreamUtils.java      |   2 +-
 .../james/util/{ => io}/ZeroedInputStream.java     |   2 +-
 .../james/util/BodyOffsetInputStreamTest.java      |   1 +
 .../apache/james/util/InputStreamUtilsTest.java    |   1 +
 .../util/io/CurrentPositionInputStreamTest.java    | 120 ++++++
 .../MessageFastViewPrecomputedProperties.java      |   4 +-
 .../mailets/delivery/MailboxAppender.java          |   8 +-
 .../mailets/delivery/LocalDeliveryTest.java        |   8 +-
 .../pom.xml                                        |   5 +
 .../cassandra/CassandraSetMessagesMethodTest.java  |   1 -
 .../jmap-draft-integration-testing-common/pom.xml  |   5 +
 .../methods/integration/SetMessagesMethodTest.java | 401 ++++++++++-----------
 .../integration/cucumber/DownloadStepdefs.java     |   2 +-
 .../integration/cucumber/UploadStepdefs.java       |   4 +-
 .../memory-jmap-draft-integration-testing/pom.xml  |   5 +
 .../jmap/memory/MemorySetMessagesMethodTest.java   |   2 -
 .../pom.xml                                        |   5 +
 .../RabbitMQAwsS3SetMessagesMethodTest.java        |   1 -
 .../jmap/draft/methods/MIMEMessageConverter.java   |  83 +++--
 .../james/jmap/draft/methods/MessageAppender.java  |  52 ++-
 .../james/jmap/draft/methods/SendMDNProcessor.java |  24 +-
 .../org/apache/james/jmap/draft/model/JmapMDN.java |   3 +-
 .../model/message/view/MessageFullViewFactory.java |  16 +-
 .../org/apache/james/jmap/http/DownloadRoutes.java |   3 +-
 .../org/apache/james/jmap/http/UploadRoutes.java   |  36 +-
 .../MessageFastViewProjectionItemFactoryTest.java  |   2 +-
 .../jmap/draft/methods/GetMessagesMethodTest.java  |  52 +--
 .../draft/methods/MIMEMessageConverterTest.java    | 255 +++++++------
 .../methods/SetMessagesCreationProcessorTest.java  |  12 +-
 .../methods/SetMessagesUpdateProcessorTest.java    |   4 +-
 .../message/view/MessageFastViewFactoryTest.java   |   8 +-
 .../message/view/MessageFullViewFactoryTest.java   |  11 +-
 .../message/view/MessageHeaderViewFactoryTest.java |   2 +-
 .../view/MessageMetadataViewFactoryTest.java       |   2 +-
 .../jmap/draft/send/PostDequeueDecoratorTest.java  |  16 +-
 ...mputeMessageFastViewProjectionListenerTest.java |  12 +-
 ...llFastViewProjectionItemsRequestToTaskTest.java |   4 +-
 ...erFastViewProjectionItemsRequestToTaskTest.java |   4 +-
 .../webadmin/vault/routes/RestoreService.java      |   2 +-
 .../james/webadmin/routes/MailboxesRoutesTest.java |  16 +-
 .../james/webadmin/routes/MessageRoutesTest.java   |   4 +-
 .../webadmin/routes/UserMailboxesRoutesTest.java   |   4 +-
 .../james/webadmin/service/ExportServiceTest.java  |   3 +-
 .../service/MailboxesExportRequestToTaskTest.java  |   4 +-
 155 files changed, 2272 insertions(+), 2060 deletions(-)
 copy server/blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/PayloadCodec.java => mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentContentLoader.java (78%)
 rename mailbox/api/src/main/java/org/apache/james/mailbox/model/{Attachment.java => AttachmentMetadata.java} (62%)
 rename mailbox/api/src/main/java/org/apache/james/mailbox/model/{MessageAttachment.java => MessageAttachmentMetadata.java} (79%)
 create mode 100644 mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java
 copy mailbox/api/src/test/java/org/apache/james/mailbox/model/{BlobTest.java => AttachmentMetadataTest.java} (54%)
 delete mode 100644 mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java
 rename mailbox/api/src/test/java/org/apache/james/mailbox/model/{MessageAttachmentTest.java => MessageAttachmentMetadataTest.java} (63%)
 copy server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/GetVacationRequestTest.java => mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAAttachmentContentLoader.java (70%)
 delete mode 100644 mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMailboxManager.java
 delete mode 100644 mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java
 create mode 100644 mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageFactory.java
 copy server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/exceptions/JmapFieldNotSupportedException.java => mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirAttachmentContentLoader.java (70%)
 create mode 100644 mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageFactory.java
 create mode 100644 mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageStorer.java
 rename mailbox/store/src/test/java/org/apache/james/mailbox/store/{ => search}/SearchUtilsMultipartMixedTest.java (97%)
 rename mailbox/store/src/test/java/org/apache/james/mailbox/store/{ => search}/SearchUtilsRFC822Test.java (93%)
 rename mailbox/store/src/test/java/org/apache/james/mailbox/store/{ => search}/SearchUtilsTest.java (99%)
 rename server/container/util/src/main/java/org/apache/james/util/{ => io}/BodyOffsetInputStream.java (99%)
 rename server/container/util/src/main/java/org/apache/james/util/{ => io}/CountDownConsumeInputStream.java (98%)
 copy protocols/pop3/src/main/java/org/apache/james/protocols/pop3/core/ExtraDotInputStream.java => server/container/util/src/main/java/org/apache/james/util/io/CurrentPositionInputStream.java (55%)
 copy server/{blob/blob-objectstorage/src/main/java/org/apache/james/blob/objectstorage/PayloadCodec.java => container/util/src/main/java/org/apache/james/util/io/InputStreamConsummer.java} (80%)
 rename server/container/util/src/main/java/org/apache/james/util/{ => io}/InputStreamUtils.java (97%)
 rename server/container/util/src/main/java/org/apache/james/util/{ => io}/ZeroedInputStream.java (97%)
 create mode 100644 server/container/util/src/test/java/org/apache/james/util/io/CurrentPositionInputStreamTest.java


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


[james-project] 31/37: JAMES-2990 s/SizeInputStream/CurrentPositionInputStream/

Posted by bt...@apache.org.
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 a5ea96dc51d2bc4b5f4421045048002c4720702c
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed Feb 5 11:46:28 2020 +0700

    JAMES-2990 s/SizeInputStream/CurrentPositionInputStream/
---
 .../cassandra/mail/CassandraAttachmentMapper.java  |  11 +-
 ...Stream.java => CurrentPositionInputStream.java} |  16 +--
 .../util/io/CurrentPositionInputStreamTest.java    | 120 +++++++++++++++++++++
 .../apache/james/util/io/SizeInputStreamTest.java  | 111 -------------------
 4 files changed, 133 insertions(+), 125 deletions(-)

diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
index 84e6022..62ed3f0 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
@@ -40,7 +40,7 @@ import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.util.ReactorUtils;
-import org.apache.james.util.io.SizeInputStream;
+import org.apache.james.util.io.CurrentPositionInputStream;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -112,17 +112,16 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
 
     @Override
     public Mono<Attachment> storeAttachmentForOwner(String contentType, InputStream inputStream, Username owner) {
-        SizeInputStream sizeInputStream = new SizeInputStream(inputStream);
+        CurrentPositionInputStream currentPositionInputStream = new CurrentPositionInputStream(inputStream);
         AttachmentId attachmentId = AttachmentId.random();
-
         return ownerDAO.addOwner(attachmentId, owner)
-            .flatMap(any -> Mono.from(blobStore.save(blobStore.getDefaultBucketName(), sizeInputStream, LOW_COST)))
-            .map(blobId -> new DAOAttachment(attachmentId, blobId, contentType, sizeInputStream.getSize()))
+            .flatMap(any -> Mono.from(blobStore.save(blobStore.getDefaultBucketName(), currentPositionInputStream, LOW_COST)))
+            .map(blobId -> new DAOAttachment(attachmentId, blobId, contentType, currentPositionInputStream.getPosition()))
             .flatMap(attachmentDAOV2::storeAttachment)
             .map(any -> Attachment.builder()
                 .attachmentId(attachmentId)
                 .type(contentType)
-                .size(sizeInputStream.getSize())
+                .size(currentPositionInputStream.getPosition())
                 .build());
     }
 
diff --git a/server/container/util/src/main/java/org/apache/james/util/io/SizeInputStream.java b/server/container/util/src/main/java/org/apache/james/util/io/CurrentPositionInputStream.java
similarity index 90%
rename from server/container/util/src/main/java/org/apache/james/util/io/SizeInputStream.java
rename to server/container/util/src/main/java/org/apache/james/util/io/CurrentPositionInputStream.java
index f289e31..a739e9d 100644
--- a/server/container/util/src/main/java/org/apache/james/util/io/SizeInputStream.java
+++ b/server/container/util/src/main/java/org/apache/james/util/io/CurrentPositionInputStream.java
@@ -24,13 +24,13 @@ import java.io.InputStream;
 
 import org.apache.commons.lang3.NotImplementedException;
 
-public class SizeInputStream extends InputStream {
+public class CurrentPositionInputStream extends InputStream {
     private final InputStream wrapped;
-    private long size;
+    private long position;
 
-    public SizeInputStream(InputStream wrapped) {
+    public CurrentPositionInputStream(InputStream wrapped) {
         this.wrapped = wrapped;
-        this.size = 0L;
+        this.position = 0L;
     }
 
     @Override
@@ -38,7 +38,7 @@ public class SizeInputStream extends InputStream {
         int read = wrapped.read();
 
         if (read > 0) {
-            size++;
+            position++;
         }
 
         return read;
@@ -87,14 +87,14 @@ public class SizeInputStream extends InputStream {
         return false;
     }
 
-    public long getSize() {
-        return size;
+    public long getPosition() {
+        return position;
     }
 
     private <T extends Number> T increaseSize(T chunkSize) {
         long longValue = chunkSize.longValue();
         if (longValue > 0) {
-            size += longValue;
+            position += longValue;
         }
         return chunkSize;
     }
diff --git a/server/container/util/src/test/java/org/apache/james/util/io/CurrentPositionInputStreamTest.java b/server/container/util/src/test/java/org/apache/james/util/io/CurrentPositionInputStreamTest.java
new file mode 100644
index 0000000..80da272
--- /dev/null
+++ b/server/container/util/src/test/java/org/apache/james/util/io/CurrentPositionInputStreamTest.java
@@ -0,0 +1,120 @@
+/****************************************************************
+ * 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.                                           *
+ ****************************************************************/
+
+package org.apache.james.util.io;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.stream.IntStream;
+
+import org.junit.jupiter.api.Test;
+
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Strings;
+
+class CurrentPositionInputStreamTest {
+    static final byte[] BYTES = "0123456789".getBytes(StandardCharsets.UTF_8);
+    static final byte[] TWELVE_MEGABYTES = Strings.repeat("0123456789\r\n", 1024 * 1024).getBytes(StandardCharsets.UTF_8);
+
+    @Test
+    void positionInputStreamShouldNotAlterContent() {
+        CurrentPositionInputStream currentPositionInputStream = new CurrentPositionInputStream(new ByteArrayInputStream(BYTES));
+
+        assertThat(currentPositionInputStream).hasSameContentAs(new ByteArrayInputStream(BYTES));
+    }
+
+    @Test
+    void positionInputStreamShouldNotAlterContentOfEmptyStream() {
+        CurrentPositionInputStream currentPositionInputStream = new CurrentPositionInputStream(new ByteArrayInputStream(new byte[0]));
+
+        assertThat(currentPositionInputStream).hasSameContentAs(new ByteArrayInputStream(new byte[0]));
+    }
+
+    @Test
+    void positionInputStreamShouldNotAlterContentOfBigStream() {
+        CurrentPositionInputStream currentPositionInputStream = new CurrentPositionInputStream(new ByteArrayInputStream(TWELVE_MEGABYTES));
+
+        assertThat(currentPositionInputStream).hasSameContentAs(new ByteArrayInputStream(TWELVE_MEGABYTES));
+    }
+
+    @Test
+    void getPositionShouldReturnZeroWhenEmpty() {
+        CurrentPositionInputStream currentPositionInputStream = new CurrentPositionInputStream(new ByteArrayInputStream(new byte[0]));
+
+        assertThat(currentPositionInputStream.getPosition()).isEqualTo(0);
+    }
+
+    @Test
+    void getPositionShouldReturnPositionWhenReadWithABiggerBuffer() throws Exception {
+        CurrentPositionInputStream currentPositionInputStream = new CurrentPositionInputStream(new ByteArrayInputStream(BYTES));
+
+        currentPositionInputStream.read(new byte[24]);
+
+        assertThat(currentPositionInputStream.getPosition()).isEqualTo(10);
+    }
+
+    @Test
+    void getPositionShouldReturnPositionWhenReadWithABufferHavingSamePositionThanContent() throws Exception {
+        CurrentPositionInputStream currentPositionInputStream = new CurrentPositionInputStream(new ByteArrayInputStream(BYTES));
+
+        currentPositionInputStream.read(new byte[10]);
+
+        assertThat(currentPositionInputStream.getPosition()).isEqualTo(10);
+    }
+
+    @Test
+    void getPositionShouldReturnPositionWhenReadUsingSmallerBuffers() throws Exception {
+        CurrentPositionInputStream currentPositionInputStream = new CurrentPositionInputStream(new ByteArrayInputStream(BYTES));
+
+        currentPositionInputStream.read(new byte[6]);
+        currentPositionInputStream.read(new byte[6]);
+
+        assertThat(currentPositionInputStream.getPosition()).isEqualTo(10);
+    }
+
+    @Test
+    void getPositionShouldReturnPositionWhenReadByte() {
+        CurrentPositionInputStream currentPositionInputStream = new CurrentPositionInputStream(new ByteArrayInputStream(BYTES));
+
+        IntStream.range(0, 10).forEach(Throwing.intConsumer(step -> currentPositionInputStream.read()));
+
+        assertThat(currentPositionInputStream.getPosition()).isEqualTo(10);
+    }
+
+    @Test
+    void getPositionShouldReturnPositionWhenSkips() throws Exception {
+        CurrentPositionInputStream currentPositionInputStream = new CurrentPositionInputStream(new ByteArrayInputStream(BYTES));
+
+        currentPositionInputStream.read(new byte[6]);
+        currentPositionInputStream.skip(6);
+
+        assertThat(currentPositionInputStream.getPosition()).isEqualTo(10);
+    }
+
+    @Test
+    void getPositionShouldReturnPartialRead() throws Exception {
+        CurrentPositionInputStream currentPositionInputStream = new CurrentPositionInputStream(new ByteArrayInputStream(BYTES));
+
+        currentPositionInputStream.read(new byte[6]);
+
+        assertThat(currentPositionInputStream.getPosition()).isEqualTo(6);
+    }
+}
\ No newline at end of file
diff --git a/server/container/util/src/test/java/org/apache/james/util/io/SizeInputStreamTest.java b/server/container/util/src/test/java/org/apache/james/util/io/SizeInputStreamTest.java
deleted file mode 100644
index ece2d91..0000000
--- a/server/container/util/src/test/java/org/apache/james/util/io/SizeInputStreamTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************
- * 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.                                           *
- ****************************************************************/
-
-package org.apache.james.util.io;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.io.ByteArrayInputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.stream.IntStream;
-
-import org.junit.jupiter.api.Test;
-
-import com.github.fge.lambdas.Throwing;
-import com.google.common.base.Strings;
-
-class SizeInputStreamTest {
-    static final byte[] BYTES = "0123456789".getBytes(StandardCharsets.UTF_8);
-    static final byte[] TWELVE_MEGABYTES = Strings.repeat("0123456789\r\n", 1024 * 1024).getBytes(StandardCharsets.UTF_8);
-
-    @Test
-    void sizeInputStreamShouldNotAlterContent() {
-        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(BYTES));
-
-        assertThat(sizeInputStream).hasSameContentAs(new ByteArrayInputStream(BYTES));
-    }
-
-    @Test
-    void sizeInputStreamShouldNotAlterContentOfEmptyStream() {
-        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(new byte[0]));
-
-        assertThat(sizeInputStream).hasSameContentAs(new ByteArrayInputStream(new byte[0]));
-    }
-
-    @Test
-    void sizeInputStreamShouldNotAlterContentOfBigStream() {
-        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(TWELVE_MEGABYTES));
-
-        assertThat(sizeInputStream).hasSameContentAs(new ByteArrayInputStream(TWELVE_MEGABYTES));
-    }
-
-    @Test
-    void getSizeShouldReturnZeroWhenEmpty() {
-        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(new byte[0]));
-
-        assertThat(sizeInputStream.getSize()).isEqualTo(0);
-    }
-
-    @Test
-    void getSizeShouldReturnSizeWhenReadWithABiggerBuffer() throws Exception {
-        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(BYTES));
-
-        sizeInputStream.read(new byte[24]);
-
-        assertThat(sizeInputStream.getSize()).isEqualTo(10);
-    }
-
-    @Test
-    void getSizeShouldReturnSizeWhenReadWithABufferHavingSameSizeThanContent() throws Exception {
-        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(BYTES));
-
-        sizeInputStream.read(new byte[10]);
-
-        assertThat(sizeInputStream.getSize()).isEqualTo(10);
-    }
-
-    @Test
-    void getSizeShouldReturnSizeWhenReadUsingSmallerBuffers() throws Exception {
-        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(BYTES));
-
-        sizeInputStream.read(new byte[6]);
-        sizeInputStream.read(new byte[6]);
-
-        assertThat(sizeInputStream.getSize()).isEqualTo(10);
-    }
-
-    @Test
-    void getSizeShouldReturnSizeWhenReadByte() {
-        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(BYTES));
-
-        IntStream.range(0, 10).forEach(Throwing.intConsumer(step -> sizeInputStream.read()));
-
-        assertThat(sizeInputStream.getSize()).isEqualTo(10);
-    }
-
-    @Test
-    void getSizeShouldReturnSizeWhenSkips() throws Exception {
-        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(BYTES));
-
-        sizeInputStream.read(new byte[6]);
-        sizeInputStream.skip(6);
-
-        assertThat(sizeInputStream.getSize()).isEqualTo(10);
-    }
-}
\ No newline at end of file


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


[james-project] 30/37: JAMES-2997 JPA and maildir should generate fix AttachmentId

Posted by bt...@apache.org.
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 7cdf09deef962abce320af4b7039cebb623e9773
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Feb 4 13:37:16 2020 +0700

    JAMES-2997 JPA and maildir should generate fix AttachmentId
    
    Calling two time getAttachments() should yeld the same result...
    
    In order to do so, we adopt a `${messageIdentifier}-${attachmentPosition}` naming pattern
---
 .../mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java | 8 +++++++-
 .../apache/james/mailbox/maildir/mail/model/MaildirMessage.java   | 8 +++++++-
 .../main/java/org/apache/james/mailbox/store/MessageStorer.java   | 4 +++-
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
index 68afe5d..e3e800e 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
@@ -25,6 +25,7 @@ import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.mail.Flags;
 import javax.persistence.Basic;
@@ -507,10 +508,11 @@ public abstract class AbstractJPAMailboxMessage implements MailboxMessage {
     @Override
     public List<MessageAttachment> getAttachments() {
         try {
+            AtomicInteger counter = new AtomicInteger(0);
             return new MessageParser().retrieveAttachments(getFullContent())
                 .stream()
                 .map(Throwing.<ParsedAttachment, MessageAttachment>function(
-                    attachmentMetadata -> attachmentMetadata.asMessageAttachment(AttachmentId.random()))
+                    attachmentMetadata -> attachmentMetadata.asMessageAttachment(generateFixedAttachmentId(counter.incrementAndGet())))
                     .sneakyThrow())
                 .collect(Guavate.toImmutableList());
         } catch (IOException e) {
@@ -518,6 +520,10 @@ public abstract class AbstractJPAMailboxMessage implements MailboxMessage {
         }
     }
 
+    private AttachmentId generateFixedAttachmentId(int position) {
+        return AttachmentId.from(getMailboxId().serialize() + "-" + getUid().asLong() + "-" + position);
+    }
+
     @Override
     public boolean hasAttachment() {
         return !getAttachments().isEmpty();
diff --git a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
index b2b4725..cfdb7a3 100644
--- a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
+++ b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
@@ -25,6 +25,7 @@ import java.io.InputStream;
 import java.io.PushbackInputStream;
 import java.util.Date;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.mail.util.SharedFileInputStream;
 
@@ -275,10 +276,11 @@ public class MaildirMessage implements Message {
     @Override
     public List<MessageAttachment> getAttachments() {
         try {
+            AtomicInteger counter = new AtomicInteger(0);
             return new MessageParser().retrieveAttachments(getFullContent())
                 .stream()
                 .map(Throwing.<ParsedAttachment, MessageAttachment>function(
-                    attachmentMetadata -> attachmentMetadata.asMessageAttachment(AttachmentId.random()))
+                    attachmentMetadata -> attachmentMetadata.asMessageAttachment(generateFixedAttachmentId(counter.incrementAndGet())))
                     .sneakyThrow())
                 .collect(Guavate.toImmutableList());
         } catch (IOException e) {
@@ -286,6 +288,10 @@ public class MaildirMessage implements Message {
         }
     }
 
+    private AttachmentId generateFixedAttachmentId(int position) {
+        return AttachmentId.from(messageName.getFullName() + "-" + position);
+    }
+
     @Override
     public boolean hasAttachment() {
         return !getAttachments().isEmpty();
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageStorer.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageStorer.java
index 7b1df1d..b7b391b 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageStorer.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageStorer.java
@@ -60,6 +60,8 @@ public interface MessageStorer {
      */
     class WithAttachment implements MessageStorer {
         private static final Logger LOGGER = LoggerFactory.getLogger(WithAttachment.class);
+        private static final int START = 0;
+        private static final int UNLIMITED = -1;
 
         private final MailboxSessionMapperFactory mapperFactory;
         private final MessageId.Factory messageIdFactory;
@@ -98,7 +100,7 @@ public interface MessageStorer {
 
         private List<ParsedAttachment> extractAttachments(SharedInputStream contentIn) {
             try {
-                return messageParser.retrieveAttachments(contentIn.newStream(0, -1));
+                return messageParser.retrieveAttachments(contentIn.newStream(START, UNLIMITED));
             } catch (Exception e) {
                 LOGGER.warn("Error while parsing mail's attachments: {}", e.getMessage(), e);
                 return ImmutableList.of();


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


[james-project] 09/37: JAMES-2997 step #7 Do not rely on properties to determine if a message has attachment

Posted by bt...@apache.org.
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 93b7d28b0f82903f4ddc081620e77143f3c30a78
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Jan 17 11:07:30 2020 +0700

    JAMES-2997 step #7 Do not rely on properties to determine if a message has attachment
    
    Use attachment metadata directly
---
 .../james/mailbox/model/MessageAttachment.java     |  6 +++
 .../elasticsearch/json/IndexableMessage.java       | 13 +-----
 .../elasticsearch/json/IndexableMessageTest.java   | 53 ++++++----------------
 .../lucene/search/LuceneMessageSearchIndex.java    |  5 +-
 .../james/mailbox/store/StoreMessageManager.java   |  6 ---
 .../store/mail/model/impl/PropertyBuilder.java     | 14 ------
 .../mailbox/store/search/MessageSearches.java      |  5 +-
 .../store/mail/model/impl/PropertyBuilderTest.java | 18 ++------
 8 files changed, 31 insertions(+), 89 deletions(-)

diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageAttachment.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageAttachment.java
index 9dda554..fc37b03 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageAttachment.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageAttachment.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.mailbox.model;
 
+import java.util.List;
 import java.util.Optional;
 
 import com.google.common.base.MoreObjects;
@@ -77,6 +78,11 @@ public class MessageAttachment {
         }
     }
 
+    public static boolean hasNonInlinedAttachment(List<MessageAttachment> attachments) {
+        return attachments.stream()
+            .anyMatch(messageAttachment -> !messageAttachment.isInlinedWithCid());
+    }
+
     private final Attachment attachment;
     private final Optional<String> name;
     private final Optional<Cid> cid;
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
index 40d2b1c..1248996 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
+++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
@@ -32,9 +32,8 @@ import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.elasticsearch.IndexAttachments;
 import org.apache.james.mailbox.elasticsearch.query.DateResolutionFormater;
 import org.apache.james.mailbox.extractor.TextExtractor;
+import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
-import org.apache.james.mailbox.store.mail.model.Property;
-import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
 import org.apache.james.mailbox.store.search.SearchUtil;
 import org.apache.james.mime4j.MimeException;
 
@@ -98,12 +97,6 @@ public class IndexableMessage {
             return this;
         }
 
-        private boolean computeHasAttachment(MailboxMessage message) {
-            return message.getProperties()
-                    .stream()
-                    .anyMatch(property -> property.equals(HAS_ATTACHMENT_PROPERTY));
-        }
-
         private IndexableMessage instantiateIndexedMessage() throws IOException, MimeException {
             String messageId = SearchUtil.getSerializedMessageIdIfSupportedByUnderlyingStorageOrNull(message);
             MimePart parsingResult = new MimePartParser(message, textExtractor).parse();
@@ -111,7 +104,7 @@ public class IndexableMessage {
             Optional<String> bodyText = parsingResult.locateFirstTextBody();
             Optional<String> bodyHtml = parsingResult.locateFirstHtmlBody();
 
-            boolean hasAttachment = computeHasAttachment(message);
+            boolean hasAttachment = MessageAttachment.hasNonInlinedAttachment(message.getAttachments());
             List<MimePart> attachments = setFlattenedAttachments(parsingResult, indexAttachments);
 
             HeaderCollection headerCollection = parsingResult.getHeaderCollection();
@@ -192,8 +185,6 @@ public class IndexableMessage {
         }
     }
 
-    public static final Property HAS_ATTACHMENT_PROPERTY = new Property(PropertyBuilder.JAMES_INTERNALS, PropertyBuilder.HAS_ATTACHMENT, "true");
-
     public static Builder builder() {
         return new Builder();
     }
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessageTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessageTest.java
index 2526f14..694e521 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessageTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessageTest.java
@@ -37,12 +37,13 @@ import org.apache.james.mailbox.elasticsearch.IndexAttachments;
 import org.apache.james.mailbox.extractor.ParsedContent;
 import org.apache.james.mailbox.extractor.TextExtractor;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
+import org.apache.james.mailbox.model.Attachment;
+import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.store.extractor.DefaultTextExtractor;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
-import org.apache.james.mailbox.store.mail.model.Property;
-import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
 import org.apache.james.mailbox.tika.TikaConfiguration;
 import org.apache.james.mailbox.tika.TikaExtension;
 import org.apache.james.mailbox.tika.TikaHttpClientImpl;
@@ -306,7 +307,7 @@ class IndexableMessageTest {
     }
 
     @Test
-    void hasAttachmentsShouldReturnTrueWhenPropertyIsPresentAndTrue() throws IOException {
+    void hasAttachmentsShouldReturnTrueWhenNonInlined() throws IOException {
         //Given
         MailboxMessage  mailboxMessage = mock(MailboxMessage.class);
         TestId mailboxId = TestId.of(1);
@@ -322,7 +323,15 @@ class IndexableMessageTest {
             .thenReturn(new Flags());
         when(mailboxMessage.getUid())
             .thenReturn(MESSAGE_UID);
-        when(mailboxMessage.getProperties()).thenReturn(ImmutableList.of(IndexableMessage.HAS_ATTACHMENT_PROPERTY));
+        when(mailboxMessage.getAttachments())
+            .thenReturn(ImmutableList.of(MessageAttachment.builder()
+                .attachment(Attachment.builder()
+                    .attachmentId(AttachmentId.from("1"))
+                    .type("text/plain")
+                    .size(36)
+                    .build())
+                .isInline(false)
+                .build()));
 
         // When
         IndexableMessage indexableMessage = IndexableMessage.builder()
@@ -337,7 +346,7 @@ class IndexableMessageTest {
     }
 
     @Test
-    void hasAttachmentsShouldReturnFalseWhenPropertyIsPresentButFalse() throws IOException {
+    void hasAttachmentsShouldReturnFalseWhenEmptyAttachments() throws IOException {
         //Given
         MailboxMessage  mailboxMessage = mock(MailboxMessage.class);
         TestId mailboxId = TestId.of(1);
@@ -353,39 +362,7 @@ class IndexableMessageTest {
             .thenReturn(MESSAGE_UID);
         when(mailboxMessage.getModSeq())
             .thenReturn(ModSeq.first());
-        when(mailboxMessage.getProperties())
-            .thenReturn(ImmutableList.of(new Property(PropertyBuilder.JAMES_INTERNALS, PropertyBuilder.HAS_ATTACHMENT, "false")));
-
-        // When
-        IndexableMessage indexableMessage = IndexableMessage.builder()
-                .message(mailboxMessage)
-                .extractor(new DefaultTextExtractor())
-                .zoneId(ZoneId.of("Europe/Paris"))
-                .indexAttachments(IndexAttachments.NO)
-                .build();
-
-        // Then
-        assertThat(indexableMessage.getHasAttachment()).isFalse();
-    }
-
-    @Test
-    void hasAttachmentsShouldReturnFalseWhenPropertyIsAbsent() throws IOException {
-        //Given
-        MailboxMessage  mailboxMessage = mock(MailboxMessage.class);
-        TestId mailboxId = TestId.of(1);
-        when(mailboxMessage.getMailboxId())
-            .thenReturn(mailboxId);
-        when(mailboxMessage.getModSeq())
-            .thenReturn(ModSeq.first());
-        when(mailboxMessage.getMessageId())
-            .thenReturn(InMemoryMessageId.of(42));
-        when(mailboxMessage.getFullContent())
-            .thenReturn(ClassLoader.getSystemResourceAsStream("eml/mailWithHeaders.eml"));
-        when(mailboxMessage.createFlags())
-            .thenReturn(new Flags());
-        when(mailboxMessage.getUid())
-            .thenReturn(MESSAGE_UID);
-        when(mailboxMessage.getProperties())
+        when(mailboxMessage.getAttachments())
             .thenReturn(ImmutableList.of());
 
         // When
diff --git a/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java b/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
index 793f4a0..30f1bce 100644
--- a/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
+++ b/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
@@ -51,6 +51,7 @@ import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.UnsupportedSearchException;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.SearchQuery;
@@ -70,7 +71,6 @@ import org.apache.james.mailbox.model.SearchQuery.UidRange;
 import org.apache.james.mailbox.model.UpdatedFlags;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
-import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
 import org.apache.james.mailbox.store.search.ListeningMessageSearchIndex;
 import org.apache.james.mailbox.store.search.SearchUtil;
 import org.apache.james.mime4j.MimeException;
@@ -732,8 +732,7 @@ public class LuceneMessageSearchIndex extends ListeningMessageSearchIndex {
     }
 
     private static boolean hasAttachment(MailboxMessage membership) {
-       return membership.getProperties().stream()
-            .anyMatch(PropertyBuilder.isHasAttachmentProperty());
+       return MessageAttachment.hasNonInlinedAttachment(membership.getAttachments());
     }
 
     private String toSentDateField(DateResolution res) {
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
index f5e18c7..1eb89a7 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
@@ -447,7 +447,6 @@ public class StoreMessageManager implements MessageManager {
             final int size = (int) file.length();
 
             final List<MessageAttachment> attachments = extractAttachments(contentIn);
-            propertyBuilder.setHasAttachment(hasNonInlinedAttachment(attachments));
 
             final MailboxMessage message = createMessage(internalDate, size, bodyStartOctet, contentIn, flags, propertyBuilder, attachments);
 
@@ -501,11 +500,6 @@ public class StoreMessageManager implements MessageManager {
         return propertyBuilder;
     }
 
-    private boolean hasNonInlinedAttachment(List<MessageAttachment> attachments) {
-        return attachments.stream()
-            .anyMatch(messageAttachment -> !messageAttachment.isInlinedWithCid());
-    }
-
     private List<MessageAttachment> extractAttachments(SharedFileInputStream contentIn) {
         try {
             return messageParser.retrieveAttachments(contentIn);
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/PropertyBuilder.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/PropertyBuilder.java
index 90d5192..1f53595 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/PropertyBuilder.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/PropertyBuilder.java
@@ -46,7 +46,6 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.SortedMap;
 import java.util.TreeMap;
-import java.util.function.Predicate;
 
 import org.apache.james.mailbox.store.mail.model.Property;
 
@@ -56,16 +55,7 @@ import com.github.steveash.guavate.Guavate;
  * Builds properties
  */
 public class PropertyBuilder {
-
     private static final int INITIAL_CAPACITY = 32;
-    public static final String JAMES_INTERNALS = "JAMES_INTERNALS";
-    public static final String HAS_ATTACHMENT = "HAS_ATTACHMENT";
-
-    public static Predicate<Property> isHasAttachmentProperty() {
-        return property -> property.getNamespace().equals(PropertyBuilder.JAMES_INTERNALS)
-            && property.getLocalName().equals(PropertyBuilder.HAS_ATTACHMENT)
-            && property.getValue().equals("true");
-    }
 
     private Long textualLineCount;
     private final List<Property> properties;
@@ -207,10 +197,6 @@ public class PropertyBuilder {
         setProperty(MIME_MIME_TYPE_SPACE, MIME_MEDIA_TYPE_NAME, value);
     }
 
-    public void setHasAttachment(boolean value) {
-        setProperty(JAMES_INTERNALS, HAS_ATTACHMENT, Boolean.toString(value));
-    }
-
     /**
      * Gets the MIME content subtype.
      * 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
index 03915fb..07d18c6 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
@@ -55,7 +55,6 @@ import org.apache.james.mailbox.model.SearchQuery.DateResolution;
 import org.apache.james.mailbox.model.SearchQuery.UidRange;
 import org.apache.james.mailbox.store.ResultUtils;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
-import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
 import org.apache.james.mailbox.store.search.comparator.CombinedComparator;
 import org.apache.james.mime4j.MimeException;
 import org.apache.james.mime4j.MimeIOException;
@@ -548,9 +547,7 @@ public class MessageSearches implements Iterable<SimpleMessageSearchIndex.Search
 
 
     private boolean matches(SearchQuery.AttachmentCriterion criterion, MailboxMessage message) throws UnsupportedSearchException {
-        boolean mailHasAttachments = message.getProperties()
-            .stream()
-            .anyMatch(PropertyBuilder.isHasAttachmentProperty());
+        boolean mailHasAttachments = MessageAttachment.hasNonInlinedAttachment(message.getAttachments());
         return mailHasAttachments == criterion.getOperator().isSet();
     }
 
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/PropertyBuilderTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/PropertyBuilderTest.java
index 1317441..1e10873 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/PropertyBuilderTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/PropertyBuilderTest.java
@@ -19,32 +19,24 @@
 
 package org.apache.james.mailbox.store.mail.model.impl;
 
+import static org.apache.james.mailbox.store.mail.model.StandardNames.MIME_CONTENT_MD5_NAME;
+import static org.apache.james.mailbox.store.mail.model.StandardNames.MIME_CONTENT_MD5_SPACE;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import org.apache.james.mailbox.store.mail.model.Property;
 import org.junit.jupiter.api.Test;
 
 class PropertyBuilderTest {
-
     @Test
     void emptyPropertyBuilderShouldCreateEmptyProperties() {
         assertThat(new PropertyBuilder().toProperties()).isEmpty();
     }
 
     @Test
-    void setHasAttachmentShouldAddFalseWhenCalledWithFalse() {
+    void setContentMD5ShouldAddMd5Property() {
         PropertyBuilder propertyBuilder = new PropertyBuilder();
-        propertyBuilder.setHasAttachment(false);
+        propertyBuilder.setContentMD5("123");
         assertThat(propertyBuilder.toProperties())
-            .containsOnly(new Property(PropertyBuilder.JAMES_INTERNALS, PropertyBuilder.HAS_ATTACHMENT, "false"));
+            .containsOnly(new Property(MIME_CONTENT_MD5_SPACE, MIME_CONTENT_MD5_NAME, "123"));
     }
-
-    @Test
-    void setHasAttachmentShouldAddTrueWhenCalledWithTrue() {
-        PropertyBuilder propertyBuilder = new PropertyBuilder();
-        propertyBuilder.setHasAttachment(true);
-        assertThat(propertyBuilder.toProperties())
-            .containsOnly(new Property(PropertyBuilder.JAMES_INTERNALS, PropertyBuilder.HAS_ATTACHMENT, "true"));
-    }
-
 }


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


[james-project] 29/37: JAMES-2997 step #14 Abstract message storage

Posted by bt...@apache.org.
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 e72c2cdad22387b8f86e03fc4e475b49be67f1d4
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Feb 4 13:26:15 2020 +0700

    JAMES-2997 step #14 Abstract message storage
    
    This avoids pretending "no attachment was stored" when attachment storage is
    not supported by the backend.
---
 .../org/apache/james/mailbox/AttachmentStorer.java |  44 -------
 .../org/apache/james/mailbox/MessageManager.java   |   9 +-
 .../mailbox/cassandra/CassandraMessageManager.java |   6 +-
 .../mailbox/jpa/openjpa/OpenJPAMessageManager.java |   6 +-
 .../mailbox/inmemory/InMemoryMessageManager.java   |   6 +-
 .../apache/james/mailbox/store/MessageStorer.java  | 137 +++++++++++++++++++++
 .../james/mailbox/store/StoreAttachmentStorer.java |  65 ----------
 .../james/mailbox/store/StoreMailboxManager.java   |   6 +-
 .../james/mailbox/store/StoreMessageManager.java   |  30 +----
 .../methods/SetMessagesCreationProcessorTest.java  |   2 +-
 10 files changed, 161 insertions(+), 150 deletions(-)

diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentStorer.java b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentStorer.java
deleted file mode 100644
index 2a3e22b..0000000
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentStorer.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/****************************************************************
- * 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.                                           *
- ****************************************************************/
-
-package org.apache.james.mailbox;
-
-import java.util.List;
-
-import javax.mail.internet.SharedInputStream;
-
-import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.MessageAttachment;
-import org.apache.james.mailbox.model.MessageId;
-
-import com.google.common.collect.ImmutableList;
-
-public interface AttachmentStorer {
-    /**
-     * If applicable, this method will parse the messageContent to retrieve associated attachments and will store them.
-     */
-    List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream messageContent, MailboxSession session) throws MailboxException;
-
-    class NoopAttachmentStorer implements AttachmentStorer {
-        @Override
-        public List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream messageContent, MailboxSession session) {
-            return ImmutableList.of();
-        }
-    }
-}
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java
index 2c67375..53f3b67 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java
@@ -54,6 +54,8 @@ import org.apache.james.mailbox.model.UidValidity;
 import org.apache.james.mime4j.dom.Message;
 import org.apache.james.mime4j.message.DefaultMessageWriter;
 
+import com.google.common.base.Preconditions;
+
 /**
  * Interface which represent a Mailbox
  * 
@@ -142,9 +144,9 @@ public interface MessageManager {
 
     class AppendResult {
         private final ComposedMessageId ids;
-        private final List<MessageAttachment> messageAttachments;
+        private final Optional<List<MessageAttachment>> messageAttachments;
 
-        public AppendResult(ComposedMessageId ids, List<MessageAttachment> messageAttachments) {
+        public AppendResult(ComposedMessageId ids, Optional<List<MessageAttachment>> messageAttachments) {
             this.ids = ids;
             this.messageAttachments = messageAttachments;
         }
@@ -154,7 +156,8 @@ public interface MessageManager {
         }
 
         public List<MessageAttachment> getMessageAttachments() {
-            return messageAttachments;
+            Preconditions.checkState(messageAttachments.isPresent(), "'attachment storage' not supported by the implementation");
+            return messageAttachments.get();
         }
 
         @Override
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
index c22aba9..928e627 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
@@ -30,8 +30,8 @@ import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
 import org.apache.james.mailbox.store.BatchSizes;
 import org.apache.james.mailbox.store.MessageFactory;
+import org.apache.james.mailbox.store.MessageStorer;
 import org.apache.james.mailbox.store.PreDeletionHooks;
-import org.apache.james.mailbox.store.StoreAttachmentStorer;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.StoreRightManager;
 import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
@@ -49,8 +49,8 @@ public class CassandraMessageManager extends StoreMessageManager {
                             StoreRightManager storeRightManager,
                             PreDeletionHooks preDeletionHooks) {
         super(CassandraMailboxManager.MESSAGE_CAPABILITIES, mapperFactory, index, eventBus, locker, mailbox,
-            quotaManager, quotaRootResolver, messageIdFactory, batchSizes, storeRightManager,
-            preDeletionHooks, new MessageFactory.StoreMessageFactory(), new StoreAttachmentStorer(mapperFactory, messageParser));
+            quotaManager, quotaRootResolver, batchSizes, storeRightManager,
+            preDeletionHooks, new MessageStorer.WithAttachment(mapperFactory, messageIdFactory, new MessageFactory.StoreMessageFactory(), mapperFactory, messageParser));
     }
 
     /**
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
index d982497..b11c70b 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
@@ -21,7 +21,6 @@ package org.apache.james.mailbox.jpa.openjpa;
 
 import javax.mail.Flags;
 
-import org.apache.james.mailbox.AttachmentStorer;
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.events.EventBus;
@@ -31,6 +30,7 @@ import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
 import org.apache.james.mailbox.store.BatchSizes;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
+import org.apache.james.mailbox.store.MessageStorer;
 import org.apache.james.mailbox.store.PreDeletionHooks;
 import org.apache.james.mailbox.store.StoreMailboxManager;
 import org.apache.james.mailbox.store.StoreMessageManager;
@@ -49,8 +49,8 @@ public class OpenJPAMessageManager extends StoreMessageManager {
                                  MessageId.Factory messageIdFactory, BatchSizes batchSizes,
                                  StoreRightManager storeRightManager) {
         super(StoreMailboxManager.DEFAULT_NO_MESSAGE_CAPABILITIES, mapperFactory, index, eventBus, locker, mailbox,
-            quotaManager, quotaRootResolver, messageIdFactory, batchSizes, storeRightManager, PreDeletionHooks.NO_PRE_DELETION_HOOK,
-            new OpenJPAMessageFactory(OpenJPAMessageFactory.AdvancedFeature.None), new AttachmentStorer.NoopAttachmentStorer());
+            quotaManager, quotaRootResolver, batchSizes, storeRightManager, PreDeletionHooks.NO_PRE_DELETION_HOOK,
+            new MessageStorer.WithoutAttachment(mapperFactory, messageIdFactory, new OpenJPAMessageFactory(OpenJPAMessageFactory.AdvancedFeature.None)));
     }
 
     /**
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
index 5d51bb7..59567b9 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
@@ -12,8 +12,8 @@ import org.apache.james.mailbox.quota.QuotaRootResolver;
 import org.apache.james.mailbox.store.BatchSizes;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.MessageFactory;
+import org.apache.james.mailbox.store.MessageStorer;
 import org.apache.james.mailbox.store.PreDeletionHooks;
-import org.apache.james.mailbox.store.StoreAttachmentStorer;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.StoreRightManager;
 import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
@@ -34,8 +34,8 @@ public class InMemoryMessageManager extends StoreMessageManager {
                                   PreDeletionHooks preDeletionHooks) {
 
         super(InMemoryMailboxManager.MESSAGE_CAPABILITIES, mapperFactory, index, eventBus, locker, mailbox, quotaManager, quotaRootResolver,
-            messageIdFactory, batchSizes, storeRightManager, preDeletionHooks, new MessageFactory.StoreMessageFactory(),
-            new StoreAttachmentStorer((InMemoryMailboxSessionMapperFactory) mapperFactory, messageParser));
+            batchSizes, storeRightManager, preDeletionHooks,
+            new MessageStorer.WithAttachment(mapperFactory, messageIdFactory, new MessageFactory.StoreMessageFactory(), (InMemoryMailboxSessionMapperFactory) mapperFactory, messageParser));
     }
 
     @Override
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageStorer.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageStorer.java
new file mode 100644
index 0000000..7b1df1d
--- /dev/null
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageStorer.java
@@ -0,0 +1,137 @@
+/****************************************************************
+ * 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.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.store;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+
+import javax.mail.Flags;
+import javax.mail.internet.SharedInputStream;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.Mailbox;
+import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.MessageMetaData;
+import org.apache.james.mailbox.model.ParsedAttachment;
+import org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
+import org.apache.james.mailbox.store.mail.MessageMapper;
+import org.apache.james.mailbox.store.mail.model.MailboxMessage;
+import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
+import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+
+public interface MessageStorer {
+    /**
+     * If supported by the underlying implementation, this method will parse the messageContent to retrieve associated
+     * attachments and will store them.
+     *
+     * Otherwize an empty optional will be returned on the right side of the pair.
+     */
+    Pair<MessageMetaData, Optional<List<MessageAttachment>>> appendMessageToStore(Mailbox mailbox, Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, MailboxSession session) throws MailboxException;
+
+    /**
+     * MessageStorer parsing, storing and returning AttachmentMetadata
+     *
+     * To be used with implementation that supports attachment content storage
+     */
+    class WithAttachment implements MessageStorer {
+        private static final Logger LOGGER = LoggerFactory.getLogger(WithAttachment.class);
+
+        private final MailboxSessionMapperFactory mapperFactory;
+        private final MessageId.Factory messageIdFactory;
+        private final MessageFactory messageFactory;
+        private final AttachmentMapperFactory attachmentMapperFactory;
+        private final MessageParser messageParser;
+
+        public WithAttachment(MailboxSessionMapperFactory mapperFactory, MessageId.Factory messageIdFactory,
+                              MessageFactory messageFactory, AttachmentMapperFactory attachmentMapperFactory,
+                              MessageParser messageParser) {
+            this.mapperFactory = mapperFactory;
+            this.messageIdFactory = messageIdFactory;
+            this.messageFactory = messageFactory;
+            this.attachmentMapperFactory = attachmentMapperFactory;
+            this.messageParser = messageParser;
+        }
+
+        @Override
+        public Pair<MessageMetaData, Optional<List<MessageAttachment>>> appendMessageToStore(Mailbox mailbox, Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, MailboxSession session) throws MailboxException {
+            MessageMapper messageMapper = mapperFactory.getMessageMapper(session);
+            MessageId messageId = messageIdFactory.generate();
+
+            return mapperFactory.getMessageMapper(session).execute(() -> {
+                List<MessageAttachment> attachments = storeAttachments(messageId, content, session);
+                MailboxMessage message = messageFactory.createMessage(messageId, mailbox, internalDate, size, bodyStartOctet, content, flags, propertyBuilder, attachments);
+                MessageMetaData metadata = messageMapper.add(mailbox, message);
+                return Pair.of(metadata, Optional.of(attachments));
+            });
+        }
+
+        private List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream messageContent, MailboxSession session) throws MailboxException {
+            List<ParsedAttachment> attachments = extractAttachments(messageContent);
+            return attachmentMapperFactory.getAttachmentMapper(session)
+                .storeAttachmentsForMessage(attachments, messageId);
+        }
+
+        private List<ParsedAttachment> extractAttachments(SharedInputStream contentIn) {
+            try {
+                return messageParser.retrieveAttachments(contentIn.newStream(0, -1));
+            } catch (Exception e) {
+                LOGGER.warn("Error while parsing mail's attachments: {}", e.getMessage(), e);
+                return ImmutableList.of();
+            }
+        }
+    }
+
+    /**
+     * MessageStorer that does not parse, store, nor return Attachment metadata
+     *
+     * To be used when the underlying implementation does not support attachment storage.
+     */
+    class WithoutAttachment implements MessageStorer {
+        private final MailboxSessionMapperFactory mapperFactory;
+        private final MessageId.Factory messageIdFactory;
+        private final MessageFactory messageFactory;
+
+        public WithoutAttachment(MailboxSessionMapperFactory mapperFactory, MessageId.Factory messageIdFactory, MessageFactory messageFactory) {
+            this.mapperFactory = mapperFactory;
+            this.messageIdFactory = messageIdFactory;
+            this.messageFactory = messageFactory;
+        }
+
+        @Override
+        public Pair<MessageMetaData, Optional<List<MessageAttachment>>> appendMessageToStore(Mailbox mailbox, Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, MailboxSession session) throws MailboxException {
+            MessageMapper messageMapper = mapperFactory.getMessageMapper(session);
+            MessageId messageId = messageIdFactory.generate();
+
+            return mapperFactory.getMessageMapper(session).execute(() -> {
+                MailboxMessage message = messageFactory.createMessage(messageId, mailbox, internalDate, size, bodyStartOctet, content, flags, propertyBuilder, ImmutableList.of());
+                MessageMetaData metadata = messageMapper.add(mailbox, message);
+                return Pair.of(metadata, Optional.empty());
+            });
+        }
+    }
+}
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentStorer.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentStorer.java
deleted file mode 100644
index 5ff314b..0000000
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentStorer.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/****************************************************************
- * 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.                                           *
- ****************************************************************/
-
-package org.apache.james.mailbox.store;
-
-import java.util.List;
-
-import javax.mail.internet.SharedInputStream;
-
-import org.apache.james.mailbox.AttachmentStorer;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.MessageAttachment;
-import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.mailbox.model.ParsedAttachment;
-import org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
-import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-
-public class StoreAttachmentStorer implements AttachmentStorer {
-    private static final Logger LOGGER = LoggerFactory.getLogger(StoreAttachmentStorer.class);
-
-    private final AttachmentMapperFactory mapperFactory;
-    private final MessageParser messageParser;
-
-    public StoreAttachmentStorer(AttachmentMapperFactory mapperFactory, MessageParser messageParser) {
-        this.mapperFactory = mapperFactory;
-        this.messageParser = messageParser;
-    }
-
-    @Override
-    public List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream messageContent, MailboxSession session) throws MailboxException {
-        List<ParsedAttachment> attachments = extractAttachments(messageContent);
-        return mapperFactory.getAttachmentMapper(session)
-            .storeAttachmentsForMessage(attachments, messageId);
-    }
-
-    private List<ParsedAttachment> extractAttachments(SharedInputStream contentIn) {
-        try {
-            return messageParser.retrieveAttachments(contentIn.newStream(0, -1));
-        } catch (Exception e) {
-            LOGGER.warn("Error while parsing mail's attachments: {}", e.getMessage(), e);
-            return ImmutableList.of();
-        }
-    }
-}
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 96cc2a5..165cda0 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
@@ -33,7 +33,6 @@ import javax.inject.Inject;
 import org.apache.james.core.Username;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeUsage;
-import org.apache.james.mailbox.AttachmentStorer.NoopAttachmentStorer;
 import org.apache.james.mailbox.MailboxAnnotationManager;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxPathLocker;
@@ -249,9 +248,8 @@ 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,
-            getQuotaComponents().getQuotaRootResolver(), getMessageIdFactory(), configuration.getBatchSizes(),
-            getStoreRightManager(), preDeletionHooks, new MessageFactory.StoreMessageFactory(),
-            new NoopAttachmentStorer());
+            getQuotaComponents().getQuotaRootResolver(), configuration.getBatchSizes(),
+            getStoreRightManager(), preDeletionHooks, new MessageStorer.WithoutAttachment(mailboxSessionMapperFactory, messageIdFactory, new MessageFactory.StoreMessageFactory()));
     }
 
     @Override
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
index 0006c6f..b09725c 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
@@ -34,18 +34,17 @@ import java.util.EnumSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.SortedMap;
 import java.util.TreeMap;
 import java.util.stream.Stream;
 
 import javax.mail.Flags;
 import javax.mail.Flags.Flag;
-import javax.mail.internet.SharedInputStream;
 import javax.mail.util.SharedFileInputStream;
 
 import org.apache.commons.io.input.TeeInputStream;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.james.mailbox.AttachmentStorer;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxManager.MessageCapabilities;
 import org.apache.james.mailbox.MailboxPathLocker;
@@ -69,7 +68,6 @@ import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.mailbox.model.MessageId.Factory;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.MessageMoves;
 import org.apache.james.mailbox.model.MessageRange;
@@ -154,17 +152,15 @@ public class StoreMessageManager implements MessageManager {
     private final QuotaManager quotaManager;
     private final QuotaRootResolver quotaRootResolver;
     private final MailboxPathLocker locker;
-    private final Factory messageIdFactory;
     private final BatchSizes batchSizes;
     private final PreDeletionHooks preDeletionHooks;
-    private final MessageFactory messageFactory;
-    private final AttachmentStorer attachmentStorer;
+    private final MessageStorer messageStorer;
 
     public StoreMessageManager(EnumSet<MessageCapabilities> messageCapabilities, MailboxSessionMapperFactory mapperFactory,
                                MessageSearchIndex index, EventBus eventBus,
                                MailboxPathLocker locker, Mailbox mailbox,
-                               QuotaManager quotaManager, QuotaRootResolver quotaRootResolver, Factory messageIdFactory, BatchSizes batchSizes,
-                               StoreRightManager storeRightManager, PreDeletionHooks preDeletionHooks, MessageFactory messageFactory, AttachmentStorer attachmentStorer) {
+                               QuotaManager quotaManager, QuotaRootResolver quotaRootResolver, BatchSizes batchSizes,
+                               StoreRightManager storeRightManager, PreDeletionHooks preDeletionHooks, MessageStorer messageStorer) {
         this.messageCapabilities = messageCapabilities;
         this.eventBus = eventBus;
         this.mailbox = mailbox;
@@ -173,12 +169,10 @@ public class StoreMessageManager implements MessageManager {
         this.locker = locker;
         this.quotaManager = quotaManager;
         this.quotaRootResolver = quotaRootResolver;
-        this.messageIdFactory = messageIdFactory;
         this.batchSizes = batchSizes;
         this.storeRightManager = storeRightManager;
         this.preDeletionHooks = preDeletionHooks;
-        this.messageFactory = messageFactory;
-        this.attachmentStorer = attachmentStorer;
+        this.messageStorer = messageStorer;
     }
 
     /**
@@ -438,7 +432,7 @@ public class StoreMessageManager implements MessageManager {
             new QuotaChecker(quotaManager, quotaRootResolver, mailbox).tryAddition(1, size);
 
             return locker.executeWithLock(getMailboxPath(), () -> {
-                Pair<MessageMetaData, List<MessageAttachment>> data = appendMessageToStore(internalDate, size, bodyStartOctet, contentIn, flags, propertyBuilder, mailboxSession);
+                Pair<MessageMetaData, Optional<List<MessageAttachment>>> data = messageStorer.appendMessageToStore(mailbox, internalDate, size, bodyStartOctet, contentIn, flags, propertyBuilder, mailboxSession);
 
                 Mailbox mailbox = getMailboxEntity();
 
@@ -643,18 +637,6 @@ public class StoreMessageManager implements MessageManager {
         }, MailboxPathLocker.LockType.Write);
     }
 
-    private Pair<MessageMetaData, List<MessageAttachment>> appendMessageToStore(Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, MailboxSession session) throws MailboxException {
-        MessageMapper messageMapper = mapperFactory.getMessageMapper(session);
-        MessageId messageId = messageIdFactory.generate();
-
-        return mapperFactory.getMessageMapper(session).execute(() -> {
-            List<MessageAttachment> attachments = attachmentStorer.storeAttachments(messageId, content, session);
-            MailboxMessage message = messageFactory.createMessage(messageId, getMailboxEntity(), internalDate, size, bodyStartOctet, content, flags, propertyBuilder, attachments);
-            MessageMetaData metadata = messageMapper.add(getMailboxEntity(), message);
-            return Pair.of(metadata, attachments);
-        });
-    }
-
     @Override
     public long getMessageCount(MailboxSession mailboxSession) throws MailboxException {
         return mapperFactory.getMessageMapper(mailboxSession).countMessagesInMailbox(getMailboxEntity());
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java
index 5e869ff..4824d92 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java
@@ -197,7 +197,7 @@ public class SetMessagesCreationProcessorTest {
         
         when(outbox.appendMessage(any(MessageManager.AppendCommand.class), any(MailboxSession.class)))
             .thenReturn(new MessageManager.AppendResult(new ComposedMessageId(OUTBOX_ID, TestMessageId.of(23), MessageUid.of(1)),
-                ImmutableList.of()));
+                Optional.of(ImmutableList.of())));
 
         drafts = mock(MessageManager.class);
         when(drafts.getId()).thenReturn(DRAFTS_ID);


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


[james-project] 02/37: JAMES-2997 Provide an efficient 'size' input stream

Posted by bt...@apache.org.
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 b81e1fe1a60c91f224bba4cf13b649bb0bb2f786
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Jan 17 10:10:21 2020 +0700

    JAMES-2997 Provide an efficient 'size' input stream
---
 .../org/apache/james/util/io/SizeInputStream.java  | 101 +++++++++++++++++++
 .../apache/james/util/io/SizeInputStreamTest.java  | 111 +++++++++++++++++++++
 2 files changed, 212 insertions(+)

diff --git a/server/container/util/src/main/java/org/apache/james/util/io/SizeInputStream.java b/server/container/util/src/main/java/org/apache/james/util/io/SizeInputStream.java
new file mode 100644
index 0000000..f289e31
--- /dev/null
+++ b/server/container/util/src/main/java/org/apache/james/util/io/SizeInputStream.java
@@ -0,0 +1,101 @@
+/****************************************************************
+ * 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.                                           *
+ ****************************************************************/
+
+package org.apache.james.util.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.lang3.NotImplementedException;
+
+public class SizeInputStream extends InputStream {
+    private final InputStream wrapped;
+    private long size;
+
+    public SizeInputStream(InputStream wrapped) {
+        this.wrapped = wrapped;
+        this.size = 0L;
+    }
+
+    @Override
+    public int read() throws IOException {
+        int read = wrapped.read();
+
+        if (read > 0) {
+            size++;
+        }
+
+        return read;
+    }
+
+    @Override
+    public int read(byte[] b) throws IOException {
+        int read = wrapped.read(b);
+        return increaseSize(read);
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        int read = wrapped.read(b, off, len);
+        return increaseSize(read);
+    }
+
+    @Override
+    public long skip(long n) throws IOException {
+        long skipped = wrapped.skip(n);
+        return increaseSize(skipped);
+    }
+
+    @Override
+    public int available() throws IOException {
+        return wrapped.available();
+    }
+
+    @Override
+    public void close() throws IOException {
+        wrapped.close();
+    }
+
+    @Override
+    public void mark(int readlimit) {
+        throw new NotImplementedException("'mark' is not supported'");
+    }
+
+    @Override
+    public void reset() {
+        throw new NotImplementedException("'reset' is not supported'");
+    }
+
+    @Override
+    public boolean markSupported() {
+        return false;
+    }
+
+    public long getSize() {
+        return size;
+    }
+
+    private <T extends Number> T increaseSize(T chunkSize) {
+        long longValue = chunkSize.longValue();
+        if (longValue > 0) {
+            size += longValue;
+        }
+        return chunkSize;
+    }
+}
diff --git a/server/container/util/src/test/java/org/apache/james/util/io/SizeInputStreamTest.java b/server/container/util/src/test/java/org/apache/james/util/io/SizeInputStreamTest.java
new file mode 100644
index 0000000..ece2d91
--- /dev/null
+++ b/server/container/util/src/test/java/org/apache/james/util/io/SizeInputStreamTest.java
@@ -0,0 +1,111 @@
+/****************************************************************
+ * 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.                                           *
+ ****************************************************************/
+
+package org.apache.james.util.io;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.stream.IntStream;
+
+import org.junit.jupiter.api.Test;
+
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Strings;
+
+class SizeInputStreamTest {
+    static final byte[] BYTES = "0123456789".getBytes(StandardCharsets.UTF_8);
+    static final byte[] TWELVE_MEGABYTES = Strings.repeat("0123456789\r\n", 1024 * 1024).getBytes(StandardCharsets.UTF_8);
+
+    @Test
+    void sizeInputStreamShouldNotAlterContent() {
+        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(BYTES));
+
+        assertThat(sizeInputStream).hasSameContentAs(new ByteArrayInputStream(BYTES));
+    }
+
+    @Test
+    void sizeInputStreamShouldNotAlterContentOfEmptyStream() {
+        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(new byte[0]));
+
+        assertThat(sizeInputStream).hasSameContentAs(new ByteArrayInputStream(new byte[0]));
+    }
+
+    @Test
+    void sizeInputStreamShouldNotAlterContentOfBigStream() {
+        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(TWELVE_MEGABYTES));
+
+        assertThat(sizeInputStream).hasSameContentAs(new ByteArrayInputStream(TWELVE_MEGABYTES));
+    }
+
+    @Test
+    void getSizeShouldReturnZeroWhenEmpty() {
+        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(new byte[0]));
+
+        assertThat(sizeInputStream.getSize()).isEqualTo(0);
+    }
+
+    @Test
+    void getSizeShouldReturnSizeWhenReadWithABiggerBuffer() throws Exception {
+        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(BYTES));
+
+        sizeInputStream.read(new byte[24]);
+
+        assertThat(sizeInputStream.getSize()).isEqualTo(10);
+    }
+
+    @Test
+    void getSizeShouldReturnSizeWhenReadWithABufferHavingSameSizeThanContent() throws Exception {
+        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(BYTES));
+
+        sizeInputStream.read(new byte[10]);
+
+        assertThat(sizeInputStream.getSize()).isEqualTo(10);
+    }
+
+    @Test
+    void getSizeShouldReturnSizeWhenReadUsingSmallerBuffers() throws Exception {
+        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(BYTES));
+
+        sizeInputStream.read(new byte[6]);
+        sizeInputStream.read(new byte[6]);
+
+        assertThat(sizeInputStream.getSize()).isEqualTo(10);
+    }
+
+    @Test
+    void getSizeShouldReturnSizeWhenReadByte() {
+        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(BYTES));
+
+        IntStream.range(0, 10).forEach(Throwing.intConsumer(step -> sizeInputStream.read()));
+
+        assertThat(sizeInputStream.getSize()).isEqualTo(10);
+    }
+
+    @Test
+    void getSizeShouldReturnSizeWhenSkips() throws Exception {
+        SizeInputStream sizeInputStream = new SizeInputStream(new ByteArrayInputStream(BYTES));
+
+        sizeInputStream.read(new byte[6]);
+        sizeInputStream.skip(6);
+
+        assertThat(sizeInputStream.getSize()).isEqualTo(10);
+    }
+}
\ No newline at end of file


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


[james-project] 21/37: JAMES-2997 Renable SetMessagesCreationProcessorTest

Posted by bt...@apache.org.
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 45ef5e4caa8e36583f9929f47cfeb65d47474dc2
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 20 14:52:51 2020 +0700

    JAMES-2997 Renable SetMessagesCreationProcessorTest
---
 .../draft/methods/SetMessagesCreationProcessorTest.java     | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java
index 9732043..5e869ff 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java
@@ -52,6 +52,7 @@ import org.apache.james.jmap.draft.send.MailMetadata;
 import org.apache.james.jmap.draft.send.MailSpool;
 import org.apache.james.jmap.draft.utils.JsoupHtmlTextExtractor;
 import org.apache.james.jmap.memory.projections.MemoryMessageFastViewProjection;
+import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.AttachmentManager;
 import org.apache.james.mailbox.BlobManager;
 import org.apache.james.mailbox.MailboxManager;
@@ -72,14 +73,14 @@ import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
+import org.apache.james.rrt.api.AliasReverseResolver;
 import org.apache.james.rrt.api.CanSendFrom;
 import org.apache.james.rrt.api.RecipientRewriteTableConfiguration;
 import org.apache.james.rrt.api.RecipientRewriteTableException;
-import org.apache.james.rrt.api.AliasReverseResolver;
 import org.apache.james.rrt.lib.AliasReverseResolverImpl;
+import org.apache.james.rrt.lib.CanSendFromImpl;
 import org.apache.james.rrt.lib.Mapping;
 import org.apache.james.rrt.lib.MappingSource;
-import org.apache.james.rrt.lib.CanSendFromImpl;
 import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
 import org.apache.james.util.OptionalUtils;
 import org.apache.james.util.html.HtmlTextExtractor;
@@ -95,8 +96,6 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
 public class SetMessagesCreationProcessorTest {
-
-    /*
     private static final Username USER = Username.of("user@example.com");
     private static final Username OTHER_USER = Username.of("other@example.com");
     private static final String OUTBOX = "outbox";
@@ -172,7 +171,7 @@ public class SetMessagesCreationProcessorTest {
         
         fakeSystemMailboxesProvider = new TestSystemMailboxesProvider(() -> optionalOutbox, () -> optionalDrafts);
         session = MailboxSessionUtil.create(USER);
-        MIMEMessageConverter mimeMessageConverter = new MIMEMessageConverter();
+        MIMEMessageConverter mimeMessageConverter = new MIMEMessageConverter(mock(AttachmentContentLoader.class));
         messageAppender = new MessageAppender(mockedMailboxManager, mockMessageIdManager, mockedAttachmentManager, mimeMessageConverter);
         messageSender = new MessageSender(mockedMailSpool);
         referenceUpdater = new ReferenceUpdater(mockMessageIdManager, mockedMailboxManager);
@@ -197,7 +196,8 @@ public class SetMessagesCreationProcessorTest {
         when(outbox.getMailboxPath()).thenReturn(MailboxPath.forUser(USER, OUTBOX));
         
         when(outbox.appendMessage(any(MessageManager.AppendCommand.class), any(MailboxSession.class)))
-            .thenReturn(new ComposedMessageId(OUTBOX_ID, TestMessageId.of(23), MessageUid.of(1)));
+            .thenReturn(new MessageManager.AppendResult(new ComposedMessageId(OUTBOX_ID, TestMessageId.of(23), MessageUid.of(1)),
+                ImmutableList.of()));
 
         drafts = mock(MessageManager.class);
         when(drafts.getId()).thenReturn(DRAFTS_ID);
@@ -508,5 +508,4 @@ public class SetMessagesCreationProcessorTest {
             return Stream.empty();
         }
     }
-*/
 }


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


[james-project] 17/37: JAMES-2997 Renable AttachmentTest

Posted by bt...@apache.org.
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 2fc93a7722a53e31956c0a32c050e1ee73c87d13
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Jan 17 16:41:30 2020 +0700

    JAMES-2997 Renable AttachmentTest
---
 .../apache/james/mailbox/model/AttachmentTest.java | 74 +++-------------------
 1 file changed, 8 insertions(+), 66 deletions(-)

diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java
index 7d85b29..e99cd7e 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java
@@ -20,59 +20,11 @@
 
 package org.apache.james.mailbox.model;
 
-import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
-import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-
-import org.apache.commons.io.IOUtils;
 import org.junit.jupiter.api.Test;
 
 class AttachmentTest {
-
-    private static Charset CHARSET = StandardCharsets.UTF_8;
-/*
-    @Test
-    void streamShouldBeConsumedOneTime() throws Exception {
-        String input = "mystream";
-        Attachment attachment = Attachment.builder()
-                .bytes(input.getBytes(CHARSET))
-                .type("content")
-                .build();
-
-        InputStream stream = attachment.getStream();
-        assertThat(stream).isNotNull();
-        assertThat(IOUtils.toString(stream, CHARSET)).isEqualTo(input);
-    }
-
-    @Test
-    void getByteShouldReturnByteArrayRepresentingTheAttachment() {
-        String input = "mystream";
-        Attachment attachment = Attachment.builder()
-            .bytes(input.getBytes(CHARSET))
-            .type("content")
-            .build();
-
-        byte[] bytes = attachment.getBytes();
-        assertThat(new String(bytes, CHARSET)).isEqualTo(input);
-    }
-
-    @Test
-    void streamShouldBeConsumedMoreThanOneTime() throws Exception {
-        String input = "mystream";
-        Attachment attachment = Attachment.builder()
-                .bytes(input.getBytes(CHARSET))
-                .type("content")
-                .build();
-
-        attachment.getStream();
-        InputStream stream = attachment.getStream();
-        assertThat(stream).isNotNull();
-        assertThat(IOUtils.toString(stream, CHARSET)).isEqualTo(input);
-    }
-
     @Test
     void builderShouldThrowWhenAttachmentIdIsNull() {
         assertThatThrownBy(() -> Attachment.builder()
@@ -81,13 +33,6 @@ class AttachmentTest {
     }
 
     @Test
-    void builderShouldThrowWhenBytesIsNull() {
-        assertThatThrownBy(() -> Attachment.builder()
-                .bytes(null))
-            .isInstanceOf(IllegalArgumentException.class);
-    }
-
-    @Test
     void builderShouldThrowWhenTypeIsNull() {
         assertThatThrownBy(() -> Attachment.builder()
                 .type(null))
@@ -109,9 +54,10 @@ class AttachmentTest {
     }
 
     @Test
-    void buildShouldThrowWhenBytesIsNotProvided() {
+    void buildShouldThrowWhenSizeIsNotProvided() {
         assertThatThrownBy(() -> Attachment.builder()
                 .attachmentId(AttachmentId.random())
+                .type("TYPE")
                 .build())
             .isInstanceOf(IllegalStateException.class);
     }
@@ -120,20 +66,16 @@ class AttachmentTest {
     void buildShouldThrowWhenTypeIsNotProvided() {
         assertThatThrownBy(() -> Attachment.builder()
                 .attachmentId(AttachmentId.random())
-                .bytes("mystream".getBytes(CHARSET))
+                .size(36)
                 .build())
             .isInstanceOf(IllegalStateException.class);
     }
 
     @Test
-    void buildShouldSetTheSize() {
-        String input = "mystream";
-        Attachment attachment = Attachment.builder()
-                .bytes(input.getBytes(CHARSET))
-                .type("content")
-                .build();
-
-        assertThat(attachment.getSize()).isEqualTo(input.getBytes(CHARSET).length);
+    void sizeShouldThrowOnNegativeValue() {
+        assertThatThrownBy(() -> Attachment.builder()
+                .attachmentId(AttachmentId.random())
+                .size(-3))
+            .isInstanceOf(IllegalArgumentException.class);
     }
-*/
 }


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


[james-project] 07/37: JAMES-2997 step #5 Implement AttachmentMapper::storeAttachmentForOwner

Posted by bt...@apache.org.
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 e3c456764252df77d4e938f203d3b57aab8b16aa
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed Jan 22 11:02:25 2020 +0700

    JAMES-2997 step #5 Implement AttachmentMapper::storeAttachmentForOwner
---
 .../apache/james/mailbox/AttachmentManager.java    |  2 +-
 .../cassandra/mail/CassandraAttachmentDAOV2.java   |  2 +-
 .../cassandra/mail/CassandraAttachmentMapper.java  | 18 ++++++++---
 .../mail/CassandraAttachmentMapperTest.java        |  4 ++-
 .../inmemory/mail/InMemoryAttachmentMapper.java    | 29 +++++++++++++----
 .../inmemory/mail/MemoryAttachmentMapperTest.java  |  4 ++-
 .../mailbox/store/StoreAttachmentManager.java      |  4 +--
 .../james/mailbox/store/mail/AttachmentMapper.java |  3 +-
 .../store/mail/model/AttachmentMapperTest.java     |  3 ++
 .../RabbitMQAwsS3SetMessagesMethodTest.java        |  2 +-
 .../org/apache/james/jmap/http/UploadRoutes.java   | 36 +++++-----------------
 11 files changed, 60 insertions(+), 47 deletions(-)

diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
index a23f2c7..946ea37 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
@@ -39,7 +39,7 @@ public interface AttachmentManager extends AttachmentContentLoader {
 
     List<Attachment> getAttachments(List<AttachmentId> attachmentIds, MailboxSession mailboxSession) throws MailboxException;
 
-    Publisher<Void> storeAttachment(Attachment attachment, MailboxSession mailboxSession);
+    Publisher<Attachment> storeAttachment(String contentType, InputStream attachmentContent, MailboxSession mailboxSession);
 
     void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId, MailboxSession mailboxSession) throws MailboxException;
 
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
index 5a1ee5f..d846f91 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
@@ -55,7 +55,7 @@ public class CassandraAttachmentDAOV2 {
         private final String type;
         private final long size;
 
-        private DAOAttachment(AttachmentId attachmentId, BlobId blobId, String type, long size) {
+        DAOAttachment(AttachmentId attachmentId, BlobId blobId, String type, long size) {
             this.attachmentId = attachmentId;
             this.blobId = blobId;
             this.type = type;
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
index 03a1461..534e3f1 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
@@ -39,6 +39,7 @@ import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.util.ReactorUtils;
+import org.apache.james.util.io.SizeInputStream;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -114,11 +115,18 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
     }
 
     @Override
-    public Mono<Void> storeAttachmentForOwner(Attachment attachment, Username owner) {
-        return ownerDAO.addOwner(attachment.getAttachmentId(), owner)
-            .then(Mono.from(blobStore.save(blobStore.getDefaultBucketName(), attachment.getBytes(), LOW_COST)))
-            .map(blobId -> CassandraAttachmentDAOV2.from(attachment, blobId))
-            .flatMap(attachmentDAOV2::storeAttachment);
+    public Mono<Attachment> storeAttachmentForOwner(String contentType, InputStream inputStream, Username owner) {
+        SizeInputStream sizeInputStream = new SizeInputStream(inputStream);
+        AttachmentId attachmentId = AttachmentId.random();
+
+        return ownerDAO.addOwner(attachmentId, owner)
+            .flatMap(any -> Mono.from(blobStore.save(blobStore.getDefaultBucketName(), sizeInputStream, LOW_COST)))
+            .map(blobId -> new DAOAttachment(attachmentId, blobId, contentType, sizeInputStream.getSize()))
+            .flatMap(attachmentDAOV2::storeAttachment)
+            .map(any -> Attachment.builder()
+                .attachmentId(attachmentId)
+                .type(contentType)
+                .build());
     }
 
     @Override
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapperTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapperTest.java
index e31a9c9..4edf53e 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapperTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapperTest.java
@@ -31,7 +31,7 @@ import org.apache.james.mailbox.store.mail.model.AttachmentMapperTest;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
 class CassandraAttachmentMapperTest extends AttachmentMapperTest {
-
+/*
     private static final CassandraModule MODULES = CassandraModule.aggregateModules(
         CassandraAttachmentModule.MODULE,
         CassandraBlobModule.MODULE);
@@ -49,4 +49,6 @@ class CassandraAttachmentMapperTest extends AttachmentMapperTest {
     protected MessageId generateMessageId() {
         return new CassandraMessageId.Factory().generate();
     }
+    
+ */
 }
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
index 7b07dfb..9112ece 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
@@ -21,11 +21,13 @@ package org.apache.james.mailbox.inmemory.mail;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.UncheckedIOException;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
@@ -80,12 +82,27 @@ public class InMemoryAttachmentMapper implements AttachmentMapper {
     }
 
     @Override
-    public Mono<Void> storeAttachmentForOwner(Attachment attachment, Username owner) {
-        return Mono.fromRunnable(() -> {
-            attachmentsById.put(attachment.getAttachmentId(), attachment);
-            attachmentsRawContentById.put(attachment.getAttachmentId(), attachment.getBytes());
-            ownersByAttachmentId.put(attachment.getAttachmentId(), owner);
-        });
+    public Mono<Attachment> storeAttachmentForOwner(String contentType, InputStream inputStream, Username owner) {
+            return Mono.fromCallable(() -> {
+                byte[] bytes = toByteArray(inputStream);
+                Attachment attachment = Attachment.builder()
+                    .bytes(bytes)
+                    .type(contentType)
+                    .attachmentId(AttachmentId.random())
+                    .build();
+                attachmentsById.put(attachment.getAttachmentId(), attachment);
+                attachmentsRawContentById.put(attachment.getAttachmentId(), bytes);
+                ownersByAttachmentId.put(attachment.getAttachmentId(), owner);
+                return attachment;
+            });
+    }
+
+    private byte[] toByteArray(InputStream inputStream) {
+        try {
+            return IOUtils.toByteArray(inputStream);
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
     }
 
     @Override
diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/MemoryAttachmentMapperTest.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/MemoryAttachmentMapperTest.java
index 2045455..e3ece02 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/MemoryAttachmentMapperTest.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/MemoryAttachmentMapperTest.java
@@ -25,7 +25,7 @@ import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.mailbox.store.mail.model.AttachmentMapperTest;
 
 class MemoryAttachmentMapperTest extends AttachmentMapperTest {
-
+/*
     @Override
     protected AttachmentMapper createAttachmentMapper() {
         return new InMemoryAttachmentMapper();
@@ -35,4 +35,6 @@ class MemoryAttachmentMapperTest extends AttachmentMapperTest {
     protected MessageId generateMessageId() {
         return new InMemoryMessageId.Factory().generate();
     }
+
+ */
 }
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
index 75e1552..98ca7f1 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
@@ -77,9 +77,9 @@ public class StoreAttachmentManager implements AttachmentManager {
     }
 
     @Override
-    public Publisher<Void> storeAttachment(Attachment attachment, MailboxSession mailboxSession) {
+    public Publisher<Attachment> storeAttachment(String contentType, InputStream attachmentContent, MailboxSession mailboxSession) {
         return attachmentMapperFactory.getAttachmentMapper(mailboxSession)
-            .storeAttachmentForOwner(attachment, mailboxSession.getUser());
+            .storeAttachmentForOwner(contentType, attachmentContent, mailboxSession.getUser());
     }
 
     @Override
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
index 4e64abc..6b5493b 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
@@ -20,6 +20,7 @@ package org.apache.james.mailbox.store.mail;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.UncheckedIOException;
 import java.util.Collection;
 import java.util.List;
 
@@ -40,7 +41,7 @@ public interface AttachmentMapper extends Mapper {
 
     List<Attachment> getAttachments(Collection<AttachmentId> attachmentIds);
 
-    Publisher<Void> storeAttachmentForOwner(Attachment attachment, Username owner);
+    Publisher<Attachment> storeAttachmentForOwner(String contentType, InputStream attachmentContent, Username owner);
 
     void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId) throws MailboxException;
 
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
index ad21cf6..93f4c21 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
@@ -40,6 +40,7 @@ import com.google.common.collect.ImmutableList;
 import reactor.core.publisher.Mono;
 
 public abstract class AttachmentMapperTest {
+    /*
     private static final AttachmentId UNKNOWN_ATTACHMENT_ID = AttachmentId.from("unknown");
     private static final Username OWNER = Username.of("owner");
     private static final Username ADDITIONAL_OWNER = Username.of("additionalOwner");
@@ -323,4 +324,6 @@ public abstract class AttachmentMapperTest {
 
         assertThat(actualOwners).isEmpty();
     }
+
+     */
 }
diff --git a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SetMessagesMethodTest.java b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SetMessagesMethodTest.java
index 97d76a7..67b4e94 100644
--- a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SetMessagesMethodTest.java
+++ b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SetMessagesMethodTest.java
@@ -61,7 +61,7 @@ public class RabbitMQAwsS3SetMessagesMethodTest extends SetMessagesMethodTest {
     public void setMessagesWithABigBodyShouldReturnCreatedMessageWhenSendingMessage() {
 
     }
-    
+
  */
 }
 
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/UploadRoutes.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/UploadRoutes.java
index 5605b13..95e6d62 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/UploadRoutes.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/UploadRoutes.java
@@ -29,7 +29,6 @@ import static org.apache.james.jmap.http.LoggingHelper.jmapContext;
 import static org.apache.james.util.ReactorUtils.logOnError;
 
 import java.io.EOFException;
-import java.io.IOException;
 import java.io.InputStream;
 import java.util.stream.Stream;
 
@@ -44,7 +43,6 @@ import org.apache.james.jmap.draft.model.UploadResponse;
 import org.apache.james.jmap.exceptions.UnauthorizedException;
 import org.apache.james.mailbox.AttachmentManager;
 import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.util.ReactorUtils;
 import org.slf4j.Logger;
@@ -53,7 +51,6 @@ import org.slf4j.LoggerFactory;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.base.Strings;
-import com.google.common.io.ByteStreams;
 
 import io.netty.handler.codec.http.HttpMethod;
 import reactor.core.publisher.Mono;
@@ -115,7 +112,7 @@ public class UploadRoutes implements JMAPRoutes {
     }
 
     private Mono<Void> post(HttpServerRequest request, HttpServerResponse response, String contentType, MailboxSession session) {
-        InputStream content = ReactorUtils.toInputStream(request.receive().asByteBuffer());
+        InputStream content = ReactorUtils.toInputStream(request.receive().asByteBuffer().subscribeOn(Schedulers.elastic()));
         return Mono.from(metricFactory.runPublishingTimerMetric("JMAP-upload-post",
             handle(contentType, content, session, response)));
     }
@@ -135,31 +132,14 @@ public class UploadRoutes implements JMAPRoutes {
     }
 
     private Mono<UploadResponse> uploadContent(String contentType, InputStream inputStream, MailboxSession session) {
-        return toBytesArray(inputStream)
-            .map(bytes -> Attachment.builder()
-                .bytes(bytes)
-                .type(contentType)
+        return Mono.from(attachmentManager.storeAttachment(contentType, inputStream, session))
+            .map(attachment -> UploadResponse.builder()
+                .blobId(attachment.getAttachmentId().getId())
+                .type(attachment.getType())
+                .size(attachment.getSize())
                 .build())
-            .flatMap(attachment -> Mono.from(attachmentManager.storeAttachment(attachment, session))
-                .thenReturn(UploadResponse.builder()
-                    .blobId(attachment.getAttachmentId().getId())
-                    .type(attachment.getType())
-                    .size(attachment.getSize())
-                    .build()));
-    }
-
-    private Mono<byte[]> toBytesArray(InputStream inputStream) {
-        return Mono.fromCallable(() -> {
-            try {
-                return ByteStreams.toByteArray(inputStream);
-            } catch (IOException e) {
-                if (e instanceof EOFException) {
-                    throw new CancelledUploadException();
-                } else {
-                    throw new InternalErrorException("Error while uploading content", e);
-                }
-            }
-        });
+            .onErrorMap(e -> e.getCause() instanceof EOFException, any -> new CancelledUploadException())
+            .onErrorMap(e -> !(e instanceof CancelledUploadException), e -> new InternalErrorException("Error while uploading content", e));
     }
 
     private Mono<Void> handleCanceledUpload(HttpServerResponse response, CancelledUploadException e) {


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


[james-project] 05/37: JAMES-2997 step #3 Rely on AttachmentContent loader for JMAP-draft message creation

Posted by bt...@apache.org.
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 a8e33bad886086efb36b497761cd807145887163
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed Jan 22 10:56:45 2020 +0700

    JAMES-2997 step #3 Rely on AttachmentContent loader for JMAP-draft message creation
---
 .../jmap/draft/methods/MIMEMessageConverter.java   |  63 +++++++------
 .../james/jmap/draft/methods/MessageAppender.java  |   2 +-
 .../draft/methods/MIMEMessageConverterTest.java    | 100 ++++++++-------------
 .../methods/SetMessagesCreationProcessorTest.java  |   5 +-
 4 files changed, 76 insertions(+), 94 deletions(-)

diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MIMEMessageConverter.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MIMEMessageConverter.java
index eac8c13..e83b561 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MIMEMessageConverter.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MIMEMessageConverter.java
@@ -20,6 +20,7 @@
 package org.apache.james.jmap.draft.methods;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.Date;
 import java.util.List;
@@ -29,9 +30,14 @@ import java.util.TimeZone;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
+import javax.inject.Inject;
+
 import org.apache.james.jmap.draft.model.CreationMessage;
 import org.apache.james.jmap.draft.model.CreationMessage.DraftEmailer;
 import org.apache.james.jmap.draft.model.message.view.MessageViewFactory;
+import org.apache.james.mailbox.AttachmentContentLoader;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mime4j.codec.DecodeMonitor;
 import org.apache.james.mime4j.codec.EncoderUtil;
@@ -99,13 +105,16 @@ public class MIMEMessageConverter {
             .collect(Guavate.toImmutableList());
 
     private final BasicBodyFactory bodyFactory;
+    private final AttachmentContentLoader attachmentContentLoader;
 
-    public MIMEMessageConverter() {
+    @Inject
+    public MIMEMessageConverter(AttachmentContentLoader attachmentContentLoader) {
+        this.attachmentContentLoader = attachmentContentLoader;
         this.bodyFactory = new BasicBodyFactory();
     }
 
-    public byte[] convert(ValueWithId.CreationMessageEntry creationMessageEntry, ImmutableList<MessageAttachment> messageAttachments) {
-        return asBytes(convertToMime(creationMessageEntry, messageAttachments));
+    public byte[] convert(ValueWithId.CreationMessageEntry creationMessageEntry, ImmutableList<MessageAttachment> messageAttachments, MailboxSession session) {
+        return asBytes(convertToMime(creationMessageEntry, messageAttachments, session));
     }
 
     public byte[] asBytes(Message message) {
@@ -116,14 +125,14 @@ public class MIMEMessageConverter {
         }
     }
 
-    @VisibleForTesting Message convertToMime(ValueWithId.CreationMessageEntry creationMessageEntry, ImmutableList<MessageAttachment> messageAttachments) {
+    @VisibleForTesting Message convertToMime(ValueWithId.CreationMessageEntry creationMessageEntry, ImmutableList<MessageAttachment> messageAttachments, MailboxSession session) {
         if (creationMessageEntry == null || creationMessageEntry.getValue() == null) {
             throw new IllegalArgumentException("creationMessageEntry is either null or has null message");
         }
 
         Message.Builder messageBuilder = Message.Builder.of();
         if (isMultipart(creationMessageEntry.getValue(), messageAttachments)) {
-            messageBuilder.setBody(createMultipart(creationMessageEntry.getValue(), messageAttachments));
+            messageBuilder.setBody(createMultipart(creationMessageEntry.getValue(), messageAttachments, session));
         } else {
             messageBuilder.setBody(createTextBody(creationMessageEntry.getValue()))
                 .setContentTransferEncoding(QUOTED_PRINTABLE);
@@ -202,10 +211,10 @@ public class MIMEMessageConverter {
         return bodyFactory.textBody(body, StandardCharsets.UTF_8);
     }
 
-    private Multipart createMultipart(CreationMessage newMessage, ImmutableList<MessageAttachment> messageAttachments) {
+    private Multipart createMultipart(CreationMessage newMessage, ImmutableList<MessageAttachment> messageAttachments, MailboxSession session) {
         try {
             if (hasAttachment(messageAttachments)) {
-                return createMultipartWithAttachments(newMessage, messageAttachments);
+                return createMultipartWithAttachments(newMessage, messageAttachments, session);
             } else {
                 return createMultipartAlternativeBody(newMessage);
             }
@@ -215,7 +224,7 @@ public class MIMEMessageConverter {
         }
     }
 
-    private Multipart createMultipartWithAttachments(CreationMessage newMessage, ImmutableList<MessageAttachment> messageAttachments) throws IOException {
+    private Multipart createMultipartWithAttachments(CreationMessage newMessage, ImmutableList<MessageAttachment> messageAttachments, MailboxSession session) throws IOException {
         MultipartBuilder mixedMultipartBuilder = MultipartBuilder.create(MIXED_SUB_TYPE);
         List<MessageAttachment> inlineAttachments = messageAttachments.stream()
             .filter(MessageAttachment::isInline)
@@ -225,29 +234,29 @@ public class MIMEMessageConverter {
             .collect(Guavate.toImmutableList());
 
         if (inlineAttachments.size() > 0) {
-            mixedMultipartBuilder.addBodyPart(relatedInnerMessage(newMessage, inlineAttachments));
+            mixedMultipartBuilder.addBodyPart(relatedInnerMessage(newMessage, inlineAttachments, session));
         } else {
             addBody(newMessage, mixedMultipartBuilder);
         }
 
-        addAttachments(besideAttachments, mixedMultipartBuilder);
+        addAttachments(besideAttachments, mixedMultipartBuilder, session);
 
         return mixedMultipartBuilder.build();
     }
 
-    private Message relatedInnerMessage(CreationMessage newMessage, List<MessageAttachment> inlines) throws IOException {
+    private Message relatedInnerMessage(CreationMessage newMessage, List<MessageAttachment> inlines, MailboxSession session) throws IOException {
         MultipartBuilder relatedMultipart = MultipartBuilder.create(RELATED_SUB_TYPE);
         addBody(newMessage, relatedMultipart);
 
         return Message.Builder.of()
-            .setBody(addAttachments(inlines, relatedMultipart)
+            .setBody(addAttachments(inlines, relatedMultipart, session)
                 .build())
             .build();
     }
 
     private MultipartBuilder addAttachments(List<MessageAttachment> messageAttachments,
-                                            MultipartBuilder multipartBuilder) {
-        messageAttachments.forEach(addAttachment(multipartBuilder));
+                                            MultipartBuilder multipartBuilder, MailboxSession session) {
+        messageAttachments.forEach(addAttachment(multipartBuilder, session));
 
         return multipartBuilder;
     }
@@ -289,26 +298,28 @@ public class MIMEMessageConverter {
         }
     }
 
-    private Consumer<MessageAttachment> addAttachment(MultipartBuilder builder) {
+    private Consumer<MessageAttachment> addAttachment(MultipartBuilder builder, MailboxSession session) {
         return att -> { 
             try {
-                builder.addBodyPart(attachmentBodyPart(att));
-            } catch (IOException e) {
+                builder.addBodyPart(attachmentBodyPart(att, session));
+            } catch (IOException | AttachmentNotFoundException e) {
                 LOGGER.error("Error while creating attachment", e);
                 throw new RuntimeException(e);
             }
         };
     }
 
-    private BodyPart attachmentBodyPart(MessageAttachment att) throws IOException {
-        BodyPartBuilder builder = BodyPartBuilder.create()
-            .use(bodyFactory)
-            .setBody(new BasicBodyFactory().binaryBody(ByteStreams.toByteArray(att.getAttachment().getStream())))
-            .setField(contentTypeField(att))
-            .setField(contentDispositionField(att.isInline()))
-            .setContentTransferEncoding(BASE64);
-        contentId(builder, att);
-        return builder.build();
+    private BodyPart attachmentBodyPart(MessageAttachment att, MailboxSession session) throws IOException, AttachmentNotFoundException {
+        try (InputStream attachmentStream = attachmentContentLoader.load(att.getAttachment(), session)) {
+            BodyPartBuilder builder = BodyPartBuilder.create()
+                .use(bodyFactory)
+                .setBody(new BasicBodyFactory().binaryBody(ByteStreams.toByteArray(attachmentStream)))
+                .setField(contentTypeField(att))
+                .setField(contentDispositionField(att.isInline()))
+                .setContentTransferEncoding(BASE64);
+            contentId(builder, att);
+            return builder.build();
+        }
     }
 
     private void contentId(BodyPartBuilder builder, MessageAttachment att) {
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageAppender.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageAppender.java
index 6e04cfe..595dce4 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageAppender.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageAppender.java
@@ -78,7 +78,7 @@ public class MessageAppender {
                                                                                MailboxSession session) throws MailboxException {
         Preconditions.checkArgument(!targetMailboxes.isEmpty());
         ImmutableList<MessageAttachment> messageAttachments = getMessageAttachments(session, createdEntry.getValue().getAttachments());
-        byte[] messageContent = mimeMessageConverter.convert(createdEntry, messageAttachments);
+        byte[] messageContent = mimeMessageConverter.convert(createdEntry, messageAttachments, session);
         SharedByteArrayInputStream content = new SharedByteArrayInputStream(messageContent);
         Date internalDate = Date.from(createdEntry.getValue().getDate().toInstant());
 
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/MIMEMessageConverterTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/MIMEMessageConverterTest.java
index 2b27933..68f235b 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/MIMEMessageConverterTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/MIMEMessageConverterTest.java
@@ -19,41 +19,9 @@
 
 package org.apache.james.jmap.draft.methods;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import java.nio.charset.StandardCharsets;
-import java.sql.Date;
-import java.time.Instant;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-
-import org.apache.james.jmap.draft.methods.ValueWithId.MessageWithId;
-import org.apache.james.jmap.draft.model.CreationMessage;
-import org.apache.james.jmap.draft.model.CreationMessage.DraftEmailer;
-import org.apache.james.jmap.draft.model.CreationMessageId;
-import org.apache.james.mailbox.model.AttachmentId;
-import org.apache.james.mailbox.model.Cid;
-import org.apache.james.mailbox.model.MessageAttachment;
-import org.apache.james.mime4j.codec.EncoderUtil;
-import org.apache.james.mime4j.codec.EncoderUtil.Usage;
-import org.apache.james.mime4j.dom.Entity;
-import org.apache.james.mime4j.dom.Message;
-import org.apache.james.mime4j.dom.Multipart;
-import org.apache.james.mime4j.dom.TextBody;
-import org.apache.james.mime4j.dom.address.Mailbox;
-import org.apache.james.mime4j.dom.field.ContentTypeField;
-import org.apache.james.mime4j.message.BasicBodyFactory;
-import org.apache.james.mime4j.stream.Field;
-import org.assertj.core.data.Index;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
 class MIMEMessageConverterTest {
-    
+
+    /*
     @Test
     void convertToMimeShouldAddInReplyToHeaderWhenProvided() {
         // Given
@@ -69,7 +37,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getHeader().getFields("In-Reply-To")).extracting(Field::getBody)
@@ -88,7 +56,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), message), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), message), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getHeader().getFields("Message-ID")).extracting(Field::getBody)
@@ -108,7 +76,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), message), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), message), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getHeader().getFields("Message-ID")).extracting(Field::getBody)
@@ -128,7 +96,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), message), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), message), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getHeader().getFields("Message-ID")).hasSize(1);
@@ -150,7 +118,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getHeader().getFields("FIRST")).extracting(Field::getBody)
@@ -171,7 +139,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getHeader().getFields("FIRST")).extracting(Field::getBody)
@@ -195,7 +163,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getFrom()).extracting(Mailbox::getAddress)
@@ -221,7 +189,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getFrom()).extracting(Mailbox::getAddress)
@@ -246,7 +214,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getHeader().getFields("FIRST")).extracting(Field::getBody)
@@ -267,7 +235,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getHeader().getFields("")).isEmpty();
@@ -287,7 +255,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), messageHavingInReplyTo), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getHeader().getFields("   ")).isEmpty();
@@ -300,7 +268,7 @@ class MIMEMessageConverterTest {
 
         assertThatThrownBy(() -> sut.convertToMime(
                 new ValueWithId.CreationMessageEntry(CreationMessageId.of("any"), null),
-                ImmutableList.of()))
+                ImmutableList.of(), session))
             .isInstanceOf(IllegalArgumentException.class);
     }
 
@@ -318,7 +286,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getFrom()).extracting(Mailbox::getAddress).allMatch(f -> f.equals(joesEmail));
@@ -342,7 +310,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getDate()).isEqualToIgnoringMillis(Date.from(now));
@@ -362,7 +330,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getHeader()
@@ -386,7 +354,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getBody()).isEqualToComparingOnlyGivenFields(expected, "content", "charset");
@@ -406,7 +374,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getBody()).isEqualToComparingOnlyGivenFields(expected, "content", "charset");
@@ -427,7 +395,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getBody()).isEqualToComparingOnlyGivenFields(expected, "content", "charset");
@@ -448,7 +416,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getBody()).isInstanceOf(Multipart.class);
@@ -508,7 +476,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getMimeType()).isEqualTo("text/plain");
@@ -528,7 +496,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getMimeType()).isEqualTo("text/html");
@@ -549,7 +517,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getBody()).isEqualToComparingOnlyGivenFields(expected, "content", "charset");
@@ -571,7 +539,7 @@ class MIMEMessageConverterTest {
 
         // When
         Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(), session);
 
         // Then
         assertThat(result.getBody()).isEqualToComparingOnlyGivenFields(expected, "content", "charset");
@@ -609,7 +577,7 @@ class MIMEMessageConverterTest {
 
             // When
             Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment));
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment), session);
             Multipart typedResult = (Multipart)result.getBody();
 
             assertThat(typedResult.getBodyParts())
@@ -656,7 +624,7 @@ class MIMEMessageConverterTest {
 
             // When
             Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment));
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment), session);
             Multipart typedResult = (Multipart)result.getBody();
 
             assertThat(typedResult.getBodyParts())
@@ -735,7 +703,7 @@ class MIMEMessageConverterTest {
 
             // When
             Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment));
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment), session);
             Multipart typedResult = (Multipart)result.getBody();
 
             assertThat(typedResult.getBodyParts())
@@ -769,7 +737,7 @@ class MIMEMessageConverterTest {
                 .build();
 
             Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment));
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment), session);
 
             assertThat(result.getBody()).isInstanceOf(Multipart.class);
             Multipart typedResult = (Multipart)result.getBody();
@@ -799,7 +767,7 @@ class MIMEMessageConverterTest {
                 .build();
 
             Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment));
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment), session);
             Multipart typedResult = (Multipart)result.getBody();
 
             assertThat(typedResult.getBodyParts())
@@ -829,7 +797,7 @@ class MIMEMessageConverterTest {
                 .build();
 
             Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment));
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment), session);
             Multipart typedResult = (Multipart)result.getBody();
 
             assertThat(typedResult.getBodyParts())
@@ -861,7 +829,7 @@ class MIMEMessageConverterTest {
                 .build();
 
             Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                    CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment));
+                    CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment), session);
             Multipart typedResult = (Multipart)result.getBody();
 
             assertThat(typedResult.getBodyParts())
@@ -906,7 +874,7 @@ class MIMEMessageConverterTest {
                 .build();
 
             Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
-                    CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(inline, attachment));
+                    CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(inline, attachment), session);
             Multipart typedResult = (Multipart)result.getBody();
 
             assertThat(typedResult.getBodyParts())
@@ -927,4 +895,6 @@ class MIMEMessageConverterTest {
             return ((ContentTypeField) attachmentPart.getHeader().getField("Content-Type")).getParameter("name");
         }
     }
+
+     */
 }
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java
index 06d8979..9732043 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesCreationProcessorTest.java
@@ -95,7 +95,8 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
 public class SetMessagesCreationProcessorTest {
-    
+
+    /*
     private static final Username USER = Username.of("user@example.com");
     private static final Username OTHER_USER = Username.of("other@example.com");
     private static final String OUTBOX = "outbox";
@@ -507,5 +508,5 @@ public class SetMessagesCreationProcessorTest {
             return Stream.empty();
         }
     }
-
+*/
 }


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


[james-project] 33/37: JAMES-2997 Store attachments sequentially with Cassandra

Posted by bt...@apache.org.
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 23725df48e41ae681c4dcb3147098de36cbd86b6
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Mar 27 14:11:15 2020 +0700

    JAMES-2997 Store attachments sequentially with Cassandra
---
 .../mailbox/cassandra/mail/CassandraAttachmentMapper.java      | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
index 62ed3f0..12a0d4c 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
@@ -115,20 +115,20 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
         CurrentPositionInputStream currentPositionInputStream = new CurrentPositionInputStream(inputStream);
         AttachmentId attachmentId = AttachmentId.random();
         return ownerDAO.addOwner(attachmentId, owner)
-            .flatMap(any -> Mono.from(blobStore.save(blobStore.getDefaultBucketName(), currentPositionInputStream, LOW_COST)))
-            .map(blobId -> new DAOAttachment(attachmentId, blobId, contentType, currentPositionInputStream.getPosition()))
+            .then(Mono.from(blobStore.save(blobStore.getDefaultBucketName(), currentPositionInputStream, LOW_COST)))
+                .map(blobId -> new DAOAttachment(attachmentId, blobId, contentType, currentPositionInputStream.getPosition()))
             .flatMap(attachmentDAOV2::storeAttachment)
-            .map(any -> Attachment.builder()
+            .then(Mono.defer(() -> Mono.just(Attachment.builder()
                 .attachmentId(attachmentId)
                 .type(contentType)
                 .size(currentPositionInputStream.getPosition())
-                .build());
+                .build())));
     }
 
     @Override
     public List<MessageAttachment> storeAttachmentsForMessage(Collection<ParsedAttachment> parsedAttachments, MessageId ownerMessageId) throws MailboxException {
         return Flux.fromIterable(parsedAttachments)
-            .flatMap(attachment -> storeAttachmentAsync(attachment, ownerMessageId))
+            .concatMap(attachment -> storeAttachmentAsync(attachment, ownerMessageId))
             .collectList()
             .block();
     }


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


[james-project] 35/37: JAMES-2997 step #10 Mailbox backend is responsible of creating messageAttachments

Posted by bt...@apache.org.
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 be52477691577d1cdb567ad1f31979273c5c8aac
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Sun Apr 19 16:47:52 2020 +0700

    JAMES-2997 step #10 Mailbox backend is responsible of creating messageAttachments
---
 .../listeners/SetCustomFlagOnBigMessagesTest.java  | 12 ++---
 .../org/apache/james/mailbox/MessageManager.java   | 14 ++---
 .../mailbox/MailboxManagerStressContract.java      |  2 +-
 .../apache/james/mailbox/MailboxManagerTest.java   | 56 +++++++++----------
 .../mailbox/manager/ManagerTestProvisionner.java   |  2 +-
 .../ElasticSearchIntegrationTest.java              | 16 +++---
 .../search/ElasticSearchSearcherTest.java          |  2 +-
 .../james/vault/DeletedMessageVaultHookTest.java   |  2 +-
 .../store/AbstractCombinationManagerTest.java      | 62 +++++++++++-----------
 .../store/AbstractMessageIdManagerStorageTest.java |  2 +-
 .../search/AbstractMessageSearchIndexTest.java     | 52 +++++++++---------
 .../tools/indexer/MessageIdReIndexerImplTest.java  |  2 +-
 .../mailbox/tools/indexer/ReIndexerImplTest.java   | 12 ++---
 .../james/imap/processor/AppendProcessor.java      |  2 +-
 .../org/apache/james/modules/MailboxProbeImpl.java |  4 +-
 .../mailets/delivery/MailboxAppender.java          |  2 +-
 .../james/jmap/draft/methods/MessageAppender.java  |  4 +-
 .../MessageFastViewProjectionItemFactoryTest.java  |  2 +-
 .../jmap/draft/methods/GetMessagesMethodTest.java  | 52 +++++++++---------
 .../message/view/MessageFastViewFactoryTest.java   |  8 +--
 .../message/view/MessageFullViewFactoryTest.java   |  2 +-
 .../message/view/MessageHeaderViewFactoryTest.java |  2 +-
 .../view/MessageMetadataViewFactoryTest.java       |  2 +-
 .../jmap/draft/send/PostDequeueDecoratorTest.java  | 16 +++---
 ...mputeMessageFastViewProjectionListenerTest.java | 12 ++---
 ...llFastViewProjectionItemsRequestToTaskTest.java |  4 +-
 ...erFastViewProjectionItemsRequestToTaskTest.java |  4 +-
 .../webadmin/vault/routes/RestoreService.java      |  2 +-
 .../james/webadmin/routes/MailboxesRoutesTest.java | 16 +++---
 .../james/webadmin/routes/MessageRoutesTest.java   |  4 +-
 .../webadmin/routes/UserMailboxesRoutesTest.java   |  4 +-
 .../james/webadmin/service/ExportServiceTest.java  |  2 +-
 .../service/MailboxesExportRequestToTaskTest.java  |  4 +-
 33 files changed, 192 insertions(+), 192 deletions(-)

diff --git a/examples/custom-listeners/src/test/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessagesTest.java b/examples/custom-listeners/src/test/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessagesTest.java
index d198a94..8972fff 100644
--- a/examples/custom-listeners/src/test/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessagesTest.java
+++ b/examples/custom-listeners/src/test/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessagesTest.java
@@ -81,7 +81,7 @@ class SetCustomFlagOnBigMessagesTest {
         ComposedMessageId composedId = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(smallMessage()),
-            mailboxSession).getIds();
+            mailboxSession).getId();
 
         assertThat(getMessageFlags(composedId.getUid()))
             .allSatisfy(flags -> assertThat(flags.contains(BIG_MESSAGE)).isFalse());
@@ -97,7 +97,7 @@ class SetCustomFlagOnBigMessagesTest {
             MessageManager.AppendCommand.builder()
                 .withFlags(appendMessageFlag)
                 .build(smallMessage()),
-            mailboxSession).getIds();
+            mailboxSession).getId();
 
         assertThat(getMessageFlags(composedId.getUid()))
             .allSatisfy(flags -> {
@@ -111,7 +111,7 @@ class SetCustomFlagOnBigMessagesTest {
         ComposedMessageId composedId = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(bigMessage()),
-            mailboxSession).getIds();
+            mailboxSession).getId();
 
         assertThat(getMessageFlags(composedId.getUid()))
             .allSatisfy(flags -> assertThat(flags.contains(BIG_MESSAGE)).isTrue());
@@ -122,7 +122,7 @@ class SetCustomFlagOnBigMessagesTest {
         ComposedMessageId composedIdOfSmallMessage = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(smallMessage()),
-            mailboxSession).getIds();
+            mailboxSession).getId();
 
         MessageResult addedMessage = inboxMessageManager
             .getMessages(MessageRange.one(composedIdOfSmallMessage.getUid()), FetchGroup.MINIMAL, mailboxSession)
@@ -154,7 +154,7 @@ class SetCustomFlagOnBigMessagesTest {
             MessageManager.AppendCommand.builder()
                 .withFlags(appendMessageFlag)
                 .build(bigMessage()),
-            mailboxSession).getIds();
+            mailboxSession).getId();
 
         assertThat(getMessageFlags(composedId.getUid()))
             .allSatisfy(flags -> {
@@ -173,7 +173,7 @@ class SetCustomFlagOnBigMessagesTest {
             MessageManager.AppendCommand.builder()
                 .withFlags(appendMessageFlag)
                 .build(bigMessage()),
-            mailboxSession).getIds();
+            mailboxSession).getId();
 
         assertThat(getMessageFlags(composedId.getUid()))
             .allSatisfy(flags -> assertThat(flags.contains(BIG_MESSAGE)).isTrue());
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java
index 53f3b67..f9c2065 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java
@@ -143,16 +143,16 @@ public interface MessageManager {
     Map<MessageUid, Flags> setFlags(Flags flags, FlagsUpdateMode flagsUpdateMode, MessageRange set, MailboxSession mailboxSession) throws MailboxException;
 
     class AppendResult {
-        private final ComposedMessageId ids;
+        private final ComposedMessageId id;
         private final Optional<List<MessageAttachment>> messageAttachments;
 
-        public AppendResult(ComposedMessageId ids, Optional<List<MessageAttachment>> messageAttachments) {
-            this.ids = ids;
+        public AppendResult(ComposedMessageId id, Optional<List<MessageAttachment>> messageAttachments) {
+            this.id = id;
             this.messageAttachments = messageAttachments;
         }
 
-        public ComposedMessageId getIds() {
-            return ids;
+        public ComposedMessageId getId() {
+            return id;
         }
 
         public List<MessageAttachment> getMessageAttachments() {
@@ -165,7 +165,7 @@ public interface MessageManager {
             if (o instanceof AppendResult) {
                 AppendResult that = (AppendResult) o;
 
-                return Objects.equals(this.ids, that.ids)
+                return Objects.equals(this.id, that.id)
                     && Objects.equals(this.messageAttachments, that.messageAttachments);
             }
             return false;
@@ -173,7 +173,7 @@ public interface MessageManager {
 
         @Override
         public final int hashCode() {
-            return Objects.hash(ids, messageAttachments);
+            return Objects.hash(id, messageAttachments);
         }
     }
 
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java
index 4821757..d160f17 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java
@@ -93,7 +93,7 @@ public interface MailboxManagerStressContract<T extends MailboxManager> {
                         MessageManager.AppendCommand
                             .from(Message.Builder.of()
                                 .setSubject("test")
-                                .setBody("testmail", StandardCharsets.UTF_8)), mailboxSession).getIds();
+                                .setBody("testmail", StandardCharsets.UTF_8)), mailboxSession).getId();
 
                     System.out.println("Append message with uid=" + messageId.getUid());
                     if (uids.put(messageId.getUid(), new Object()) != null) {
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 7382127..f3dfaa4 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
@@ -824,7 +824,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
 
         @Test
         void deleteMessageShouldFireExpungedEvent() throws Exception {
-            ComposedMessageId messageId = inboxManager.appendMessage(MessageManager.AppendCommand.builder().build(message), session).getIds();
+            ComposedMessageId messageId = inboxManager.appendMessage(MessageManager.AppendCommand.builder().build(message), session).getId();
             inboxManager.setFlags(new Flags(Flags.Flag.DELETED), MessageManager.FlagsUpdateMode.ADD, MessageRange.all(), session);
 
             retrieveEventBus(mailboxManager).register(listener, new MailboxIdRegistrationKey(inboxId));
@@ -913,7 +913,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             assumeTrue(mailboxManager.getSupportedMessageCapabilities().contains(MailboxManager.MessageCapabilities.UniqueID));
 
             Optional<MailboxId> targetMailboxId = mailboxManager.createMailbox(newPath, session);
-            ComposedMessageId messageId = inboxManager.appendMessage(AppendCommand.builder().build(message), session).getIds();
+            ComposedMessageId messageId = inboxManager.appendMessage(AppendCommand.builder().build(message), session).getId();
 
             retrieveEventBus(mailboxManager).register(listener, new MailboxIdRegistrationKey(targetMailboxId.get()));
             mailboxManager.copyMessages(MessageRange.all(), inbox, newPath, session);
@@ -946,7 +946,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             assumeTrue(mailboxManager.getSupportedMessageCapabilities().contains(MailboxManager.MessageCapabilities.UniqueID));
 
             Optional<MailboxId> targetMailboxId = mailboxManager.createMailbox(newPath, session);
-            ComposedMessageId messageId = inboxManager.appendMessage(AppendCommand.builder().build(message), session).getIds();
+            ComposedMessageId messageId = inboxManager.appendMessage(AppendCommand.builder().build(message), session).getId();
 
             retrieveEventBus(mailboxManager).register(listener, new MailboxIdRegistrationKey(targetMailboxId.get()));
             mailboxManager.moveMessages(MessageRange.all(), inbox, newPath, session);
@@ -964,7 +964,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             assumeTrue(mailboxManager.getSupportedMessageCapabilities().contains(MailboxManager.MessageCapabilities.UniqueID));
 
             mailboxManager.createMailbox(newPath, session);
-            ComposedMessageId messageId = inboxManager.appendMessage(AppendCommand.builder().build(message), session).getIds();
+            ComposedMessageId messageId = inboxManager.appendMessage(AppendCommand.builder().build(message), session).getId();
 
             retrieveEventBus(mailboxManager).register(listener, new MailboxIdRegistrationKey(inboxId));
             mailboxManager.moveMessages(MessageRange.all(), inbox, newPath, session);
@@ -1194,7 +1194,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             MessageManager cacahueteMessageManager = mailboxManager.getMailbox(cacahueteMailboxId, session);
             MessageId cacahueteMessageId = cacahueteMessageManager
                 .appendMessage(AppendCommand.from(message), session)
-                .getIds().getMessageId();
+                .getId().getMessageId();
 
             MailboxPath pirouetteFilder = MailboxPath.forUser(USER_1, "PIROUETTE");
             MailboxId pirouetteMailboxId = mailboxManager.createMailbox(pirouetteFilder, session).get();
@@ -1202,7 +1202,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
 
             MessageId pirouetteMessageId = pirouetteMessageManager
                 .appendMessage(AppendCommand.from(message), session)
-                .getIds().getMessageId();
+                .getId().getMessageId();
 
             MultimailboxesSearchQuery multiMailboxesQuery = MultimailboxesSearchQuery
                 .from(new SearchQuery())
@@ -1226,7 +1226,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
 
             MessageId messageId = delegatedMessageManager
                 .appendMessage(AppendCommand.from(message), sessionFromDelegater)
-                .getIds().getMessageId();
+                .getId().getMessageId();
 
             mailboxManager.setRights(delegatedMailboxPath,
                 MailboxACL.EMPTY.apply(MailboxACL.command()
@@ -1376,7 +1376,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
 
             MessageId messageId = searchedMessageManager
                 .appendMessage(AppendCommand.from(message), session)
-                .getIds().getMessageId();
+                .getId().getMessageId();
 
             MultimailboxesSearchQuery multiMailboxesQuery = MultimailboxesSearchQuery
                 .from(new SearchQuery())
@@ -1842,11 +1842,11 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
 
             MessageId messageId1 = inboxMessageManager
                 .appendMessage(AppendCommand.from(message), session)
-                .getIds()
+                .getId()
                 .getMessageId();
             MessageId messageId2 = inboxMessageManager
                 .appendMessage(AppendCommand.from(message), session)
-                .getIds()
+                .getId()
                 .getMessageId();
 
             mailboxManager.moveMessages(MessageRange.all(), inbox, otherMailbox, session);
@@ -1886,10 +1886,10 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
 
             ComposedMessageId composedMessageId1 = inboxMessageManager
                 .appendMessage(AppendCommand.from(message), session)
-                .getIds();
+                .getId();
             MessageId messageId2 = inboxMessageManager
                 .appendMessage(AppendCommand.from(message), session)
-                .getIds()
+                .getId()
                 .getMessageId();
 
             mailboxManager.moveMessages(MessageRange.one(composedMessageId1.getUid()), inbox, otherMailbox, session);
@@ -1979,11 +1979,11 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
 
             MessageId messageId1 = inboxMessageManager
                 .appendMessage(AppendCommand.from(message), session)
-                .getIds()
+                .getId()
                 .getMessageId();
             MessageId messageId2 = inboxMessageManager
                 .appendMessage(AppendCommand.from(message), session)
-                .getIds()
+                .getId()
                 .getMessageId();
 
             mailboxManager.copyMessages(MessageRange.all(), inbox, otherMailbox, session);
@@ -2022,10 +2022,10 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
 
             ComposedMessageId composedMessageId1 = inboxMessageManager
                 .appendMessage(AppendCommand.from(message), session)
-                .getIds();
+                .getId();
             MessageId messageId2 = inboxMessageManager
                 .appendMessage(AppendCommand.from(message), session)
-                .getIds()
+                .getId()
                 .getMessageId();
 
             MessageId messageId1 = composedMessageId1.getMessageId();
@@ -2213,7 +2213,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             void expungeShouldCallAllPreDeletionHooks() throws Exception {
                 ComposedMessageId composeId = inboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session).getIds();
+                    .build(message), session).getId();
                 inboxManager.expunge(MessageRange.one(composeId.getUid()), session);
 
                 ArgumentCaptor<PreDeletionHook.DeleteOperation> preDeleteCaptor1 = ArgumentCaptor.forClass(PreDeletionHook.DeleteOperation.class);
@@ -2234,7 +2234,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             void deleteMailboxShouldCallAllPreDeletionHooks() throws Exception {
                 ComposedMessageId composeId = inboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session).getIds();
+                    .build(message), session).getId();
                 mailboxManager.deleteMailbox(inbox, session);
 
                 ArgumentCaptor<PreDeletionHook.DeleteOperation> preDeleteCaptor1 = ArgumentCaptor.forClass(PreDeletionHook.DeleteOperation.class);
@@ -2255,7 +2255,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             void deleteMailboxByIdShouldCallAllPreDeletionHooks() throws Exception {
                 ComposedMessageId composeId = inboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session).getIds();
+                    .build(message), session).getId();
                 mailboxManager.deleteMailbox(inboxId, session);
 
                 ArgumentCaptor<PreDeletionHook.DeleteOperation> preDeleteCaptor1 = ArgumentCaptor.forClass(PreDeletionHook.DeleteOperation.class);
@@ -2276,10 +2276,10 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             void expungeShouldCallAllPreDeletionHooksOnEachMessageDeletionCall() throws Exception {
                 ComposedMessageId composeId1 = inboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session).getIds();
+                    .build(message), session).getId();
                 ComposedMessageId composeId2 = inboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session).getIds();
+                    .build(message), session).getId();
 
                 inboxManager.expunge(MessageRange.one(composeId1.getUid()), session);
                 inboxManager.expunge(MessageRange.one(composeId2.getUid()), session);
@@ -2302,7 +2302,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             void expungeShouldCallAllPreDeletionHooksOnlyOnMessagesMarkedAsDeleted() throws Exception {
                 ComposedMessageId composeId1 = inboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session).getIds();
+                    .build(message), session).getId();
                 inboxManager.appendMessage(AppendCommand.builder()
                     .build(message), session);
 
@@ -2337,10 +2337,10 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             void expungeShouldCallAllPreDeletionHooksOnEachMessageDeletionOnDifferentMailboxes() throws Exception {
                 ComposedMessageId composeId1 = inboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session).getIds();
+                    .build(message), session).getId();
                 ComposedMessageId composeId2 = anotherMailboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session).getIds();
+                    .build(message), session).getId();
 
                 inboxManager.expunge(MessageRange.one(composeId1.getUid()), session);
                 anotherMailboxManager.expunge(MessageRange.one(composeId2.getUid()), session);
@@ -2370,7 +2370,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
 
                 ComposedMessageId composeId1 = inboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session).getIds();
+                    .build(message), session).getId();
                 assertThatThrownBy(() -> inboxManager.expunge(MessageRange.one(composeId1.getUid()), session))
                     .isInstanceOf(RuntimeException.class);
 
@@ -2397,7 +2397,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
                         return Mono.empty();
                     });
 
-                ComposedMessageId composeId1 = inboxManager.appendMessage(AppendCommand.builder().build(message), session).getIds();
+                ComposedMessageId composeId1 = inboxManager.appendMessage(AppendCommand.builder().build(message), session).getId();
                 inboxManager.setFlags(new Flags(Flags.Flag.DELETED), MessageManager.FlagsUpdateMode.ADD,
                     MessageRange.one(composeId1.getUid()), session);
                 inboxManager.expunge(MessageRange.all(), session);
@@ -2428,7 +2428,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
         void getMessagesShouldIncludeHasAttachmentInformation() throws Exception {
             ComposedMessageId composeId = inboxManager.appendMessage(AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.DELETED))
-                .build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/twoAttachmentsApi.eml")), session).getIds();
+                .build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/twoAttachmentsApi.eml")), session).getId();
 
             MessageResultIterator messages = inboxManager.getMessages(MessageRange.one(composeId.getUid()), FetchGroup.MINIMAL, session);
 
@@ -2442,7 +2442,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
         void getMessagesShouldNotIncludeAttachmentInformationWhenNone() throws Exception {
             ComposedMessageId composeId = inboxManager.appendMessage(AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.DELETED))
-                .build(message), session).getIds();
+                .build(message), session).getId();
 
             MessageResultIterator messages = inboxManager.getMessages(MessageRange.one(composeId.getUid()), FetchGroup.MINIMAL, session);
 
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/manager/ManagerTestProvisionner.java b/mailbox/api/src/test/java/org/apache/james/mailbox/manager/ManagerTestProvisionner.java
index 309d48b..45079dc 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/manager/ManagerTestProvisionner.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/manager/ManagerTestProvisionner.java
@@ -100,7 +100,7 @@ public class ManagerTestProvisionner {
     public MessageUid appendMessage(MessageManager messageManager, MailboxSession session, Flags flags) throws MailboxException, UnsupportedEncodingException {
         return messageManager.appendMessage(new ByteArrayInputStream(MockMail.MAIL_TEXT_PLAIN.getBytes(StandardCharsets.UTF_8)),
             Calendar.getInstance().getTime(), session, true, flags)
-            .getIds()
+            .getId()
             .getUid();
     }
 
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
index 51983b3..2e53000 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
@@ -131,7 +131,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
             Message.Builder.of()
                 .setTo(recipient)
                 .setBody(Strings.repeat("0à2345678é", 3200), StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
 
         elasticSearch.awaitForElasticSearch();
 
@@ -150,7 +150,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
             Message.Builder.of()
                 .setTo(recipient)
                 .setBody(Strings.repeat("0123456789", 3300), StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
 
         elasticSearch.awaitForElasticSearch();
 
@@ -169,7 +169,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
             Message.Builder.of()
                 .setTo(recipient)
                 .setBody(Strings.repeat("0123456789 ", 5000), StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
 
         elasticSearch.awaitForElasticSearch();
 
@@ -188,7 +188,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
             Message.Builder.of()
                 .setTo(recipient)
                 .setBody(Strings.repeat("0123456789 ", 5000) + " matchMe", StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
 
         elasticSearch.awaitForElasticSearch();
 
@@ -208,7 +208,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
             Message.Builder.of()
                 .setTo(recipient)
                 .setBody(reasonableLongTerm, StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
 
         elasticSearch.awaitForElasticSearch();
 
@@ -225,14 +225,14 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
         ComposedMessageId customDateHeaderMessageId = messageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(ClassLoader.getSystemResourceAsStream("eml/mailCustomDateHeader.eml")),
-            session).getIds();
+            session).getId();
 
         elasticSearch.awaitForElasticSearch();
 
         ComposedMessageId customStringHeaderMessageId = messageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(ClassLoader.getSystemResourceAsStream("eml/mailCustomStringHeader.eml")),
-            session).getIds();
+            session).getId();
 
         elasticSearch.awaitForElasticSearch();
 
@@ -256,7 +256,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
         ComposedMessageId customStringHeaderMessageId = messageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(ClassLoader.getSystemResourceAsStream("eml/mailCustomStringHeader.eml")),
-            session).getIds();
+            session).getId();
 
         elasticSearch.awaitForElasticSearch();
 
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcherTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcherTest.java
index 444628f..686af32 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcherTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcherTest.java
@@ -168,6 +168,6 @@ class ElasticSearchSearcherTest {
                 .setTo(recipient)
                 .setBody("Hello", StandardCharsets.UTF_8)),
             session)
-            .getIds();
+            .getId();
     }
 }
\ No newline at end of file
diff --git a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultHookTest.java b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultHookTest.java
index 4f0bfc5..53b9fc9 100644
--- a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultHookTest.java
+++ b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultHookTest.java
@@ -103,7 +103,7 @@ class DeletedMessageVaultHookTest {
         return messageManager.appendMessage(MessageManager.AppendCommand.builder()
                 .withInternalDate(INTERNAL_DATE)
                 .build(mailContent), aliceSession)
-            .getIds();
+            .getId();
     }
 
     @BeforeEach
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractCombinationManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractCombinationManagerTest.java
index 33a7280..f106aa7 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractCombinationManagerTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractCombinationManagerTest.java
@@ -98,7 +98,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMessageCountFromMessageManagerShouldReturnDataSetInMailboxesFromMessageIdManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -111,7 +111,7 @@ public abstract class AbstractCombinationManagerTest {
         query.andCriteria(SearchQuery.all());
 
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -124,7 +124,7 @@ public abstract class AbstractCombinationManagerTest {
         query.andCriteria(SearchQuery.all());
 
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.setInMailboxes(messageId,
             ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
@@ -142,7 +142,7 @@ public abstract class AbstractCombinationManagerTest {
         SearchQuery query = new SearchQuery();
         query.andCriteria(SearchQuery.all());
 
-        ComposedMessageId composedMessageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session).getIds();
+        ComposedMessageId composedMessageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session).getId();
 
         messageIdManager.setInMailboxes(composedMessageId.getMessageId(),
             ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
@@ -161,7 +161,7 @@ public abstract class AbstractCombinationManagerTest {
         MultimailboxesSearchQuery multiMailboxesQuery = builder.build();
 
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -173,7 +173,7 @@ public abstract class AbstractCombinationManagerTest {
     void setFlagsToDeleteThenExpungeFromMessageManagerThenGetMessageFromMessageIdManagerShouldNotReturnAnything() throws Exception {
         Flags deleted = new Flags(Flag.DELETED);
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageManager1.setFlags(deleted, FlagsUpdateMode.ADD, MessageRange.all(), session);
         messageManager1.expunge(MessageRange.all(), session);
@@ -184,7 +184,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void expungeFromMessageManagerShouldWorkWhenSetFlagsToDeletedWithMessageIdManager() throws Exception {
         Flags deleted = new Flags(Flag.DELETED);
-        ComposedMessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session).getIds();
+        ComposedMessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session).getId();
 
         messageIdManager.setFlags(deleted, FlagsUpdateMode.ADD, messageId.getMessageId(), ImmutableList.of(mailbox1.getMailboxId()), session);
 
@@ -199,7 +199,7 @@ public abstract class AbstractCombinationManagerTest {
         ComposedMessageId messageId = messageManager1.appendMessage(
             MessageManager.AppendCommand.builder()
                 .withFlags(deleted)
-                .build(mailContent), session).getIds();
+                .build(mailContent), session).getId();
 
         messageIdManager.setInMailboxes(messageId.getMessageId(), ImmutableList.of(mailbox1.getMailboxId()), session);
 
@@ -211,7 +211,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMessageFromMessageIdManagerShouldReturnMessageWhenAppendMessageFromMessageManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         assertThat(messageIdManager.getMessage(messageId, FetchGroup.MINIMAL, session)).hasSize(1);
     }
@@ -219,7 +219,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMessageFromMessageIdManagerShouldReturnMessageWhenCopyMessageWithMailboxIdFromMailboxManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         mailboxManager.copyMessages(MessageRange.all(), mailbox1.getMailboxId(), mailbox2.getMailboxId(), session);
 
@@ -233,7 +233,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMessageFromMessageIdManagerShouldReturnMessageWhenCopyMessageWithMailboxPathFromMailboxManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         mailboxManager.copyMessages(MessageRange.all(), MailboxFixture.INBOX_ALICE, MailboxFixture.OUTBOX_ALICE, session);
 
@@ -247,7 +247,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMessageFromMessageIdManagerShouldReturnMessageWhenMoveMessageWithMailboxIdFromMailboxManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         mailboxManager.moveMessages(MessageRange.all(), MailboxFixture.INBOX_ALICE, MailboxFixture.OUTBOX_ALICE, session);
 
@@ -261,7 +261,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMessagesFromMessageManagerShouldReturnMessagesCreatedBySetInMailboxesFromMessageIdManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -276,7 +276,7 @@ public abstract class AbstractCombinationManagerTest {
         ComposedMessageId messageId = messageManager1.appendMessage(
             MessageManager.AppendCommand.builder()
                 .withFlags(recent)
-                .build(mailContent), session).getIds();
+                .build(mailContent), session).getId();
 
         long mailbox2NextUid = messageManager2.getMetaData(true, session, MessageManager.MetaData.FetchGroup.UNSEEN_COUNT).getUidNext().asLong();
         messageIdManager.setInMailboxes(messageId.getMessageId(), ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
@@ -294,7 +294,7 @@ public abstract class AbstractCombinationManagerTest {
             MessageManager.AppendCommand.builder()
                 .withFlags(recent)
                 .build(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -307,7 +307,7 @@ public abstract class AbstractCombinationManagerTest {
         ComposedMessageId messageId = messageManager1.appendMessage(
             MessageManager.AppendCommand.builder()
                 .withFlags(recent)
-                .build(mailContent), session).getIds();
+                .build(mailContent), session).getId();
 
         messageIdManager.setInMailboxes(messageId.getMessageId(), ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -327,7 +327,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMetadataFromMessageManagerShouldReturnHighestModSeqWhenSetInMailboxesFromMessageIdManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -337,7 +337,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMetadataFromMessageManagerShouldReturnMessageCountWhenSetInMailboxesFromMessageIdManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -347,7 +347,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMetadataFromMessageManagerShouldReturnNumberOfUnseenMessageWhenSetInMailboxesFromMessageIdManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -356,7 +356,7 @@ public abstract class AbstractCombinationManagerTest {
 
     @Test
     void getMetadataFromMessageManagerShouldReturnFirstUnseenMessageWhenSetInMailboxesFromMessageIdManager() throws Exception {
-        ComposedMessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session).getIds();
+        ComposedMessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session).getId();
 
         messageIdManager.setInMailboxes(messageId.getMessageId(), ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -367,7 +367,7 @@ public abstract class AbstractCombinationManagerTest {
     void getMetadataFromMessageManagerShouldReturnNumberOfUnseenMessageWhenSetFlagsFromMessageIdManager() throws Exception {
         Flags newFlag = new Flags(Flag.RECENT);
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.setFlags(newFlag, FlagsUpdateMode.ADD, messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -377,7 +377,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMetadataFromMessageManagerShouldReturnFirstUnseenMessageWhenSetFlagsFromMessageIdManager() throws Exception {
         Flags newFlag = new Flags(Flag.USER);
-        ComposedMessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session).getIds();
+        ComposedMessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session).getId();
 
         messageIdManager.setFlags(newFlag, FlagsUpdateMode.ADD, messageId.getMessageId(), ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -387,7 +387,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void setInMailboxesFromMessageIdManagerShouldMoveMessage() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox2.getMailboxId()), session);
 
@@ -412,7 +412,7 @@ public abstract class AbstractCombinationManagerTest {
             MessageManager.AppendCommand.builder()
                 .withFlags(messageFlag)
                 .build(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -443,7 +443,7 @@ public abstract class AbstractCombinationManagerTest {
             MessageManager.AppendCommand.builder()
                 .withFlags(messageFlag)
                 .build(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.setFlags(deleted, FlagsUpdateMode.ADD, messageId, ImmutableList.of(mailbox1.getMailboxId()), session);
 
@@ -461,7 +461,7 @@ public abstract class AbstractCombinationManagerTest {
             MessageManager.AppendCommand.builder()
                 .withFlags(customFlag1)
                 .build(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
 
         messageIdManager.setFlags(customFlag2, FlagsUpdateMode.ADD, messageId, ImmutableList.of(mailbox1.getMailboxId()), session);
@@ -483,7 +483,7 @@ public abstract class AbstractCombinationManagerTest {
             MessageManager.AppendCommand.builder()
                 .withFlags(custom1)
                 .build(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
         messageManager2.setFlags(custom2, FlagsUpdateMode.ADD, MessageRange.all(), session);
@@ -500,7 +500,7 @@ public abstract class AbstractCombinationManagerTest {
     void getUidsShouldInteractWellWithSetInMailboxes() throws Exception {
         MessageId messageId = messageManager1
             .appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -521,7 +521,7 @@ public abstract class AbstractCombinationManagerTest {
     void getUidsShouldInteractWellWithDelete() throws Exception {
         MessageId messageId = messageManager1
             .appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.delete(messageId, ImmutableList.of(mailbox1.getMailboxId()), session);
 
@@ -533,10 +533,10 @@ public abstract class AbstractCombinationManagerTest {
     void getUidsShouldInteractWellWithDeletes() throws Exception {
         MessageId messageId1 = messageManager1
             .appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
         MessageId messageId2 = messageManager1
             .appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getIds().getMessageId();
+            .getId().getMessageId();
 
         messageIdManager.delete(ImmutableList.of(messageId1, messageId2), session);
 
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerStorageTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerStorageTest.java
index 55914ad..25fe936 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerStorageTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerStorageTest.java
@@ -969,7 +969,7 @@ public abstract class AbstractMessageIdManagerStorageTest {
             .appendMessage(MessageManager.AppendCommand.builder()
             .withFlags(new Flags(Flags.Flag.DELETED))
             .build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/twoAttachmentsApi.eml")), bobSession)
-            .getIds()
+            .getId()
             .getMessageId();
 
         List<MessageResult> messages = messageIdManager.getMessage(messageId, FetchGroup.MINIMAL, bobSession);
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
index 9063fd6..7c55990 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
@@ -133,7 +133,7 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1388617200000L),
             session,
             RECENT,
-            new Flags(Flags.Flag.DELETED)).getIds();
+            new Flags(Flags.Flag.DELETED)).getId();
         // sentDate: Thu, 4 Jun 2015 09:23:37 +0000
         // Internal date : 2014/02/02 00:00:00.000
         m2 = inboxMessageManager.appendMessage(
@@ -141,7 +141,7 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1391295600000L),
             session,
             RECENT,
-            new Flags(Flags.Flag.ANSWERED)).getIds();
+            new Flags(Flags.Flag.ANSWERED)).getId();
         // sentDate: Thu, 4 Jun 2015 09:27:37 +0000
         // Internal date : 2014/03/02 00:00:00.000
         m3 = inboxMessageManager.appendMessage(
@@ -149,7 +149,7 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1393714800000L),
             session,
             RECENT,
-            new Flags(Flags.Flag.DRAFT)).getIds();
+            new Flags(Flags.Flag.DRAFT)).getId();
         // sentDate: Tue, 2 Jun 2015 08:16:19 +0000
         // Internal date : 2014/05/02 00:00:00.000
         m4 = inboxMessageManager.appendMessage(
@@ -157,7 +157,7 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1398981600000L),
             session,
             RECENT,
-            new Flags(Flags.Flag.RECENT)).getIds();
+            new Flags(Flags.Flag.RECENT)).getId();
         // sentDate: Fri, 15 May 2015 06:35:59 +0000
         // Internal date : 2014/04/02 00:00:00.000
         m5 = inboxMessageManager.appendMessage(
@@ -165,7 +165,7 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1396389600000L),
             session,
             RECENT,
-            new Flags(Flags.Flag.FLAGGED)).getIds();
+            new Flags(Flags.Flag.FLAGGED)).getId();
         // sentDate: Wed, 03 Jun 2015 19:14:32 +0000
         // Internal date : 2014/06/02 00:00:00.000
         m6 = inboxMessageManager.appendMessage(
@@ -173,7 +173,7 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1401660000000L),
             session,
             RECENT,
-            new Flags(Flags.Flag.SEEN)).getIds();
+            new Flags(Flags.Flag.SEEN)).getId();
         // sentDate: Thu, 04 Jun 2015 07:36:08 +0000
         // Internal date : 2014/07/02 00:00:00.000
         m7 = inboxMessageManager.appendMessage(
@@ -181,7 +181,7 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1404252000000L),
             session,
             NOT_RECENT,
-            new Flags()).getIds();
+            new Flags()).getId();
         // sentDate: Thu, 4 Jun 2015 06:08:41 +0200
         // Internal date : 2014/08/02 00:00:00.000
         m8 = inboxMessageManager.appendMessage(
@@ -189,7 +189,7 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1406930400000L),
             session,
             RECENT,
-            new Flags("Hello")).getIds();
+            new Flags("Hello")).getId();
         // sentDate: Thu, 4 Jun 2015 06:08:41 +0200
         // Internal date : 2014/08/02 00:00:00.000
         mOther = myFolderMessageManager.appendMessage(
@@ -197,34 +197,34 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1406930400000L),
             session,
             RECENT,
-            new Flags(Flags.Flag.SEEN)).getIds();
+            new Flags(Flags.Flag.SEEN)).getId();
         m9 = inboxMessageManager.appendMessage(
             ClassLoader.getSystemResourceAsStream("eml/frnog.eml"),
             new Date(1409608800000L),
             session,
             RECENT,
-            new Flags("Hello you")).getIds();
+            new Flags("Hello you")).getId();
 
         mailWithAttachment = myFolderMessageManager.appendMessage(
             ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeTextInlined.eml"),
             new Date(1409608900000L),
             session,
             RECENT,
-            new Flags("Hello you")).getIds();
+            new Flags("Hello you")).getId();
 
         mailWithInlinedAttachment = myFolderMessageManager.appendMessage(
             ClassLoader.getSystemResourceAsStream("eml/oneInlinedAttachment.eml"),
             new Date(1409608900000L),
             session,
             RECENT,
-            new Flags("Hello you")).getIds();
+            new Flags("Hello you")).getId();
 
         m10 = otherInboxMessageManager.appendMessage(
             ClassLoader.getSystemResourceAsStream("eml/mail1.eml"),
             new Date(1391295600000L),
             otherSession,
             RECENT,
-            new Flags()).getIds();
+            new Flags()).getId();
 
         await();
     }
@@ -422,7 +422,7 @@ public abstract class AbstractMessageSearchIndexTest {
         ComposedMessageId mailWithDotsInHeader = myFolderMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(ClassLoader.getSystemResourceAsStream("eml/headerWithDot.eml")),
-            session).getIds();
+            session).getId();
         await();
         
         SearchQuery searchQuery = new SearchQuery(SearchQuery.all());
@@ -437,7 +437,7 @@ public abstract class AbstractMessageSearchIndexTest {
         ComposedMessageId mailWithDotsInHeader = myFolderMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(ClassLoader.getSystemResourceAsStream("eml/headerWithDot.eml")),
-            session).getIds();
+            session).getId();
         await();
 
         SearchQuery searchQuery = new SearchQuery(SearchQuery.headerExists("X-header.with.dots"));
@@ -453,7 +453,7 @@ public abstract class AbstractMessageSearchIndexTest {
         ComposedMessageId m11 = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
             .build(ClassLoader.getSystemResourceAsStream("eml/mail5.eml")),
-            session).getIds();
+            session).getId();
 
         String emailToSearch = "luc.duzan@james.apache.org";
 
@@ -1362,7 +1362,7 @@ public abstract class AbstractMessageSearchIndexTest {
         ComposedMessageId messageWithBeautifulBananaAsTextAttachment = myFolderMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
             .build(ClassLoader.getSystemResourceAsStream("eml/emailWithTextAttachment.eml")),
-            session).getIds();
+            session).getId();
         await();
 
         SearchQuery searchQuery = new SearchQuery(SearchQuery.mailContains("User message banana"));
@@ -1377,7 +1377,7 @@ public abstract class AbstractMessageSearchIndexTest {
         ComposedMessageId messageWithBeautifulBananaAsTextAttachment = myFolderMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(ClassLoader.getSystemResourceAsStream("eml/emailWithTextAttachment.eml")),
-            session).getIds();
+            session).getId();
         await();
 
         SearchQuery searchQuery = new SearchQuery(SearchQuery.attachmentContains("beautiful banana"));
@@ -1401,7 +1401,7 @@ public abstract class AbstractMessageSearchIndexTest {
                 .setBody(multipart)
                 .build();
         ComposedMessageId messageWithBeautifulBananaAsPDFAttachment = myFolderMessageManager
-            .appendMessage(MessageManager.AppendCommand.from(message), session).getIds();
+            .appendMessage(MessageManager.AppendCommand.from(message), session).getId();
         await();
 
         SearchQuery searchQuery = new SearchQuery(SearchQuery.attachmentContains("beautiful banana"));
@@ -1441,19 +1441,19 @@ public abstract class AbstractMessageSearchIndexTest {
             .build(Message.Builder.of()
                 .setSubject("test")
                 .setBody("testmail", StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
         ComposedMessageId message2 = messageManager.appendMessage(MessageManager.AppendCommand.builder()
             .withInternalDate(date2)
             .build(Message.Builder.of()
                 .setSubject("test")
                 .setBody("testmail", StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
         ComposedMessageId message3 = messageManager.appendMessage(MessageManager.AppendCommand.builder()
             .withInternalDate(date3)
             .build(Message.Builder.of()
                 .setSubject("test")
                 .setBody("testmail", StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
 
         await();
 
@@ -1480,7 +1480,7 @@ public abstract class AbstractMessageSearchIndexTest {
             .withInternalDate(date1)
             .build(Message.Builder.of()
                 .setSubject("test")
-                .setBody("testmail", StandardCharsets.UTF_8)), session).getIds();
+                .setBody("testmail", StandardCharsets.UTF_8)), session).getId();
         ComposedMessageId message2 = messageManager.appendMessage(MessageManager.AppendCommand.builder()
             .withInternalDate(date2)
             .build(Message.Builder.of()
@@ -1488,12 +1488,12 @@ public abstract class AbstractMessageSearchIndexTest {
                 .setDate(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
                     .parse("2017/08/23 00:00:00 "), TimeZone.getTimeZone(ZoneId.of("+0200")))
                 .setBody("testmail", StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
         ComposedMessageId message3 = messageManager.appendMessage(MessageManager.AppendCommand.builder()
             .withInternalDate(date3)
             .build(Message.Builder.of()
                 .setSubject("test")
-                .setBody("testmail", StandardCharsets.UTF_8)), session).getIds();
+                .setBody("testmail", StandardCharsets.UTF_8)), session).getId();
 
         await();
 
@@ -1555,7 +1555,7 @@ public abstract class AbstractMessageSearchIndexTest {
                                     .build())
                                 .build())
                             .build())),
-            session).getIds();
+            session).getId();
 
         await();
 
diff --git a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/MessageIdReIndexerImplTest.java b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/MessageIdReIndexerImplTest.java
index 694a73c..5aefb71 100644
--- a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/MessageIdReIndexerImplTest.java
+++ b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/MessageIdReIndexerImplTest.java
@@ -67,7 +67,7 @@ public class MessageIdReIndexerImplTest {
         ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
             .appendMessage(
                 MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                systemSession).getIds();
+                systemSession).getId();
 
         reIndexer.reIndex(createdMessage.getMessageId()).run();
 
diff --git a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/ReIndexerImplTest.java b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/ReIndexerImplTest.java
index 7399e20..f38f39c 100644
--- a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/ReIndexerImplTest.java
+++ b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/ReIndexerImplTest.java
@@ -71,7 +71,7 @@ public class ReIndexerImplTest {
         ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
             .appendMessage(
                 MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                systemSession).getIds();
+                systemSession).getId();
 
         reIndexer.reIndex(INBOX).run();
 
@@ -98,7 +98,7 @@ public class ReIndexerImplTest {
         ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
             .appendMessage(
                 MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                systemSession).getIds();
+                systemSession).getId();
 
         reIndexer.reIndex().run();
         ArgumentCaptor<MailboxMessage> messageCaptor = ArgumentCaptor.forClass(MailboxMessage.class);
@@ -124,7 +124,7 @@ public class ReIndexerImplTest {
         ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
             .appendMessage(
                 MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                systemSession).getIds();
+                systemSession).getId();
 
         reIndexer.reIndex(USERNAME).run();
         ArgumentCaptor<MailboxMessage> messageCaptor = ArgumentCaptor.forClass(MailboxMessage.class);
@@ -150,7 +150,7 @@ public class ReIndexerImplTest {
         ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
             .appendMessage(
                 MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                systemSession).getIds();
+                systemSession).getId();
 
         reIndexer.reIndex(INBOX, createdMessage.getUid()).run();
         ArgumentCaptor<MailboxMessage> messageCaptor = ArgumentCaptor.forClass(MailboxMessage.class);
@@ -173,7 +173,7 @@ public class ReIndexerImplTest {
         ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
             .appendMessage(
                 MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                systemSession).getIds();
+                systemSession).getId();
 
         reIndexer.reIndex(mailboxId, createdMessage.getUid()).run();
         ArgumentCaptor<MailboxMessage> messageCaptor = ArgumentCaptor.forClass(MailboxMessage.class);
@@ -216,7 +216,7 @@ public class ReIndexerImplTest {
         ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
             .appendMessage(
                 MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                systemSession).getIds();
+                systemSession).getId();
 
         reIndexer.reIndex(mailboxId).run();
         ArgumentCaptor<MailboxMessage> messageCaptor = ArgumentCaptor.forClass(MailboxMessage.class);
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/AppendProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/AppendProcessor.java
index 1efaedb..5fe4aa5 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/AppendProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/AppendProcessor.java
@@ -128,7 +128,7 @@ public class AppendProcessor extends AbstractMailboxProcessor<AppendRequest> {
             final SelectedMailbox selectedMailbox = session.getSelected();
             final boolean isSelectedMailbox = selectedMailbox != null && selectedMailbox.getMailboxId().equals(mailbox.getId());
             final ComposedMessageId messageId = mailbox.appendMessage(message, datetime, mailboxSession, !isSelectedMailbox, flagsToBeSet)
-                .getIds();
+                .getId();
             if (isSelectedMailbox) {
                 selectedMailbox.addRecent(messageId.getUid());
             }
diff --git a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java
index c5b0c54..97e0c16 100644
--- a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java
+++ b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java
@@ -152,7 +152,7 @@ public class MailboxProbeImpl implements GuiceProbe, MailboxProbe {
 
         MailboxSession mailboxSession = mailboxManager.createSystemSession(Username.of(username));
         MessageManager messageManager = mailboxManager.getMailbox(mailboxPath, mailboxSession);
-        return messageManager.appendMessage(message, internalDate, mailboxSession, isRecent, flags).getIds();
+        return messageManager.appendMessage(message, internalDate, mailboxSession, isRecent, flags).getId();
     }
 
     public ComposedMessageId appendMessage(String username, MailboxPath mailboxPath, MessageManager.AppendCommand appendCommand)
@@ -160,7 +160,7 @@ public class MailboxProbeImpl implements GuiceProbe, MailboxProbe {
 
         MailboxSession mailboxSession = mailboxManager.createSystemSession(Username.of(username));
         MessageManager messageManager = mailboxManager.getMailbox(mailboxPath, mailboxSession);
-        return messageManager.appendMessage(appendCommand, mailboxSession).getIds();
+        return messageManager.appendMessage(appendCommand, mailboxSession).getId();
     }
 
     @Override
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailboxAppender.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailboxAppender.java
index f552ca4..3f1e8f5 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailboxAppender.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailboxAppender.java
@@ -51,7 +51,7 @@ public class MailboxAppender {
     public ComposedMessageId append(MimeMessage mail, Username user, String folder) throws MessagingException {
         MailboxSession session = createMailboxSession(user);
         return append(mail, user, useSlashAsSeparator(folder, session), session)
-            .getIds();
+            .getId();
     }
 
     private String useSlashAsSeparator(String urlPath, MailboxSession session) throws MessagingException {
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageAppender.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageAppender.java
index 3b76e13..f816549 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageAppender.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageAppender.java
@@ -91,7 +91,7 @@ public class MessageAppender {
                 .notRecent()
                 .build(content),
             session);
-        ComposedMessageId ids = appendResult.getIds();
+        ComposedMessageId ids = appendResult.getId();
         if (targetMailboxes.size() > 1) {
             messageIdManager.setInMailboxes(ids.getMessageId(), targetMailboxes, session);
         }
@@ -121,7 +121,7 @@ public class MessageAppender {
         AppendResult appendResult = messageManager.appendMessage(MessageManager.AppendCommand.builder()
             .withFlags(flags)
             .build(content), session);
-        ComposedMessageId ids = appendResult.getIds();
+        ComposedMessageId ids = appendResult.getId();
 
         return MetaDataWithContent.builder()
             .uid(ids.getUid())
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/MessageFastViewProjectionItemFactoryTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/MessageFastViewProjectionItemFactoryTest.java
index a042f8e..f3a0690 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/MessageFastViewProjectionItemFactoryTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/MessageFastViewProjectionItemFactoryTest.java
@@ -136,7 +136,7 @@ class MessageFastViewProjectionItemFactoryTest {
 
     MessageResult toMessageResult(String messageAsString) throws Exception {
         ComposedMessageId composedMessageId = mailbox.appendMessage(MessageManager.AppendCommand.builder()
-            .build(messageAsString), session).getIds();
+            .build(messageAsString), session).getId();
 
         return mailbox.getMessages(MessageRange.one(composedMessageId.getUid()), FetchGroup.FULL_CONTENT, session)
             .next();
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/GetMessagesMethodTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/GetMessagesMethodTest.java
index c726407..4103ff3 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/GetMessagesMethodTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/GetMessagesMethodTest.java
@@ -180,9 +180,9 @@ public class GetMessagesMethodTest {
     @SuppressWarnings("unchecked")
     public void processShouldFetchMessages() throws Exception {
         MessageManager inbox = mailboxManager.getMailbox(inboxPath, session);
-        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session).getIds();
-        ComposedMessageId message2 = inbox.appendMessage(AppendCommand.from(messageContent2), session).getIds();
-        ComposedMessageId message3 = inbox.appendMessage(AppendCommand.from(messageContent3), session).getIds();
+        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session).getId();
+        ComposedMessageId message2 = inbox.appendMessage(AppendCommand.from(messageContent2), session).getId();
+        ComposedMessageId message3 = inbox.appendMessage(AppendCommand.from(messageContent3), session).getId();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId(),
@@ -215,7 +215,7 @@ public class GetMessagesMethodTest {
                 org.apache.james.mime4j.dom.Message.Builder.of()
                     .setSubject("message 1 subject")
                     .setBody("my <b>HTML</b> message", "html", StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message.getMessageId()))
@@ -237,7 +237,7 @@ public class GetMessagesMethodTest {
     @Test
     public void processShouldReturnOnlyMandatoryPropertiesOnEmptyPropertyList() throws Exception {
         MessageManager inbox = mailboxManager.getMailbox(inboxPath, session);
-        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(this.messageContent1), session).getIds();
+        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(this.messageContent1), session).getId();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId()))
@@ -255,7 +255,7 @@ public class GetMessagesMethodTest {
     public void processShouldReturnAllPropertiesWhenNoPropertyGiven() throws Exception {
         MessageManager inbox = mailboxManager.getMailbox(inboxPath, session);
 
-        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session).getIds();
+        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session).getId();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId()))
@@ -271,7 +271,7 @@ public class GetMessagesMethodTest {
     public void processShouldAddMandatoryPropertiesWhenNotInPropertyList() throws Exception {
         MessageManager inbox = mailboxManager.getMailbox(inboxPath, session);
 
-        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session).getIds();
+        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session).getId();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId()))
@@ -290,7 +290,7 @@ public class GetMessagesMethodTest {
     public void processShouldReturnTextBodyWhenBodyInPropertyListAndEmptyHtmlBody() throws Exception {
         MessageManager inbox = mailboxManager.getMailbox(inboxPath, session);
 
-        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session).getIds();
+        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session).getId();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId()))
@@ -316,7 +316,7 @@ public class GetMessagesMethodTest {
                 org.apache.james.mime4j.dom.Message.Builder.of()
                     .setSubject("message 1 subject")
                     .setBody("my <b>HTML</b> message", "html", StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message.getMessageId()))
@@ -344,7 +344,7 @@ public class GetMessagesMethodTest {
             AppendCommand.from(org.apache.james.mime4j.dom.Message.Builder.of()
                 .setSubject("message 1 subject")
                 .setBody("", "html", StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message.getMessageId()))
@@ -378,7 +378,7 @@ public class GetMessagesMethodTest {
                     .addBodyPart(BodyPartBuilder.create()
                         .setBody("<a>The </a> <strong>HTML</strong> message", "html", StandardCharsets.UTF_8))
                     .build())),
-            session).getIds();
+            session).getId();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message.getMessageId()))
@@ -409,7 +409,7 @@ public class GetMessagesMethodTest {
                     .setField(new RawField("HEADer2", "Header2Content"))
                     .setSubject("message 1 subject")
                     .setBody("my message", StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId()))
@@ -437,7 +437,7 @@ public class GetMessagesMethodTest {
                     .setField(new RawField("HEADer2", "Header2Content"))
                     .setSubject("message 1 subject")
                     .setBody("my message", StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId()))
@@ -469,7 +469,7 @@ public class GetMessagesMethodTest {
                     .setField(new RawField("HEADer2", "Header2Content"))
                     .setSubject("message 1 subject")
                     .setBody("my message", StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
 
         MailboxId customMailboxId = mailboxManager.getMailbox(customMailboxPath, session).getId();
         messageIdManager.setInMailboxes(message1.getMessageId(),
@@ -506,7 +506,7 @@ public class GetMessagesMethodTest {
                     .setField(new RawField("HEADer2", "Header2Content"))
                     .setSubject("message 1 subject")
                     .setBody("my message", StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
 
         MailboxId customMailboxId = mailboxManager.getMailbox(customMailboxPath, session).getId();
         messageIdManager.setInMailboxes(message1.getMessageId(),
@@ -541,7 +541,7 @@ public class GetMessagesMethodTest {
                     .setField(new RawField("HEADer2", "Header2Content"))
                     .setSubject("message 1 subject")
                     .setBody("my message", StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
 
         MailboxId customMailboxId = mailboxManager.getMailbox(customMailboxPath, session).getId();
         messageIdManager.setInMailboxes(message1.getMessageId(),
@@ -576,7 +576,7 @@ public class GetMessagesMethodTest {
                     .setField(new RawField("HEADer2", "Header2Content"))
                     .setSubject("message 1 subject")
                     .setBody("my message", StandardCharsets.UTF_8)),
-            session).getIds();
+            session).getId();
 
         MailboxId customMailboxId = mailboxManager.getMailbox(customMailboxPath, session).getId();
         messageIdManager.setInMailboxes(message1.getMessageId(),
@@ -611,8 +611,8 @@ public class GetMessagesMethodTest {
             .setBody("my message", StandardCharsets.UTF_8)
             .build();
 
-        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent), session).getIds();
-        ComposedMessageId message2 = inbox.appendMessage(AppendCommand.from(messageContent), session).getIds();
+        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent), session).getId();
+        ComposedMessageId message2 = inbox.appendMessage(AppendCommand.from(messageContent), session).getId();
 
         doCallRealMethod()
             .doThrow(new RuntimeException())
@@ -643,17 +643,17 @@ public class GetMessagesMethodTest {
             AppendCommand.builder()
                 .withFlags(flags)
                 .build(messageContent1),
-            session).getIds();
+            session).getId();
         ComposedMessageId message2 = inbox.appendMessage(
             AppendCommand.builder()
                 .withFlags(flags)
                 .build(messageContent2),
-            session).getIds();
+            session).getId();
         ComposedMessageId message3 = inbox.appendMessage(
             AppendCommand.builder()
                 .withFlags(flags)
                 .build(messageContent3),
-            session).getIds();
+            session).getId();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId(),
@@ -702,17 +702,17 @@ public class GetMessagesMethodTest {
             AppendCommand.builder()
                 .withFlags(flags1)
                 .build(messageContent1),
-            session).getIds();
+            session).getId();
         ComposedMessageId message2 = inbox.appendMessage(
             AppendCommand.builder()
                 .withFlags(flags2)
                 .build(messageContent2),
-            session).getIds();
+            session).getId();
         ComposedMessageId message3 = inbox.appendMessage(
             AppendCommand.builder()
                 .withFlags(flags3)
                 .build(messageContent3),
-            session).getIds();
+            session).getId();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId(),
@@ -756,7 +756,7 @@ public class GetMessagesMethodTest {
             AppendCommand.builder()
                 .withFlags(flags)
                 .build(messageContent1),
-            session).getIds();
+            session).getId();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId()))
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFastViewFactoryTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFastViewFactoryTest.java
index a871a02..3c4d2de 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFastViewFactoryTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFastViewFactoryTest.java
@@ -121,19 +121,19 @@ class MessageFastViewFactoryTest {
         previewComputedMessage1 = bobInbox.appendMessage(MessageManager.AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.SEEN))
                 .build(ClassLoaderUtils.getSystemResourceAsSharedStream("fullMessage.eml")),
-            session).getIds();
+            session).getId();
         missingPreviewComputedMessage1 = bobInbox.appendMessage(MessageManager.AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.SEEN))
                 .build(ClassLoaderUtils.getSystemResourceAsSharedStream("fullMessage.eml")),
-            session).getIds();
+            session).getId();
         previewComputedMessage2 = bobInbox.appendMessage(MessageManager.AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.SEEN))
                 .build(ClassLoaderUtils.getSystemResourceAsSharedStream("fullMessage.eml")),
-            session).getIds();
+            session).getId();
         previewComputedMessage3 = bobInbox.appendMessage(MessageManager.AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.SEEN))
                 .build(ClassLoaderUtils.getSystemResourceAsSharedStream("fullMessage.eml")),
-            session).getIds();
+            session).getId();
 
         fastViewProjection = new MemoryMessageFastViewProjection(new RecordingMetricFactory());
 
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java
index 4805f1e..48846ea 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java
@@ -121,7 +121,7 @@ class MessageFullViewFactoryTest {
         message1 = bobInbox.appendMessage(MessageManager.AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.SEEN))
                 .build(ClassLoaderUtils.getSystemResourceAsSharedStream("fullMessage.eml")),
-            session).getIds();
+            session).getId();
 
         fastViewProjection = spy(new MemoryMessageFastViewProjection(new RecordingMetricFactory()));
         messageFullViewFactory = new MessageFullViewFactory(resources.getBlobManager(), messageContentExtractor, htmlTextExtractor,
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageHeaderViewFactoryTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageHeaderViewFactoryTest.java
index 06b28fc..b10f4fc 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageHeaderViewFactoryTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageHeaderViewFactoryTest.java
@@ -74,7 +74,7 @@ class MessageHeaderViewFactoryTest {
         message1 = bobInbox.appendMessage(MessageManager.AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.SEEN))
                 .build(ClassLoaderUtils.getSystemResourceAsSharedStream("fullMessage.eml")),
-            session).getIds();
+            session).getId();
 
         testee = new MessageHeaderViewFactory(resources.getBlobManager(), messageIdManager);
     }
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageMetadataViewFactoryTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageMetadataViewFactoryTest.java
index f1423c8..5297c72 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageMetadataViewFactoryTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageMetadataViewFactoryTest.java
@@ -66,7 +66,7 @@ class MessageMetadataViewFactoryTest {
         message1 = bobInbox.appendMessage(MessageManager.AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.SEEN))
                 .build("header: value\r\n\r\nbody"),
-            session).getIds();
+            session).getId();
 
         testee = new MessageMetadataViewFactory(resources.getBlobManager(), messageIdManager);
     }
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/send/PostDequeueDecoratorTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/send/PostDequeueDecoratorTest.java
index 2111440..8366beb 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/send/PostDequeueDecoratorTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/send/PostDequeueDecoratorTest.java
@@ -114,7 +114,7 @@ public class PostDequeueDecoratorTest {
         mailboxManager.createMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
         mailboxManager.createMailbox(SENT_MAILBOX_PATH, mailboxSession);
         MessageManager messageManager = mailboxManager.getMailbox(SENT_MAILBOX_PATH, mailboxSession);
-        ComposedMessageId sentMessageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getIds();
+        ComposedMessageId sentMessageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getId();
         mail.setAttribute(messageIdAttribute(sentMessageId.getMessageId().serialize()));
         mail.setAttribute(USERNAME_ATTRIBUTE);
         
@@ -126,7 +126,7 @@ public class PostDequeueDecoratorTest {
         MailboxSession mailboxSession = mailboxManager.createSystemSession(USERNAME);
         mailboxManager.createMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
         MessageManager messageManager = mailboxManager.getMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
-        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getIds();
+        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getId();
         mail.setAttribute(messageIdAttribute(messageId.getMessageId().serialize()));
         mail.setAttribute(USERNAME_ATTRIBUTE);
 
@@ -139,7 +139,7 @@ public class PostDequeueDecoratorTest {
         mailboxManager.createMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
         mailboxManager.createMailbox(SENT_MAILBOX_PATH, mailboxSession);
         MessageManager messageManager = mailboxManager.getMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
-        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getIds();
+        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getId();
         mail.setAttribute(messageIdAttribute(messageId.getMessageId().serialize()));
         mail.setAttribute(USERNAME_ATTRIBUTE);
         
@@ -157,7 +157,7 @@ public class PostDequeueDecoratorTest {
         mailboxManager.createMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
         mailboxManager.createMailbox(SENT_MAILBOX_PATH, mailboxSession);
         MessageManager messageManager = mailboxManager.getMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
-        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getIds();
+        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getId();
         mail.setAttribute(messageIdAttribute(messageId.getMessageId().serialize()));
         mail.setAttribute(USERNAME_ATTRIBUTE);
         
@@ -175,7 +175,7 @@ public class PostDequeueDecoratorTest {
         mailboxManager.createMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
         mailboxManager.createMailbox(SENT_MAILBOX_PATH, mailboxSession);
         MessageManager messageManager = mailboxManager.getMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
-        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getIds();
+        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getId();
         mail.setAttribute(messageIdAttribute(messageId.getMessageId().serialize()));
         mail.setAttribute(USERNAME_ATTRIBUTE);
         
@@ -209,7 +209,7 @@ public class PostDequeueDecoratorTest {
         mailboxManager.createMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
         mailboxManager.createMailbox(SENT_MAILBOX_PATH, mailboxSession);
         MessageManager messageManager = mailboxManager.getMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
-        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getIds();
+        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getId();
         mail.setAttribute(messageIdAttribute(messageId.getMessageId().serialize()));
         
         testee.done(true);
@@ -265,7 +265,7 @@ public class PostDequeueDecoratorTest {
         mailboxManager.createMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
         MailboxId sentMailboxId = mailboxManager.createMailbox(SENT_MAILBOX_PATH, mailboxSession).get();
         MessageManager messageManager = mailboxManager.getMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
-        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getIds();
+        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getId();
         mail.setAttribute(messageIdAttribute(messageId.getMessageId().serialize()));
         mail.setAttribute(USERNAME_ATTRIBUTE);
 
@@ -293,7 +293,7 @@ public class PostDequeueDecoratorTest {
         mailboxManager.createMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
         mailboxManager.createMailbox(SENT_MAILBOX_PATH, mailboxSession).get();
         MessageManager messageManager = mailboxManager.getMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
-        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getIds();
+        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getId();
         mail.setAttribute(messageIdAttribute(messageId.getMessageId().serialize()));
         mail.setAttribute(USERNAME_ATTRIBUTE);
 
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/event/ComputeMessageFastViewProjectionListenerTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/event/ComputeMessageFastViewProjectionListenerTest.java
index ce2c2a8..98794c1 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/event/ComputeMessageFastViewProjectionListenerTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/event/ComputeMessageFastViewProjectionListenerTest.java
@@ -162,7 +162,7 @@ class ComputeMessageFastViewProjectionListenerTest {
         ComposedMessageId composedId = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(previewMessage()),
-            mailboxSession).getIds();
+            mailboxSession).getId();
 
         assertThat(Mono.from(messageFastViewProjection.retrieve(composedId.getMessageId())).block())
             .isEqualTo(PRECOMPUTED_PROPERTIES_PREVIEW);
@@ -173,7 +173,7 @@ class ComputeMessageFastViewProjectionListenerTest {
         ComposedMessageId composedId = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(emptyMessage()),
-            mailboxSession).getIds();
+            mailboxSession).getId();
 
         assertThat(Mono.from(messageFastViewProjection.retrieve(composedId.getMessageId())).block())
             .isEqualTo(PRECOMPUTED_PROPERTIES_EMPTY);
@@ -184,7 +184,7 @@ class ComputeMessageFastViewProjectionListenerTest {
         ComposedMessageId composedId = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(ClassLoaderUtils.getSystemResourceAsSharedStream("fullMessage.eml")),
-            mailboxSession).getIds();
+            mailboxSession).getId();
 
         assertThat(Mono.from(messageFastViewProjection.retrieve(composedId.getMessageId())).block())
             .isEqualTo(PRECOMPUTED_PROPERTIES_PREVIEW_HAS_ATTACHMENT);
@@ -195,7 +195,7 @@ class ComputeMessageFastViewProjectionListenerTest {
         ComposedMessageId composedId = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(ClassLoaderUtils.getSystemResourceAsSharedStream("emptyBodyMessageWithOneAttachment.eml")),
-            mailboxSession).getIds();
+            mailboxSession).getId();
 
         assertThat(Mono.from(messageFastViewProjection.retrieve(composedId.getMessageId())).block())
             .isEqualTo(PRECOMPUTED_PROPERTIES_HAS_ATTACHMENT);
@@ -206,12 +206,12 @@ class ComputeMessageFastViewProjectionListenerTest {
         ComposedMessageId composedId1 = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(previewMessage()),
-            mailboxSession).getIds();
+            mailboxSession).getId();
 
         ComposedMessageId composedId2 = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(emptyMessage()),
-            mailboxSession).getIds();
+            mailboxSession).getId();
 
         SoftAssertions.assertSoftly(softly -> {
             softly.assertThat(Mono.from(messageFastViewProjection.retrieve(composedId1.getMessageId())).block())
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java
index c58245b..efb642b 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java
@@ -304,7 +304,7 @@ class RecomputeAllFastViewProjectionItemsRequestToTaskTest {
         Optional<MailboxId> mailboxId = mailboxManager.createMailbox(MailboxPath.inbox(BOB), session);
         ComposedMessageId messageId = mailboxManager.getMailbox(mailboxId.get(), session).appendMessage(
             MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-            session).getIds();
+            session).getId();
 
         String taskId = with()
             .queryParam("action", "recomputeFastViewProjectionItems")
@@ -327,7 +327,7 @@ class RecomputeAllFastViewProjectionItemsRequestToTaskTest {
         Optional<MailboxId> mailboxId = mailboxManager.createMailbox(MailboxPath.inbox(BOB), session);
         ComposedMessageId messageId = mailboxManager.getMailbox(mailboxId.get(), session).appendMessage(
             MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-            session).getIds();
+            session).getId();
 
         String taskId1 = with()
             .queryParam("action", "recomputeFastViewProjectionItems")
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTaskTest.java b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTaskTest.java
index 866cc7a..41b1291 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTaskTest.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTaskTest.java
@@ -372,7 +372,7 @@ class RecomputeUserFastViewProjectionItemsRequestToTaskTest {
     void recomputeUserShouldUpdateProjection() throws Exception {
         ComposedMessageId messageId = mailboxManager.getMailbox(bobInboxboxId, bobSession).appendMessage(
             MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-            bobSession).getIds();
+            bobSession).getId();
 
         String taskId = with()
             .queryParam("action", "recomputeFastViewProjectionItems")
@@ -392,7 +392,7 @@ class RecomputeUserFastViewProjectionItemsRequestToTaskTest {
     void recomputeUserShouldBeIdempotent() throws Exception {
         ComposedMessageId messageId = mailboxManager.getMailbox(bobInboxboxId, bobSession).appendMessage(
             MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-            bobSession).getIds();
+            bobSession).getId();
 
         String taskId1 = with()
             .queryParam("action", "recomputeFastViewProjectionItems")
diff --git a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/RestoreService.java b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/RestoreService.java
index 3331980..4c36958 100644
--- a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/RestoreService.java
+++ b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/RestoreService.java
@@ -80,7 +80,7 @@ class RestoreService {
     private Mono<RestoreResult> appendToMailbox(MessageManager restoreMailboxManager, DeletedMessage deletedMessage, MailboxSession session) {
         return appendCommand(deletedMessage)
             .map(Throwing.<AppendCommand, ComposedMessageId>function(
-                appendCommand -> restoreMailboxManager.appendMessage(appendCommand, session).getIds()).sneakyThrow())
+                appendCommand -> restoreMailboxManager.appendMessage(appendCommand, session).getId()).sneakyThrow())
             .map(any -> RESTORE_SUCCEED)
             .onErrorResume(throwable -> {
                 LOGGER.error("append message {} to restore mailbox of user {} didn't success",
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MailboxesRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MailboxesRoutesTest.java
index cba4c7a..9d211d4 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MailboxesRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MailboxesRoutesTest.java
@@ -207,7 +207,7 @@ class MailboxesRoutesTest {
                 ComposedMessageId composedMessageId = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession).getIds();
+                        systemSession).getId();
 
                 doThrow(new RuntimeException())
                     .when(searchIndex)
@@ -244,7 +244,7 @@ class MailboxesRoutesTest {
                 ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession).getIds();
+                        systemSession).getId();
 
                 String taskId = with()
                     .post("/mailboxes?task=reIndex")
@@ -395,7 +395,7 @@ class MailboxesRoutesTest {
                 ComposedMessageId composedMessageId = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession).getIds();
+                        systemSession).getId();
 
                 doThrow(new RuntimeException())
                     .when(searchIndex)
@@ -433,7 +433,7 @@ class MailboxesRoutesTest {
                 ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession).getIds();
+                        systemSession).getId();
 
                 String taskId = when()
                     .post("/mailboxes/" + mailboxId.serialize() + "?task=reIndex")
@@ -566,7 +566,7 @@ class MailboxesRoutesTest {
                 ComposedMessageId composedMessageId = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession).getIds();
+                        systemSession).getId();
 
                 String taskId = when()
                     .post("/mailboxes/" + mailboxId.serialize() + "/mails/"
@@ -599,7 +599,7 @@ class MailboxesRoutesTest {
                 ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession).getIds();
+                        systemSession).getId();
 
                 String taskId = when()
                     .post("/mailboxes/" + mailboxId.serialize() + "/mails/"
@@ -781,7 +781,7 @@ class MailboxesRoutesTest {
                 ComposedMessageId composedMessageId = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession).getIds();
+                        systemSession).getId();
 
                 doThrow(new RuntimeException())
                     .when(searchIndex)
@@ -829,7 +829,7 @@ class MailboxesRoutesTest {
                 ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession).getIds();
+                        systemSession).getId();
 
                 doThrow(new RuntimeException()).when(searchIndex).add(any(MailboxSession.class), any(Mailbox.class), any(MailboxMessage.class));
 
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MessageRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MessageRoutesTest.java
index 4ac0ccd..63c1a0a 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MessageRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MessageRoutesTest.java
@@ -166,7 +166,7 @@ class MessageRoutesTest {
                 ComposedMessageId composedMessageId = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession).getIds();
+                        systemSession).getId();
 
                 String taskId = when()
                     .post("/messages/" + composedMessageId.getMessageId().serialize() + "?task=reIndex")
@@ -197,7 +197,7 @@ class MessageRoutesTest {
                 ComposedMessageId composedMessageId = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession).getIds();
+                        systemSession).getId();
 
                 String taskId = when()
                     .post("/messages/" + composedMessageId.getMessageId().serialize() + "?task=reIndex")
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java
index 4cc023f..7b6875d 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java
@@ -1159,7 +1159,7 @@ class UserMailboxesRoutesTest {
                 ComposedMessageId composedMessageId = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession).getIds();
+                        systemSession).getId();
 
                 doThrow(new RuntimeException())
                     .when(searchIndex)
@@ -1197,7 +1197,7 @@ class UserMailboxesRoutesTest {
                 ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession).getIds();
+                        systemSession).getId();
 
                 String taskId = given()
                     .queryParam("task", "reIndex")
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/ExportServiceTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/ExportServiceTest.java
index e21fc07..fa0c391 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/ExportServiceTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/ExportServiceTest.java
@@ -116,7 +116,7 @@ class ExportServiceTest {
             .appendMessage(MessageManager.AppendCommand.builder()
                     .build(message),
                 testSystem.bobSession)
-            .getIds();
+            .getId();
     }
 
     @Test
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/MailboxesExportRequestToTaskTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/MailboxesExportRequestToTaskTest.java
index 9dfe1e5..ab9eb19 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/MailboxesExportRequestToTaskTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/MailboxesExportRequestToTaskTest.java
@@ -348,7 +348,7 @@ class MailboxesExportRequestToTaskTest {
 
         ComposedMessageId id = testSystem.mailboxManager.getMailbox(bobInboxboxId, testSystem.bobSession).appendMessage(
             MessageManager.AppendCommand.builder().build(MESSAGE_CONTENT),
-            testSystem.bobSession).getIds();
+            testSystem.bobSession).getId();
 
         String taskId = with()
             .queryParam("action", "export")
@@ -375,7 +375,7 @@ class MailboxesExportRequestToTaskTest {
 
         ComposedMessageId id = testSystem.mailboxManager.getMailbox(bobInboxboxId, testSystem.bobSession).appendMessage(
             MessageManager.AppendCommand.builder().build(MESSAGE_CONTENT),
-            testSystem.bobSession).getIds();
+            testSystem.bobSession).getId();
 
         testSystem.usersRepository.addUser(CEDRIC, PASSWORD);
         MailboxSession cedricSession = testSystem.mailboxManager.createSystemSession(CEDRIC);


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


[james-project] 04/37: JAMES-2997 step #2 Remove Attachment::toBlob method

Posted by bt...@apache.org.
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 8f286b5537831aeeea403bae8eb73d9c03a5fcc9
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Mon Dec 9 11:06:10 2019 +0100

    JAMES-2997 step #2 Remove Attachment::toBlob method
    
    We furthermore take the opportunity to lazy load blob content
---
 .../mailbox/exception/BlobNotFoundException.java   |  5 +++
 .../org/apache/james/mailbox/model/Attachment.java |  7 ----
 .../java/org/apache/james/mailbox/model/Blob.java  | 38 +++++++++++++++-------
 .../apache/james/mailbox/model/AttachmentTest.java | 16 ---------
 .../org/apache/james/mailbox/model/BlobTest.java   |  6 ++--
 .../james/mailbox/store/StoreBlobManager.java      | 32 +++++++++++++-----
 .../james/mailbox/store/StoreBlobManagerTest.java  |  8 +++--
 7 files changed, 63 insertions(+), 49 deletions(-)

diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/exception/BlobNotFoundException.java b/mailbox/api/src/main/java/org/apache/james/mailbox/exception/BlobNotFoundException.java
index f46a4d6..7066c47 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/exception/BlobNotFoundException.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/exception/BlobNotFoundException.java
@@ -30,6 +30,11 @@ public class BlobNotFoundException extends RuntimeException {
         this.blobId = blobId;
     }
 
+    public BlobNotFoundException(BlobId blobId, Throwable cause) {
+        super("Could not retrieve " + blobId.asString(), cause);
+        this.blobId = blobId;
+    }
+
     public BlobId getBlobId() {
         return blobId;
     }
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
index 47b2f67..6cd578a 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
@@ -116,13 +116,6 @@ public class Attachment {
         return bytes;
     }
 
-    public Blob toBlob() {
-        return Blob.builder()
-            .id(BlobId.fromBytes(bytes))
-            .payload(bytes)
-            .contentType(type)
-            .build();
-    }
 
     @Override
     public boolean equals(Object obj) {
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java
index 694faf9..141f3a8 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Blob.java
@@ -19,21 +19,33 @@
 
 package org.apache.james.mailbox.model;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Objects;
 
+import org.apache.james.mailbox.exception.BlobNotFoundException;
+
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
 
 public class Blob {
 
+    @FunctionalInterface
+    public interface InputStreamSupplier {
+        /**
+         * @return the content of this blob as an inputStream.
+         *
+         * The caller is responsible of closing it.
+         */
+        InputStream load() throws IOException, BlobNotFoundException;
+    }
+
     public static class Builder {
         private BlobId blobId;
-        private byte[] payload;
+        private InputStreamSupplier payload;
         private String contentType;
+        private Long size;
 
         private Builder() {
         }
@@ -43,7 +55,7 @@ public class Blob {
             return this;
         }
 
-        public Builder payload(byte[] payload) {
+        public Builder payload(InputStreamSupplier payload) {
             this.payload = payload;
             return this;
         }
@@ -53,12 +65,18 @@ public class Blob {
             return this;
         }
 
+        public Builder size(long size) {
+            this.size = size;
+            return this;
+        }
+
         public Blob build() {
             Preconditions.checkState(blobId != null, "id can not be empty");
             Preconditions.checkState(payload != null, "payload can not be empty");
             Preconditions.checkState(contentType != null, "contentType can not be empty");
+            Preconditions.checkState(size != null, "size can not be empty");
 
-            return new Blob(blobId, payload, contentType);
+            return new Blob(blobId, payload, contentType, size);
         }
     }
 
@@ -67,28 +85,24 @@ public class Blob {
     }
 
     private final BlobId blobId;
-    private final byte[] payload;
+    private final InputStreamSupplier payload;
     private final String contentType;
     private final long size;
 
     @VisibleForTesting
-    Blob(BlobId blobId, byte[] payload, String contentType) {
+    Blob(BlobId blobId, InputStreamSupplier payload, String contentType, long size) {
         this.blobId = blobId;
         this.payload = payload;
         this.contentType = contentType;
-        this.size = payload.length;
+        this.size = size;
     }
 
     public BlobId getBlobId() {
         return blobId;
     }
 
-    public byte[] getPayload() {
-        return payload;
-    }
-
     public InputStream getStream() throws IOException {
-        return new ByteArrayInputStream(payload);
+        return payload.load();
     }
 
     public long getSize() {
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java
index 69c5636..85beb1a 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java
@@ -136,20 +136,4 @@ class AttachmentTest {
         assertThat(attachment.getSize()).isEqualTo(input.getBytes(CHARSET).length);
     }
 
-    @Test
-    void toBlobShouldGenerateTheAttachmentBlob() {
-        byte[] bytes = "mystream".getBytes(CHARSET);
-        String content = "content";
-        Attachment attachment = Attachment.builder()
-            .bytes(bytes)
-            .type(content)
-            .build();
-        Blob expected = Blob.builder()
-            .id(BlobId.fromBytes(bytes))
-            .contentType(content)
-            .payload(bytes)
-            .build();
-
-        assertThat(attachment.toBlob()).isEqualTo(expected);
-    }
 }
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobTest.java
index b19219d..32e87e0 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobTest.java
@@ -40,7 +40,7 @@ class BlobTest {
             .withIgnoredFields("payload", "size")
             .verify();
     }
-
+/*
     @Test
     void buildShouldConstructValidBlob() {
         assertThat(
@@ -50,7 +50,7 @@ class BlobTest {
                 .payload(PAYLOAD)
                 .build())
             .isEqualTo(
-                new Blob(ID, PAYLOAD, CONTENT_TYPE));
+                new Blob(ID, PAYLOAD, CONTENT_TYPE, length));
     }
 
     @Test
@@ -81,5 +81,5 @@ class BlobTest {
                 .contentType(CONTENT_TYPE)
                 .build())
             .isInstanceOf(IllegalStateException.class);
-    }
+    }*/
 }
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
index 3be2405..34b8f83 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
@@ -19,12 +19,10 @@
 
 package org.apache.james.mailbox.store;
 
-import java.io.InputStream;
 import java.util.Optional;
 
 import javax.inject.Inject;
 
-import org.apache.commons.io.IOUtils;
 import org.apache.james.mailbox.AttachmentManager;
 import org.apache.james.mailbox.BlobManager;
 import org.apache.james.mailbox.MailboxSession;
@@ -32,11 +30,14 @@ import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.BlobNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.Blob;
 import org.apache.james.mailbox.model.BlobId;
+import org.apache.james.mailbox.model.Content;
 import org.apache.james.mailbox.model.FetchGroup;
 import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.MessageResult;
 
 import com.github.fge.lambdas.Throwing;
 
@@ -69,7 +70,21 @@ public class StoreBlobManager implements BlobManager {
     private Optional<Blob> getBlobFromAttachment(BlobId blobId, MailboxSession mailboxSession) throws MailboxException {
         try {
             AttachmentId attachmentId = AttachmentId.from(blobId);
-            return Optional.of(attachmentManager.getAttachment(attachmentId, mailboxSession).toBlob());
+            Attachment attachment = attachmentManager.getAttachment(attachmentId, mailboxSession);
+
+            Blob blob = Blob.builder()
+                .id(blobId)
+                .payload(() -> {
+                    try {
+                        return attachmentManager.loadAttachmentContent(attachmentId, mailboxSession);
+                    } catch (AttachmentNotFoundException e) {
+                        throw new BlobNotFoundException(blobId, e);
+                    }
+                })
+                .size(attachment.getSize())
+                .contentType(attachment.getType())
+                .build();
+            return Optional.of(blob);
         } catch (AttachmentNotFoundException e) {
             return Optional.empty();
         }
@@ -77,12 +92,13 @@ public class StoreBlobManager implements BlobManager {
 
     private Optional<Blob> getBlobFromMessage(BlobId blobId, MailboxSession mailboxSession) {
         return retrieveMessageId(blobId)
-                .flatMap(messageId -> loadMessageAsBlob(messageId, mailboxSession))
+                .flatMap(messageId -> loadMessageAsInputStream(messageId, mailboxSession))
                 .map(Throwing.function(
-                    blob -> Blob.builder()
+                    content -> Blob.builder()
                         .id(blobId)
                         .contentType(MESSAGE_RFC822_CONTENT_TYPE)
-                        .payload(IOUtils.toByteArray(blob))
+                        .size(content.size())
+                        .payload(content::getInputStream)
                         .build()));
     }
 
@@ -94,11 +110,11 @@ public class StoreBlobManager implements BlobManager {
         }
     }
 
-    private Optional<InputStream> loadMessageAsBlob(MessageId messageId, MailboxSession mailboxSession)  {
+    private Optional<Content> loadMessageAsInputStream(MessageId messageId, MailboxSession mailboxSession)  {
         try {
             return messageIdManager.getMessage(messageId, FetchGroup.FULL_CONTENT, mailboxSession)
                 .stream()
-                .map(Throwing.function(message -> message.getFullContent().getInputStream()))
+                .map(Throwing.function(MessageResult::getFullContent))
                 .findFirst();
         } catch (MailboxException e) {
             throw new RuntimeException(e);
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
index dbcaca0..8c86114 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
@@ -72,7 +72,7 @@ class StoreBlobManagerTest {
 
         blobManager = new StoreBlobManager(attachmentManager, messageIdManager, new TestMessageId.Factory());
     }
-
+/*
     @Test
     void retrieveShouldReturnBlobWhenAttachment() throws Exception {
         when(attachmentManager.getAttachment(ATTACHMENT_ID, session))
@@ -90,6 +90,8 @@ class StoreBlobManagerTest {
                 .build());
     }
 
+ */
+
     @Test
     void retrieveShouldThrowWhenNotFound() throws Exception {
         when(attachmentManager.getAttachment(ATTACHMENT_ID, session))
@@ -100,7 +102,7 @@ class StoreBlobManagerTest {
         assertThatThrownBy(() -> blobManager.retrieve(BLOB_ID_ATTACHMENT, session))
             .isInstanceOf(BlobNotFoundException.class);
     }
-
+/*
     @Test
     void retrieveShouldReturnBlobWhenMessage() throws Exception {
         when(attachmentManager.getAttachment(any(), any()))
@@ -120,7 +122,7 @@ class StoreBlobManagerTest {
                 .payload(BYTES)
                 .build());
     }
-
+*/
     @Test
     void retrieveShouldThrowOnMailboxExceptionWhenRetrievingAttachment() throws Exception {
         when(attachmentManager.getAttachment(any(), any()))


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


[james-project] 36/37: JAMES-2997 s/Attachment/AttachmentMetadata + s/MessageAttachment/MessageAttachmentMetadata

Posted by bt...@apache.org.
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 c6f8e0a9ac52a9908c23d530efb71c0d12b622a9
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Sun Apr 19 16:52:12 2020 +0700

    JAMES-2997 s/Attachment/AttachmentMetadata + s/MessageAttachment/MessageAttachmentMetadata
---
 .../james/mailbox/AttachmentContentLoader.java     |  4 +-
 .../apache/james/mailbox/AttachmentManager.java    | 10 ++---
 .../org/apache/james/mailbox/MessageManager.java   |  8 ++--
 .../{Attachment.java => AttachmentMetadata.java}   | 12 +++---
 ...achment.java => MessageAttachmentMetadata.java} | 22 +++++-----
 .../apache/james/mailbox/model/MessageResult.java  |  2 +-
 .../james/mailbox/model/ParsedAttachment.java      | 12 +++---
 ...chmentTest.java => AttachmentMetadataTest.java} | 16 +++----
 ...est.java => MessageAttachmentMetadataTest.java} | 34 +++++++--------
 .../mailbox/cassandra/mail/AttachmentLoader.java   | 12 +++---
 .../cassandra/mail/CassandraAttachmentDAOV2.java   |  8 ++--
 .../cassandra/mail/CassandraAttachmentMapper.java  | 20 ++++-----
 .../cassandra/mail/CassandraMessageDAO.java        |  4 +-
 .../cassandra/mail/MessageRepresentation.java      |  4 +-
 .../cassandra/mail/AttachmentLoaderTest.java       | 32 +++++++-------
 .../mail/CassandraAttachmentDAOV2Test.java         |  4 +-
 .../cassandra/mail/CassandraMessageDAOTest.java    |  8 ++--
 .../MessageAttachmentRepresentationByIdTest.java   |  6 +--
 .../elasticsearch/json/IndexableMessage.java       |  4 +-
 ...asticSearchListeningMessageSearchIndexTest.java |  8 ++--
 .../elasticsearch/json/IndexableMessageTest.java   |  8 ++--
 .../mailbox/jpa/JPAAttachmentContentLoader.java    |  4 +-
 .../model/openjpa/AbstractJPAMailboxMessage.java   |  6 +--
 .../mailbox/jpa/openjpa/OpenJPAMessageFactory.java |  4 +-
 .../lucene/search/LuceneMessageSearchIndex.java    |  4 +-
 .../mailbox/maildir/mail/model/MaildirMessage.java |  6 +--
 .../maildir/MaildirAttachmentContentLoader.java    |  4 +-
 .../inmemory/mail/InMemoryAttachmentMapper.java    | 24 +++++------
 .../james/vault/DeletedMessageConverterTest.java   | 12 +++---
 .../apache/james/mailbox/store/MessageFactory.java |  6 +--
 .../james/mailbox/store/MessageResultImpl.java     |  4 +-
 .../apache/james/mailbox/store/MessageStorer.java  | 12 +++---
 .../mailbox/store/StoreAttachmentManager.java      |  8 ++--
 .../james/mailbox/store/StoreBlobManager.java      |  4 +-
 .../james/mailbox/store/StoreMessageManager.java   |  4 +-
 .../mailbox/store/StoreMessageResultIterator.java  |  4 +-
 .../james/mailbox/store/mail/AttachmentMapper.java | 12 +++---
 .../store/mail/model/DelegatingMailboxMessage.java |  4 +-
 .../james/mailbox/store/mail/model/Message.java    |  4 +-
 .../mail/model/impl/SimpleMailboxMessage.java      | 12 +++---
 .../store/mail/model/impl/SimpleMessage.java       |  8 ++--
 .../mailbox/store/search/MessageSearches.java      | 16 +++----
 .../AbstractMailboxManagerAttachmentTest.java      | 16 +++----
 .../apache/james/mailbox/store/MessageBuilder.java |  4 +-
 .../mailbox/store/StoreAttachmentManagerTest.java  |  4 +-
 .../james/mailbox/store/StoreBlobManagerTest.java  |  4 +-
 .../store/mail/model/AttachmentMapperTest.java     | 24 +++++------
 .../model/MessageWithAttachmentMapperTest.java     | 10 ++---
 .../mail/model/impl/SimpleMailboxMessageTest.java  |  8 ++--
 .../apache/james/jmap/draft/MessageIdProbe.java    |  4 +-
 .../MessageFastViewPrecomputedProperties.java      |  4 +-
 .../methods/integration/SetMessagesMethodTest.java | 49 +++++++++++-----------
 .../jmap/draft/methods/MIMEMessageConverter.java   | 34 +++++++--------
 .../james/jmap/draft/methods/MessageAppender.java  | 12 +++---
 .../model/message/view/MessageFullViewFactory.java | 16 +++----
 .../draft/methods/MIMEMessageConverterTest.java    | 41 +++++++++---------
 .../message/view/MessageFullViewFactoryTest.java   |  7 ++--
 57 files changed, 320 insertions(+), 317 deletions(-)

diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentContentLoader.java b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentContentLoader.java
index 1c084d5..9536c72 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentContentLoader.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentContentLoader.java
@@ -23,10 +23,10 @@ import java.io.IOException;
 import java.io.InputStream;
 
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
-import org.apache.james.mailbox.model.Attachment;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 
 public interface AttachmentContentLoader {
 
-    InputStream load(Attachment attachment, MailboxSession mailboxSession) throws IOException, AttachmentNotFoundException;
+    InputStream load(AttachmentMetadata attachment, MailboxSession mailboxSession) throws IOException, AttachmentNotFoundException;
 
 }
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
index 99722a1..468e037 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
@@ -25,24 +25,24 @@ import java.util.List;
 
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 import org.reactivestreams.Publisher;
 
 public interface AttachmentManager extends AttachmentContentLoader {
 
     boolean exists(AttachmentId attachmentId, MailboxSession session) throws MailboxException;
 
-    Attachment getAttachment(AttachmentId attachmentId, MailboxSession mailboxSession) throws MailboxException, AttachmentNotFoundException;
+    AttachmentMetadata getAttachment(AttachmentId attachmentId, MailboxSession mailboxSession) throws MailboxException, AttachmentNotFoundException;
 
-    List<Attachment> getAttachments(List<AttachmentId> attachmentIds, MailboxSession mailboxSession) throws MailboxException;
+    List<AttachmentMetadata> getAttachments(List<AttachmentId> attachmentIds, MailboxSession mailboxSession) throws MailboxException;
 
-    Publisher<Attachment> storeAttachment(String contentType, InputStream attachmentContent, MailboxSession mailboxSession);
+    Publisher<AttachmentMetadata> storeAttachment(String contentType, InputStream attachmentContent, MailboxSession mailboxSession);
 
     InputStream loadAttachmentContent(AttachmentId attachmentId, MailboxSession mailboxSession) throws AttachmentNotFoundException, IOException;
 
     @Override
-    default InputStream load(Attachment attachment, MailboxSession mailboxSession) throws IOException, AttachmentNotFoundException {
+    default InputStream load(AttachmentMetadata attachment, MailboxSession mailboxSession) throws IOException, AttachmentNotFoundException {
         return loadAttachmentContent(attachment.getAttachmentId(), mailboxSession);
     }
 
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java
index f9c2065..2f675c1 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java
@@ -45,7 +45,7 @@ import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxCounters;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.MessageAttachment;
+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.model.MessageResultIterator;
@@ -144,9 +144,9 @@ public interface MessageManager {
 
     class AppendResult {
         private final ComposedMessageId id;
-        private final Optional<List<MessageAttachment>> messageAttachments;
+        private final Optional<List<MessageAttachmentMetadata>> messageAttachments;
 
-        public AppendResult(ComposedMessageId id, Optional<List<MessageAttachment>> messageAttachments) {
+        public AppendResult(ComposedMessageId id, Optional<List<MessageAttachmentMetadata>> messageAttachments) {
             this.id = id;
             this.messageAttachments = messageAttachments;
         }
@@ -155,7 +155,7 @@ public interface MessageManager {
             return id;
         }
 
-        public List<MessageAttachment> getMessageAttachments() {
+        public List<MessageAttachmentMetadata> getMessageAttachments() {
             Preconditions.checkState(messageAttachments.isPresent(), "'attachment storage' not supported by the implementation");
             return messageAttachments.get();
         }
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/AttachmentMetadata.java
similarity index 90%
rename from mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
rename to mailbox/api/src/main/java/org/apache/james/mailbox/model/AttachmentMetadata.java
index 6e36f8c..9676f76 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/AttachmentMetadata.java
@@ -24,7 +24,7 @@ import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 
-public class Attachment {
+public class AttachmentMetadata {
     public static class Builder {
         private AttachmentId attachmentId;
         private Long size;
@@ -48,12 +48,12 @@ public class Attachment {
             return this;
         }
 
-        public Attachment build() {
+        public AttachmentMetadata build() {
             Preconditions.checkState(type != null, "'type' is mandatory");
             Preconditions.checkState(size != null, "'size' is mandatory");
             Preconditions.checkState(attachmentId != null, "'attachmentId' is mandatory");
 
-            return new Attachment(attachmentId, type, size);
+            return new AttachmentMetadata(attachmentId, type, size);
         }
     }
 
@@ -65,7 +65,7 @@ public class Attachment {
     private final String type;
     private final long size;
 
-    private Attachment(AttachmentId attachmentId, String type, long size) {
+    private AttachmentMetadata(AttachmentId attachmentId, String type, long size) {
         this.attachmentId = attachmentId;
         this.type = type;
         this.size = size;
@@ -86,8 +86,8 @@ public class Attachment {
 
     @Override
     public boolean equals(Object obj) {
-        if (obj instanceof Attachment) {
-            Attachment other = (Attachment) obj;
+        if (obj instanceof AttachmentMetadata) {
+            AttachmentMetadata other = (AttachmentMetadata) obj;
             return Objects.equal(attachmentId, other.attachmentId)
                 && Objects.equal(type, other.type)
                 && Objects.equal(size, other.size);
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageAttachment.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageAttachmentMetadata.java
similarity index 85%
rename from mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageAttachment.java
rename to mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageAttachmentMetadata.java
index 8e6b407..1093bd0 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageAttachment.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageAttachmentMetadata.java
@@ -26,7 +26,7 @@ import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
 
-public class MessageAttachment {
+public class MessageAttachmentMetadata {
 
     public static Builder builder() {
         return new Builder();
@@ -34,7 +34,7 @@ public class MessageAttachment {
 
     public static class Builder {
 
-        private Attachment attachment;
+        private AttachmentMetadata attachment;
         private Optional<String> name;
         private Optional<Cid> cid;
         private Optional<Boolean> isInline = Optional.empty();
@@ -44,7 +44,7 @@ public class MessageAttachment {
             cid = Optional.empty();
         }
 
-        public Builder attachment(Attachment attachment) {
+        public Builder attachment(AttachmentMetadata attachment) {
             Preconditions.checkArgument(attachment != null);
             this.attachment = attachment;
             return this;
@@ -77,30 +77,30 @@ public class MessageAttachment {
             return this;
         }
 
-        public MessageAttachment build() {
+        public MessageAttachmentMetadata build() {
             Preconditions.checkState(attachment != null, "'attachment' is mandatory");
-            return new MessageAttachment(attachment, name, cid, isInline.orElse(false));
+            return new MessageAttachmentMetadata(attachment, name, cid, isInline.orElse(false));
         }
     }
 
-    public static boolean hasNonInlinedAttachment(List<MessageAttachment> attachments) {
+    public static boolean hasNonInlinedAttachment(List<MessageAttachmentMetadata> attachments) {
         return attachments.stream()
             .anyMatch(messageAttachment -> !messageAttachment.isInlinedWithCid());
     }
 
-    private final Attachment attachment;
+    private final AttachmentMetadata attachment;
     private final Optional<String> name;
     private final Optional<Cid> cid;
     private final boolean isInline;
 
-    public MessageAttachment(Attachment attachment, Optional<String> name, Optional<Cid> cid, boolean isInline) {
+    public MessageAttachmentMetadata(AttachmentMetadata attachment, Optional<String> name, Optional<Cid> cid, boolean isInline) {
         this.attachment = attachment;
         this.name = name;
         this.cid = cid;
         this.isInline = isInline;
     }
 
-    public Attachment getAttachment() {
+    public AttachmentMetadata getAttachment() {
         return attachment;
     }
 
@@ -126,8 +126,8 @@ public class MessageAttachment {
 
     @Override
     public boolean equals(Object obj) {
-        if (obj instanceof MessageAttachment) {
-            MessageAttachment other = (MessageAttachment) obj;
+        if (obj instanceof MessageAttachmentMetadata) {
+            MessageAttachmentMetadata other = (MessageAttachmentMetadata) obj;
             return Objects.equal(attachment, other.attachment)
                 && Objects.equal(name, other.name)
                 && Objects.equal(cid, other.cid)
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageResult.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageResult.java
index b21f5ce..0dabf05 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageResult.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageResult.java
@@ -161,7 +161,7 @@ public interface MessageResult extends Comparable<MessageResult> {
      *
      * These attachments will be loaded only for Full
      */
-    List<MessageAttachment> getLoadedAttachments() throws MailboxException;
+    List<MessageAttachmentMetadata> getLoadedAttachments() throws MailboxException;
 
     /**
      * Indicates if the message have attachments, regardless of loaded attachments.
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java
index 7c269e5..c615473 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java
@@ -108,9 +108,9 @@ public class ParsedAttachment {
         return isInline;
     }
 
-    public MessageAttachment asMessageAttachment(AttachmentId attachmentId, long size) {
-        return MessageAttachment.builder()
-            .attachment(Attachment.builder()
+    public MessageAttachmentMetadata asMessageAttachment(AttachmentId attachmentId, long size) {
+        return MessageAttachmentMetadata.builder()
+            .attachment(AttachmentMetadata.builder()
                 .attachmentId(attachmentId)
                 .type(contentType)
                 .size(size)
@@ -121,9 +121,9 @@ public class ParsedAttachment {
             .build();
     }
 
-    public MessageAttachment asMessageAttachment(AttachmentId attachmentId) throws IOException {
-        return MessageAttachment.builder()
-            .attachment(Attachment.builder()
+    public MessageAttachmentMetadata asMessageAttachment(AttachmentId attachmentId) throws IOException {
+        return MessageAttachmentMetadata.builder()
+            .attachment(AttachmentMetadata.builder()
                 .attachmentId(attachmentId)
                 .type(contentType)
                 .size(content.length)
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentMetadataTest.java
similarity index 84%
rename from mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java
rename to mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentMetadataTest.java
index e99cd7e..1c0eaba 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentMetadataTest.java
@@ -24,38 +24,38 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import org.junit.jupiter.api.Test;
 
-class AttachmentTest {
+class AttachmentMetadataTest {
     @Test
     void builderShouldThrowWhenAttachmentIdIsNull() {
-        assertThatThrownBy(() -> Attachment.builder()
+        assertThatThrownBy(() -> AttachmentMetadata.builder()
                 .attachmentId(null))
             .isInstanceOf(IllegalArgumentException.class);
     }
 
     @Test
     void builderShouldThrowWhenTypeIsNull() {
-        assertThatThrownBy(() -> Attachment.builder()
+        assertThatThrownBy(() -> AttachmentMetadata.builder()
                 .type(null))
             .isInstanceOf(IllegalArgumentException.class);
     }
 
     @Test
     void builderShouldThrowWhenTypeIsEmpty() {
-        assertThatThrownBy(() -> Attachment.builder()
+        assertThatThrownBy(() -> AttachmentMetadata.builder()
                 .type(""))
             .isInstanceOf(IllegalArgumentException.class);
     }
 
     @Test
     void buildShouldThrowWhenAttachmentIdIsNotProvided() {
-        assertThatThrownBy(() -> Attachment.builder()
+        assertThatThrownBy(() -> AttachmentMetadata.builder()
                 .build())
             .isInstanceOf(IllegalStateException.class);
     }
 
     @Test
     void buildShouldThrowWhenSizeIsNotProvided() {
-        assertThatThrownBy(() -> Attachment.builder()
+        assertThatThrownBy(() -> AttachmentMetadata.builder()
                 .attachmentId(AttachmentId.random())
                 .type("TYPE")
                 .build())
@@ -64,7 +64,7 @@ class AttachmentTest {
 
     @Test
     void buildShouldThrowWhenTypeIsNotProvided() {
-        assertThatThrownBy(() -> Attachment.builder()
+        assertThatThrownBy(() -> AttachmentMetadata.builder()
                 .attachmentId(AttachmentId.random())
                 .size(36)
                 .build())
@@ -73,7 +73,7 @@ class AttachmentTest {
 
     @Test
     void sizeShouldThrowOnNegativeValue() {
-        assertThatThrownBy(() -> Attachment.builder()
+        assertThatThrownBy(() -> AttachmentMetadata.builder()
                 .attachmentId(AttachmentId.random())
                 .size(-3))
             .isInstanceOf(IllegalArgumentException.class);
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageAttachmentTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageAttachmentMetadataTest.java
similarity index 73%
rename from mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageAttachmentTest.java
rename to mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageAttachmentMetadataTest.java
index 638985a..5b49895 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageAttachmentTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageAttachmentMetadataTest.java
@@ -26,32 +26,32 @@ import java.util.Optional;
 
 import org.junit.jupiter.api.Test;
 
-class MessageAttachmentTest {
+class MessageAttachmentMetadataTest {
 
     @Test
     void buildShouldThrowWhenAttachmentIsNotGiven() {
-        assertThatThrownBy(() -> MessageAttachment.builder()
+        assertThatThrownBy(() -> MessageAttachmentMetadata.builder()
                 .build())
             .isInstanceOf(IllegalStateException.class);
     }
 
     @Test
     void builderShouldThrowWhenAttachmentIsNull() {
-        assertThatThrownBy(() -> MessageAttachment.builder()
+        assertThatThrownBy(() -> MessageAttachmentMetadata.builder()
                 .attachment(null))
             .isInstanceOf(IllegalArgumentException.class);
     }
 
     @Test
     void buildShouldWorkWhenMandatoryAttributesAreGiven() {
-        Attachment attachment = Attachment.builder()
+        AttachmentMetadata attachment = AttachmentMetadata.builder()
             .attachmentId(AttachmentId.from("1"))
             .size(36)
             .type("type")
             .build();
-        MessageAttachment expectedMessageAttachment = new MessageAttachment(attachment, Optional.empty(), Optional.empty(), false);
+        MessageAttachmentMetadata expectedMessageAttachment = new MessageAttachmentMetadata(attachment, Optional.empty(), Optional.empty(), false);
 
-        MessageAttachment messageAttachment = MessageAttachment.builder()
+        MessageAttachmentMetadata messageAttachment = MessageAttachmentMetadata.builder()
             .attachment(attachment)
             .build();
 
@@ -60,13 +60,13 @@ class MessageAttachmentTest {
 
     @Test
     void buildShouldAcceptIsInlineAndNoCid() {
-        Attachment attachment = Attachment.builder()
+        AttachmentMetadata attachment = AttachmentMetadata.builder()
             .attachmentId(AttachmentId.from("1"))
             .size(36)
             .type("type")
             .build();
 
-        MessageAttachment messageAttachment = MessageAttachment.builder()
+        MessageAttachmentMetadata messageAttachment = MessageAttachmentMetadata.builder()
             .attachment(attachment)
             .isInline(true)
             .build();
@@ -76,14 +76,14 @@ class MessageAttachmentTest {
 
     @Test
     void buildShouldSetAttributesWhenAllAreGiven() {
-        Attachment attachment = Attachment.builder()
+        AttachmentMetadata attachment = AttachmentMetadata.builder()
             .attachmentId(AttachmentId.from("1"))
             .size(36)
             .type("type")
             .build();
-        MessageAttachment expectedMessageAttachment = new MessageAttachment(attachment, Optional.of("name"), Optional.of(Cid.from("cid")), true);
+        MessageAttachmentMetadata expectedMessageAttachment = new MessageAttachmentMetadata(attachment, Optional.of("name"), Optional.of(Cid.from("cid")), true);
 
-        MessageAttachment messageAttachment = MessageAttachment.builder()
+        MessageAttachmentMetadata messageAttachment = MessageAttachmentMetadata.builder()
             .attachment(attachment)
             .name("name")
             .cid(Cid.from("cid"))
@@ -95,13 +95,13 @@ class MessageAttachmentTest {
 
     @Test
     void isInlinedWithCidShouldReturnTrueWhenIsInlineAndHasCid() throws Exception {
-        Attachment attachment = Attachment.builder()
+        AttachmentMetadata attachment = AttachmentMetadata.builder()
             .attachmentId(AttachmentId.from("1"))
             .size(36)
             .type("type")
             .build();
 
-        MessageAttachment messageAttachment = MessageAttachment.builder()
+        MessageAttachmentMetadata messageAttachment = MessageAttachmentMetadata.builder()
             .attachment(attachment)
             .name("name")
             .cid(Cid.from("cid"))
@@ -113,13 +113,13 @@ class MessageAttachmentTest {
 
     @Test
     void isInlinedWithCidShouldReturnFalseWhenIsNotInline() throws Exception {
-        Attachment attachment = Attachment.builder()
+        AttachmentMetadata attachment = AttachmentMetadata.builder()
             .attachmentId(AttachmentId.from("1"))
             .size(36)
             .type("type")
             .build();
 
-        MessageAttachment messageAttachment = MessageAttachment.builder()
+        MessageAttachmentMetadata messageAttachment = MessageAttachmentMetadata.builder()
             .attachment(attachment)
             .name("name")
             .cid(Cid.from("cid"))
@@ -131,13 +131,13 @@ class MessageAttachmentTest {
 
     @Test
     void isInlinedWithCidShouldReturnFalseWhenIsInlineButNoCid() throws Exception {
-        Attachment attachment = Attachment.builder()
+        AttachmentMetadata attachment = AttachmentMetadata.builder()
             .attachmentId(AttachmentId.from("1"))
             .size(36)
             .type("type")
             .build();
 
-        MessageAttachment messageAttachment = MessageAttachment.builder()
+        MessageAttachmentMetadata messageAttachment = MessageAttachmentMetadata.builder()
             .attachment(attachment)
             .name("name")
             .isInline(true)
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoader.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoader.java
index c458fae..a765dcd 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoader.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoader.java
@@ -21,8 +21,8 @@ package org.apache.james.mailbox.cassandra.mail;
 import java.util.List;
 import java.util.stream.Stream;
 
-import org.apache.james.mailbox.model.Attachment;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.AttachmentMetadata;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 
@@ -46,7 +46,7 @@ public class AttachmentLoader {
             .map(messageRepresentation::toMailboxMessage);
     }
 
-    private Mono<List<MessageAttachment>> loadAttachments(Stream<MessageAttachmentRepresentation> messageAttachmentRepresentations, MessageMapper.FetchType fetchType) {
+    private Mono<List<MessageAttachmentMetadata>> loadAttachments(Stream<MessageAttachmentRepresentation> messageAttachmentRepresentations, MessageMapper.FetchType fetchType) {
         if (fetchType == MessageMapper.FetchType.Body || fetchType == MessageMapper.FetchType.Full) {
             return getAttachments(messageAttachmentRepresentations.collect(Guavate.toImmutableList()));
         } else {
@@ -55,7 +55,7 @@ public class AttachmentLoader {
     }
 
     @VisibleForTesting
-    Mono<List<MessageAttachment>> getAttachments(List<MessageAttachmentRepresentation> attachmentRepresentations) {
+    Mono<List<MessageAttachmentMetadata>> getAttachments(List<MessageAttachmentRepresentation> attachmentRepresentations) {
         return Flux.fromIterable(attachmentRepresentations)
                 .flatMapSequential(attachmentRepresentation ->
                         attachmentMapper.getAttachmentsAsMono(attachmentRepresentation.getAttachmentId())
@@ -63,8 +63,8 @@ public class AttachmentLoader {
                 .collect(Guavate.toImmutableList());
     }
 
-    private MessageAttachment constructMessageAttachment(Attachment attachment, MessageAttachmentRepresentation messageAttachmentRepresentation) {
-        return MessageAttachment.builder()
+    private MessageAttachmentMetadata constructMessageAttachment(AttachmentMetadata attachment, MessageAttachmentRepresentation messageAttachmentRepresentation) {
+        return MessageAttachmentMetadata.builder()
                 .attachment(attachment)
                 .name(messageAttachmentRepresentation.getName().orElse(null))
                 .cid(messageAttachmentRepresentation.getCid())
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
index 226b40a..5d1cb80 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
@@ -38,8 +38,8 @@ import javax.inject.Inject;
 
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
 import org.apache.james.blob.api.BlobId;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 
 import com.datastax.driver.core.PreparedStatement;
 import com.datastax.driver.core.Row;
@@ -78,8 +78,8 @@ public class CassandraAttachmentDAOV2 {
             return size;
         }
 
-        public Attachment toAttachment() {
-            return Attachment.builder()
+        public AttachmentMetadata toAttachment() {
+            return AttachmentMetadata.builder()
                 .attachmentId(attachmentId)
                 .type(type)
                 .size(size)
@@ -105,7 +105,7 @@ public class CassandraAttachmentDAOV2 {
         }
     }
 
-    public static DAOAttachment from(Attachment attachment, BlobId blobId) {
+    public static DAOAttachment from(AttachmentMetadata attachment, BlobId blobId) {
         return new DAOAttachment(
             attachment.getAttachmentId(),
             blobId,
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
index 12a0d4c..8d84078 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
@@ -33,9 +33,9 @@ import org.apache.james.core.Username;
 import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAOV2.DAOAttachment;
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.AttachmentMetadata;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
@@ -76,7 +76,7 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
     }
 
     @Override
-    public Attachment getAttachment(AttachmentId attachmentId) throws AttachmentNotFoundException {
+    public AttachmentMetadata getAttachment(AttachmentId attachmentId) throws AttachmentNotFoundException {
         Preconditions.checkArgument(attachmentId != null);
         return getAttachmentInternal(attachmentId)
             .blockOptional()
@@ -84,7 +84,7 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
     }
 
     @Override
-    public List<Attachment> getAttachments(Collection<AttachmentId> attachmentIds) {
+    public List<AttachmentMetadata> getAttachments(Collection<AttachmentId> attachmentIds) {
         Preconditions.checkArgument(attachmentIds != null);
         return Flux.fromIterable(attachmentIds)
             .flatMap(this::getAttachmentsAsMono)
@@ -100,25 +100,25 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
             .orElseThrow(() -> new AttachmentNotFoundException(attachmentId.toString()));
     }
 
-    public Mono<Attachment> getAttachmentsAsMono(AttachmentId attachmentId) {
+    public Mono<AttachmentMetadata> getAttachmentsAsMono(AttachmentId attachmentId) {
         return getAttachmentInternal(attachmentId)
             .switchIfEmpty(ReactorUtils.executeAndEmpty(() -> logNotFound((attachmentId))));
     }
 
-    private Mono<Attachment> getAttachmentInternal(AttachmentId id) {
+    private Mono<AttachmentMetadata> getAttachmentInternal(AttachmentId id) {
         return attachmentDAOV2.getAttachment(id)
             .map(DAOAttachment::toAttachment);
     }
 
     @Override
-    public Mono<Attachment> storeAttachmentForOwner(String contentType, InputStream inputStream, Username owner) {
+    public Mono<AttachmentMetadata> storeAttachmentForOwner(String contentType, InputStream inputStream, Username owner) {
         CurrentPositionInputStream currentPositionInputStream = new CurrentPositionInputStream(inputStream);
         AttachmentId attachmentId = AttachmentId.random();
         return ownerDAO.addOwner(attachmentId, owner)
             .then(Mono.from(blobStore.save(blobStore.getDefaultBucketName(), currentPositionInputStream, LOW_COST)))
                 .map(blobId -> new DAOAttachment(attachmentId, blobId, contentType, currentPositionInputStream.getPosition()))
             .flatMap(attachmentDAOV2::storeAttachment)
-            .then(Mono.defer(() -> Mono.just(Attachment.builder()
+            .then(Mono.defer(() -> Mono.just(AttachmentMetadata.builder()
                 .attachmentId(attachmentId)
                 .type(contentType)
                 .size(currentPositionInputStream.getPosition())
@@ -126,7 +126,7 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
     }
 
     @Override
-    public List<MessageAttachment> storeAttachmentsForMessage(Collection<ParsedAttachment> parsedAttachments, MessageId ownerMessageId) throws MailboxException {
+    public List<MessageAttachmentMetadata> storeAttachmentsForMessage(Collection<ParsedAttachment> parsedAttachments, MessageId ownerMessageId) throws MailboxException {
         return Flux.fromIterable(parsedAttachments)
             .concatMap(attachment -> storeAttachmentAsync(attachment, ownerMessageId))
             .collectList()
@@ -145,7 +145,7 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
         return ownerDAO.retrieveOwners(attachmentId).collect(Guavate.toImmutableList()).block();
     }
 
-    private Mono<MessageAttachment> storeAttachmentAsync(ParsedAttachment parsedAttachment, MessageId ownerMessageId) {
+    private Mono<MessageAttachmentMetadata> storeAttachmentAsync(ParsedAttachment parsedAttachment, MessageId ownerMessageId) {
         AttachmentId attachmentId = AttachmentId.random();
         byte[] content = parsedAttachment.getContent();
         return Mono.from(blobStore.save(blobStore.getDefaultBucketName(), content, LOW_COST))
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java
index 63b617a..07dfbd1 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java
@@ -66,7 +66,7 @@ import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.Cid;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.store.mail.MessageMapper.FetchType;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.Property;
@@ -204,7 +204,7 @@ public class CassandraMessageDAO {
             .collect(Guavate.toImmutableList());
     }
 
-    private UDTValue toUDT(MessageAttachment messageAttachment) {
+    private UDTValue toUDT(MessageAttachmentMetadata messageAttachment) {
         UDTValue result = typesProvider.getDefinedUserType(ATTACHMENTS)
             .newValue()
             .setString(Attachments.ID, messageAttachment.getAttachmentId().getId())
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageRepresentation.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageRepresentation.java
index 728f0d2..5416730 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageRepresentation.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageRepresentation.java
@@ -30,7 +30,7 @@ import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
 import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
 import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
@@ -66,7 +66,7 @@ public class MessageRepresentation {
         this.attachments = attachments;
     }
 
-    public SimpleMailboxMessage toMailboxMessage(List<MessageAttachment> attachments) {
+    public SimpleMailboxMessage toMailboxMessage(List<MessageAttachmentMetadata> attachments) {
         return SimpleMailboxMessage.builder()
             .messageId(messageId)
             .mailboxId(mailboxId)
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoaderTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoaderTest.java
index cc23204..39eddb2 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoaderTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoaderTest.java
@@ -25,10 +25,10 @@ import static org.mockito.Mockito.when;
 import java.util.Collection;
 import java.util.Optional;
 
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 import org.apache.james.mailbox.model.Cid;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -51,7 +51,7 @@ class AttachmentLoaderTest {
     void getAttachmentsShouldWorkWithDuplicatedAttachments() {
         AttachmentId attachmentId = AttachmentId.from("1");
 
-        Attachment attachment = Attachment.builder()
+        AttachmentMetadata attachment = AttachmentMetadata.builder()
             .attachmentId(attachmentId)
             .size(11)
             .type("type")
@@ -65,10 +65,10 @@ class AttachmentLoaderTest {
         boolean isInlined = false;
         MessageAttachmentRepresentation attachmentRepresentation = new MessageAttachmentRepresentation(attachmentId, name, cid, isInlined);
 
-        Collection<MessageAttachment> attachments = testee.getAttachments(ImmutableList.of(attachmentRepresentation, attachmentRepresentation))
+        Collection<MessageAttachmentMetadata> attachments = testee.getAttachments(ImmutableList.of(attachmentRepresentation, attachmentRepresentation))
             .block();
 
-        MessageAttachment expectedAttachment = new MessageAttachment(attachment, name, cid, isInlined);
+        MessageAttachmentMetadata expectedAttachment = new MessageAttachmentMetadata(attachment, name, cid, isInlined);
         assertThat(attachments).hasSize(2)
             .containsOnly(expectedAttachment, expectedAttachment);
     }
@@ -77,7 +77,7 @@ class AttachmentLoaderTest {
     void getAttachmentsShouldWorkWithDuplicatedIds() {
         AttachmentId attachmentId = AttachmentId.from("1");
 
-        Attachment attachment = Attachment.builder()
+        AttachmentMetadata attachment = AttachmentMetadata.builder()
             .attachmentId(attachmentId)
             .size(11)
             .type("type")
@@ -93,12 +93,12 @@ class AttachmentLoaderTest {
         MessageAttachmentRepresentation attachmentRepresentation1 = new MessageAttachmentRepresentation(attachmentId, name1, cid, isInlined);
         MessageAttachmentRepresentation attachmentRepresentation2 = new MessageAttachmentRepresentation(attachmentId, name2, cid, isInlined);
 
-        Collection<MessageAttachment> attachments = testee.getAttachments(ImmutableList.of(attachmentRepresentation1, attachmentRepresentation2))
+        Collection<MessageAttachmentMetadata> attachments = testee.getAttachments(ImmutableList.of(attachmentRepresentation1, attachmentRepresentation2))
             .block();
 
         assertThat(attachments).hasSize(2)
-            .containsOnly(new MessageAttachment(attachment, name1, cid, isInlined),
-                new MessageAttachment(attachment, name2, cid, isInlined));
+            .containsOnly(new MessageAttachmentMetadata(attachment, name1, cid, isInlined),
+                new MessageAttachmentMetadata(attachment, name2, cid, isInlined));
     }
 
     @Test
@@ -106,12 +106,12 @@ class AttachmentLoaderTest {
         AttachmentId attachmentId1 = AttachmentId.from("1");
         AttachmentId attachmentId2 = AttachmentId.from("2");
 
-        Attachment attachment1 = Attachment.builder()
+        AttachmentMetadata attachment1 = AttachmentMetadata.builder()
             .attachmentId(attachmentId1)
             .size(12)
             .type("type")
             .build();
-        Attachment attachment2 = Attachment.builder()
+        AttachmentMetadata attachment2 = AttachmentMetadata.builder()
             .attachmentId(attachmentId2)
             .size(13)
             .type("type")
@@ -129,19 +129,19 @@ class AttachmentLoaderTest {
         MessageAttachmentRepresentation attachmentRepresentation1 = new MessageAttachmentRepresentation(attachmentId1, name1, cid, isInlined);
         MessageAttachmentRepresentation attachmentRepresentation2 = new MessageAttachmentRepresentation(attachmentId2, name2, cid, isInlined);
 
-        Collection<MessageAttachment> attachments = testee.getAttachments(ImmutableList.of(attachmentRepresentation1, attachmentRepresentation2))
+        Collection<MessageAttachmentMetadata> attachments = testee.getAttachments(ImmutableList.of(attachmentRepresentation1, attachmentRepresentation2))
             .block();
 
         assertThat(attachments).hasSize(2)
-            .containsOnly(new MessageAttachment(attachment1, name1, cid, isInlined),
-                new MessageAttachment(attachment2, name2, cid, isInlined));
+            .containsOnly(new MessageAttachmentMetadata(attachment1, name1, cid, isInlined),
+                new MessageAttachmentMetadata(attachment2, name2, cid, isInlined));
     }
 
     @Test
     void getAttachmentsShouldReturnEmptyByDefault() {
         AttachmentId attachmentId = AttachmentId.from("1");
 
-        Attachment attachment = Attachment.builder()
+        AttachmentMetadata attachment = AttachmentMetadata.builder()
             .attachmentId(attachmentId)
             .size(11)
             .type("type")
@@ -150,7 +150,7 @@ class AttachmentLoaderTest {
         when(attachmentMapper.getAttachmentsAsMono(attachmentId))
                 .thenReturn(Mono.just(attachment));
 
-        Collection<MessageAttachment> attachments = testee.getAttachments(ImmutableList.of())
+        Collection<MessageAttachmentMetadata> attachments = testee.getAttachments(ImmutableList.of())
             .block();
 
         assertThat(attachments).isEmpty();
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2Test.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2Test.java
index e9cbec6..23032e1 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2Test.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2Test.java
@@ -29,8 +29,8 @@ import org.apache.james.blob.api.BlobId;
 import org.apache.james.blob.api.HashBlobId;
 import org.apache.james.mailbox.cassandra.mail.CassandraAttachmentDAOV2.DAOAttachment;
 import org.apache.james.mailbox.cassandra.modules.CassandraAttachmentModule;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
@@ -58,7 +58,7 @@ class CassandraAttachmentDAOV2Test {
 
     @Test
     void getAttachmentShouldReturnAttachmentWhenStored() {
-        Attachment attachment = Attachment.builder()
+        AttachmentMetadata attachment = AttachmentMetadata.builder()
             .attachmentId(ATTACHMENT_ID)
             .type("application/json")
             .size(4)
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAOTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAOTest.java
index e1ca868..7ee6030 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAOTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAOTest.java
@@ -42,9 +42,11 @@ import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.cassandra.modules.CassandraMessageModule;
+import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
@@ -63,7 +65,7 @@ class CassandraMessageDAOTest {
     private static final CassandraId MAILBOX_ID = CassandraId.timeBased();
     private static final String CONTENT = "Subject: Test7 \n\nBody7\n.\n";
     private static final MessageUid messageUid = MessageUid.of(1);
-    private static final List<MessageAttachment> NO_ATTACHMENT = ImmutableList.of();
+    private static final List<MessageAttachmentMetadata> NO_ATTACHMENT = ImmutableList.of();
 
     public static final CassandraModule MODULES = CassandraModule.aggregateModules(
             CassandraMessageModule.MODULE,
@@ -167,7 +169,7 @@ class CassandraMessageDAOTest {
             .isEqualTo(CONTENT.substring(0, BODY_START));
     }
 
-    private SimpleMailboxMessage createMessage(MessageId messageId, String content, int bodyStart, PropertyBuilder propertyBuilder, Collection<MessageAttachment> attachments) {
+    private SimpleMailboxMessage createMessage(MessageId messageId, String content, int bodyStart, PropertyBuilder propertyBuilder, Collection<MessageAttachmentMetadata> attachments) {
         return SimpleMailboxMessage.builder()
             .messageId(messageId)
             .mailboxId(MAILBOX_ID)
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/MessageAttachmentRepresentationByIdTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/MessageAttachmentRepresentationByIdTest.java
index 84d000d..254fc84 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/MessageAttachmentRepresentationByIdTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/MessageAttachmentRepresentationByIdTest.java
@@ -26,7 +26,7 @@ import java.util.Optional;
 
 import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.Cid;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.junit.jupiter.api.Test;
 
 
@@ -34,13 +34,13 @@ class MessageAttachmentRepresentationByIdTest {
 
     @Test
     void buildShouldThrowWhenAttachmentIsNotGiven() {
-        assertThatThrownBy(() -> MessageAttachment.builder().build())
+        assertThatThrownBy(() -> MessageAttachmentMetadata.builder().build())
             .isInstanceOf(IllegalStateException.class);
     }
 
     @Test
     void builderShouldThrowWhenAttachmentIsNull() {
-        assertThatThrownBy(() -> MessageAttachment.builder().attachment(null))
+        assertThatThrownBy(() -> MessageAttachmentMetadata.builder().attachment(null))
             .isInstanceOf(IllegalArgumentException.class);
     }
 
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
index 1248996..62df164 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
+++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
@@ -32,7 +32,7 @@ import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.elasticsearch.IndexAttachments;
 import org.apache.james.mailbox.elasticsearch.query.DateResolutionFormater;
 import org.apache.james.mailbox.extractor.TextExtractor;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.search.SearchUtil;
 import org.apache.james.mime4j.MimeException;
@@ -104,7 +104,7 @@ public class IndexableMessage {
             Optional<String> bodyText = parsingResult.locateFirstTextBody();
             Optional<String> bodyHtml = parsingResult.locateFirstHtmlBody();
 
-            boolean hasAttachment = MessageAttachment.hasNonInlinedAttachment(message.getAttachments());
+            boolean hasAttachment = MessageAttachmentMetadata.hasNonInlinedAttachment(message.getAttachments());
             List<MimePart> attachments = setFlattenedAttachments(parsingResult, indexAttachments);
 
             HeaderCollection headerCollection = parsingResult.getHeaderCollection();
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
index d01eb29..c04d02f 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
@@ -55,11 +55,11 @@ import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
 import org.apache.james.mailbox.manager.ManagerTestProvisionner;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.model.TestId;
@@ -113,8 +113,8 @@ class ElasticSearchListeningMessageSearchIndexTest {
         .uid(MESSAGE_UID_2)
         .build();
 
-    static final MessageAttachment MESSAGE_ATTACHMENT = MessageAttachment.builder()
-        .attachment(Attachment.builder()
+    static final MessageAttachmentMetadata MESSAGE_ATTACHMENT = MessageAttachmentMetadata.builder()
+        .attachment(AttachmentMetadata.builder()
             .attachmentId(AttachmentId.from("1"))
             .type("type")
             .size(523)
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessageTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessageTest.java
index 694e521..12270ca 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessageTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessageTest.java
@@ -37,9 +37,9 @@ import org.apache.james.mailbox.elasticsearch.IndexAttachments;
 import org.apache.james.mailbox.extractor.ParsedContent;
 import org.apache.james.mailbox.extractor.TextExtractor;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.AttachmentMetadata;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.store.extractor.DefaultTextExtractor;
@@ -324,8 +324,8 @@ class IndexableMessageTest {
         when(mailboxMessage.getUid())
             .thenReturn(MESSAGE_UID);
         when(mailboxMessage.getAttachments())
-            .thenReturn(ImmutableList.of(MessageAttachment.builder()
-                .attachment(Attachment.builder()
+            .thenReturn(ImmutableList.of(MessageAttachmentMetadata.builder()
+                .attachment(AttachmentMetadata.builder()
                     .attachmentId(AttachmentId.from("1"))
                     .type("text/plain")
                     .size(36)
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAAttachmentContentLoader.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAAttachmentContentLoader.java
index b368084..fb9500b 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAAttachmentContentLoader.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAAttachmentContentLoader.java
@@ -24,11 +24,11 @@ import java.io.InputStream;
 import org.apache.commons.lang3.NotImplementedException;
 import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.model.Attachment;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 
 public class JPAAttachmentContentLoader implements AttachmentContentLoader {
     @Override
-    public InputStream load(Attachment attachment, MailboxSession mailboxSession) {
+    public InputStream load(AttachmentMetadata attachment, MailboxSession mailboxSession) {
         throw new NotImplementedException("JPA doesn't support loading attachment separately from Message");
     }
 }
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
index e3e800e..004c317 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
@@ -52,7 +52,7 @@ import org.apache.james.mailbox.jpa.mail.model.JPAUserFlag;
 import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.store.mail.model.DefaultMessageId;
@@ -506,12 +506,12 @@ public abstract class AbstractJPAMailboxMessage implements MailboxMessage {
     }
 
     @Override
-    public List<MessageAttachment> getAttachments() {
+    public List<MessageAttachmentMetadata> getAttachments() {
         try {
             AtomicInteger counter = new AtomicInteger(0);
             return new MessageParser().retrieveAttachments(getFullContent())
                 .stream()
-                .map(Throwing.<ParsedAttachment, MessageAttachment>function(
+                .map(Throwing.<ParsedAttachment, MessageAttachmentMetadata>function(
                     attachmentMetadata -> attachmentMetadata.asMessageAttachment(generateFixedAttachmentId(counter.incrementAndGet())))
                     .sneakyThrow())
                 .collect(Guavate.toImmutableList());
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageFactory.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageFactory.java
index 2135a76..3da21a7 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageFactory.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageFactory.java
@@ -32,7 +32,7 @@ import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAEncryptedMailboxMessag
 import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMailboxMessage;
 import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAStreamingMailboxMessage;
 import org.apache.james.mailbox.model.Mailbox;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.MessageFactory;
 import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
@@ -51,7 +51,7 @@ public class OpenJPAMessageFactory implements MessageFactory<AbstractJPAMailboxM
     }
 
     @Override
-    public AbstractJPAMailboxMessage createMessage(MessageId messageId, Mailbox mailbox, Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, List<MessageAttachment> attachments) throws MailboxException {
+    public AbstractJPAMailboxMessage createMessage(MessageId messageId, Mailbox mailbox, Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, List<MessageAttachmentMetadata> attachments) throws MailboxException {
         switch (feature) {
             case Streaming:
                 return new JPAStreamingMailboxMessage(JPAMailbox.from(mailbox), internalDate, size, flags, content,
diff --git a/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java b/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
index 30f1bce..5d95dd7 100644
--- a/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
+++ b/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
@@ -51,7 +51,7 @@ import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.UnsupportedSearchException;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.SearchQuery;
@@ -732,7 +732,7 @@ public class LuceneMessageSearchIndex extends ListeningMessageSearchIndex {
     }
 
     private static boolean hasAttachment(MailboxMessage membership) {
-       return MessageAttachment.hasNonInlinedAttachment(membership.getAttachments());
+       return MessageAttachmentMetadata.hasNonInlinedAttachment(membership.getAttachments());
     }
 
     private String toSentDateField(DateResolution res) {
diff --git a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
index cfdb7a3..0195b58 100644
--- a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
+++ b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
@@ -32,7 +32,7 @@ import javax.mail.util.SharedFileInputStream;
 import org.apache.commons.io.IOUtils;
 import org.apache.james.mailbox.maildir.MaildirMessageName;
 import org.apache.james.mailbox.model.AttachmentId;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.store.mail.model.DefaultMessageId;
@@ -274,12 +274,12 @@ public class MaildirMessage implements Message {
     }
 
     @Override
-    public List<MessageAttachment> getAttachments() {
+    public List<MessageAttachmentMetadata> getAttachments() {
         try {
             AtomicInteger counter = new AtomicInteger(0);
             return new MessageParser().retrieveAttachments(getFullContent())
                 .stream()
-                .map(Throwing.<ParsedAttachment, MessageAttachment>function(
+                .map(Throwing.<ParsedAttachment, MessageAttachmentMetadata>function(
                     attachmentMetadata -> attachmentMetadata.asMessageAttachment(generateFixedAttachmentId(counter.incrementAndGet())))
                     .sneakyThrow())
                 .collect(Guavate.toImmutableList());
diff --git a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirAttachmentContentLoader.java b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirAttachmentContentLoader.java
index f3e486a..7570580 100644
--- a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirAttachmentContentLoader.java
+++ b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirAttachmentContentLoader.java
@@ -24,11 +24,11 @@ import java.io.InputStream;
 import org.apache.commons.lang3.NotImplementedException;
 import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.model.Attachment;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 
 public class MaildirAttachmentContentLoader implements AttachmentContentLoader {
     @Override
-    public InputStream load(Attachment attachment, MailboxSession mailboxSession) {
+    public InputStream load(AttachmentMetadata attachment, MailboxSession mailboxSession) {
         throw new NotImplementedException("Maildir doesn't support loading attachment separately from Message");
     }
 }
\ No newline at end of file
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
index ed3c749..d35f515 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
@@ -31,9 +31,9 @@ import org.apache.commons.io.IOUtils;
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.AttachmentMetadata;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
@@ -52,7 +52,7 @@ import reactor.core.publisher.Mono;
 public class InMemoryAttachmentMapper implements AttachmentMapper {
     
     private static final int INITIAL_SIZE = 128;
-    private final Map<AttachmentId, Attachment> attachmentsById;
+    private final Map<AttachmentId, AttachmentMetadata> attachmentsById;
     private final Map<AttachmentId, byte[]> attachmentsRawContentById;
     private final Multimap<AttachmentId, MessageId> messageIdsByAttachmentId;
     private final Multimap<AttachmentId, Username> ownersByAttachmentId;
@@ -65,7 +65,7 @@ public class InMemoryAttachmentMapper implements AttachmentMapper {
     }
 
     @Override
-    public Attachment getAttachment(AttachmentId attachmentId) throws AttachmentNotFoundException {
+    public AttachmentMetadata getAttachment(AttachmentId attachmentId) throws AttachmentNotFoundException {
         Preconditions.checkArgument(attachmentId != null);
         if (!attachmentsById.containsKey(attachmentId)) {
             throw new AttachmentNotFoundException(attachmentId.getId());
@@ -74,9 +74,9 @@ public class InMemoryAttachmentMapper implements AttachmentMapper {
     }
 
     @Override
-    public List<Attachment> getAttachments(Collection<AttachmentId> attachmentIds) {
+    public List<AttachmentMetadata> getAttachments(Collection<AttachmentId> attachmentIds) {
         Preconditions.checkArgument(attachmentIds != null);
-        Builder<Attachment> builder = ImmutableList.builder();
+        Builder<AttachmentMetadata> builder = ImmutableList.builder();
         for (AttachmentId attachmentId : attachmentIds) {
             if (attachmentsById.containsKey(attachmentId)) {
                 builder.add(attachmentsById.get(attachmentId));
@@ -86,10 +86,10 @@ public class InMemoryAttachmentMapper implements AttachmentMapper {
     }
 
     @Override
-    public Mono<Attachment> storeAttachmentForOwner(String contentType, InputStream inputStream, Username owner) {
+    public Mono<AttachmentMetadata> storeAttachmentForOwner(String contentType, InputStream inputStream, Username owner) {
         return Mono.fromCallable(() -> {
             byte[] bytes = toByteArray(inputStream);
-            Attachment attachment = Attachment.builder()
+            AttachmentMetadata attachment = AttachmentMetadata.builder()
                 .type(contentType)
                 .attachmentId(AttachmentId.random())
                 .size(bytes.length)
@@ -120,19 +120,19 @@ public class InMemoryAttachmentMapper implements AttachmentMapper {
     }
 
     @Override
-    public List<MessageAttachment> storeAttachmentsForMessage(Collection<ParsedAttachment> parsedAttachments, MessageId ownerMessageId) throws MailboxException {
+    public List<MessageAttachmentMetadata> storeAttachmentsForMessage(Collection<ParsedAttachment> parsedAttachments, MessageId ownerMessageId) throws MailboxException {
         return parsedAttachments.stream()
-            .map(Throwing.<ParsedAttachment, MessageAttachment>function(
+            .map(Throwing.<ParsedAttachment, MessageAttachmentMetadata>function(
                 typedContent -> storeAttachmentForMessage(ownerMessageId, typedContent))
                 .sneakyThrow())
             .collect(Guavate.toImmutableList());
     }
 
-    private MessageAttachment storeAttachmentForMessage(MessageId ownerMessageId, ParsedAttachment parsedAttachment) throws MailboxException {
+    private MessageAttachmentMetadata storeAttachmentForMessage(MessageId ownerMessageId, ParsedAttachment parsedAttachment) throws MailboxException {
         AttachmentId attachmentId = AttachmentId.random();
         byte[] bytes = parsedAttachment.getContent();
 
-        attachmentsById.put(attachmentId, Attachment.builder()
+        attachmentsById.put(attachmentId, AttachmentMetadata.builder()
             .attachmentId(attachmentId)
             .type(parsedAttachment.getContentType())
             .size(bytes.length)
diff --git a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageConverterTest.java b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageConverterTest.java
index 57d5b5d..aec87ba 100644
--- a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageConverterTest.java
+++ b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageConverterTest.java
@@ -41,10 +41,10 @@ import java.util.List;
 
 import org.apache.james.core.MaybeSender;
 import org.apache.james.core.Username;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.store.MessageBuilder;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
@@ -70,9 +70,9 @@ class DeletedMessageConverterTest {
 
     private static final Username EMPTY_OWNER = null;
 
-    private static final Collection<MessageAttachment> NO_ATTACHMENT = ImmutableList.of();
-    private static final Collection<MessageAttachment> ATTACHMENTS = ImmutableList.of(MessageAttachment.builder()
-        .attachment(Attachment.builder()
+    private static final Collection<MessageAttachmentMetadata> NO_ATTACHMENT = ImmutableList.of();
+    private static final Collection<MessageAttachmentMetadata> ATTACHMENTS = ImmutableList.of(MessageAttachmentMetadata.builder()
+        .attachment(AttachmentMetadata.builder()
             .attachmentId(AttachmentId.from("1"))
             .type("type")
             .size(48)
@@ -91,7 +91,7 @@ class DeletedMessageConverterTest {
             .header(DATE_FIELD, "Thu, 30 Oct 2014 14:12:00 +0000 (GMT)");
     }
 
-    private MailboxMessage buildMessage(MessageBuilder messageBuilder, Collection<MessageAttachment> attachments) throws Exception {
+    private MailboxMessage buildMessage(MessageBuilder messageBuilder, Collection<MessageAttachmentMetadata> attachments) throws Exception {
         MailboxMessage mailboxMessage = messageBuilder
             .size(CONTENT.length)
             .build(MESSAGE_ID);
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageFactory.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageFactory.java
index c2b3b2e..4a4a4f2 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageFactory.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageFactory.java
@@ -27,7 +27,7 @@ import javax.mail.internet.SharedInputStream;
 
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
@@ -36,13 +36,13 @@ import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
 public interface MessageFactory<T extends MailboxMessage> {
     T createMessage(MessageId messageId, Mailbox mailbox, Date internalDate, int size, int bodyStartOctet,
                                  SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder,
-                                 List<MessageAttachment> attachments) throws MailboxException;
+                                 List<MessageAttachmentMetadata> attachments) throws MailboxException;
 
     class StoreMessageFactory implements MessageFactory<SimpleMailboxMessage> {
         @Override
         public SimpleMailboxMessage createMessage(MessageId messageId, Mailbox mailbox, Date internalDate, int size,
                                             int bodyStartOctet, SharedInputStream content, Flags flags,
-                                            PropertyBuilder propertyBuilder, List<MessageAttachment> attachments) {
+                                            PropertyBuilder propertyBuilder, List<MessageAttachmentMetadata> attachments) {
             return new SimpleMailboxMessage(messageId, internalDate, size, bodyStartOctet, content, flags, propertyBuilder,
                 mailbox.getMailboxId(), attachments);
         }
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageResultImpl.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageResultImpl.java
index c48d513..6d68e3d 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageResultImpl.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageResultImpl.java
@@ -36,7 +36,7 @@ import org.apache.james.mailbox.model.Content;
 import org.apache.james.mailbox.model.Header;
 import org.apache.james.mailbox.model.Headers;
 import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.MessageResult;
@@ -306,7 +306,7 @@ public class MessageResultImpl implements MessageResult {
     }
     
     @Override
-    public List<MessageAttachment> getLoadedAttachments() {
+    public List<MessageAttachmentMetadata> getLoadedAttachments() {
         return message.getAttachments();
     }
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageStorer.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageStorer.java
index b7b391b..07e9f2f 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageStorer.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageStorer.java
@@ -30,7 +30,7 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.ParsedAttachment;
@@ -51,7 +51,7 @@ public interface MessageStorer {
      *
      * Otherwize an empty optional will be returned on the right side of the pair.
      */
-    Pair<MessageMetaData, Optional<List<MessageAttachment>>> appendMessageToStore(Mailbox mailbox, Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, MailboxSession session) throws MailboxException;
+    Pair<MessageMetaData, Optional<List<MessageAttachmentMetadata>>> appendMessageToStore(Mailbox mailbox, Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, MailboxSession session) throws MailboxException;
 
     /**
      * MessageStorer parsing, storing and returning AttachmentMetadata
@@ -80,19 +80,19 @@ public interface MessageStorer {
         }
 
         @Override
-        public Pair<MessageMetaData, Optional<List<MessageAttachment>>> appendMessageToStore(Mailbox mailbox, Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, MailboxSession session) throws MailboxException {
+        public Pair<MessageMetaData, Optional<List<MessageAttachmentMetadata>>> appendMessageToStore(Mailbox mailbox, Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, MailboxSession session) throws MailboxException {
             MessageMapper messageMapper = mapperFactory.getMessageMapper(session);
             MessageId messageId = messageIdFactory.generate();
 
             return mapperFactory.getMessageMapper(session).execute(() -> {
-                List<MessageAttachment> attachments = storeAttachments(messageId, content, session);
+                List<MessageAttachmentMetadata> attachments = storeAttachments(messageId, content, session);
                 MailboxMessage message = messageFactory.createMessage(messageId, mailbox, internalDate, size, bodyStartOctet, content, flags, propertyBuilder, attachments);
                 MessageMetaData metadata = messageMapper.add(mailbox, message);
                 return Pair.of(metadata, Optional.of(attachments));
             });
         }
 
-        private List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream messageContent, MailboxSession session) throws MailboxException {
+        private List<MessageAttachmentMetadata> storeAttachments(MessageId messageId, SharedInputStream messageContent, MailboxSession session) throws MailboxException {
             List<ParsedAttachment> attachments = extractAttachments(messageContent);
             return attachmentMapperFactory.getAttachmentMapper(session)
                 .storeAttachmentsForMessage(attachments, messageId);
@@ -125,7 +125,7 @@ public interface MessageStorer {
         }
 
         @Override
-        public Pair<MessageMetaData, Optional<List<MessageAttachment>>> appendMessageToStore(Mailbox mailbox, Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, MailboxSession session) throws MailboxException {
+        public Pair<MessageMetaData, Optional<List<MessageAttachmentMetadata>>> appendMessageToStore(Mailbox mailbox, Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, MailboxSession session) throws MailboxException {
             MessageMapper messageMapper = mapperFactory.getMessageMapper(session);
             MessageId messageId = messageIdFactory.generate();
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
index 9d281fb..6f230b9 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
@@ -32,8 +32,8 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
 import org.reactivestreams.Publisher;
@@ -60,7 +60,7 @@ public class StoreAttachmentManager implements AttachmentManager {
     }
 
     @Override
-    public Attachment getAttachment(AttachmentId attachmentId, MailboxSession mailboxSession) throws MailboxException, AttachmentNotFoundException {
+    public AttachmentMetadata getAttachment(AttachmentId attachmentId, MailboxSession mailboxSession) throws MailboxException, AttachmentNotFoundException {
         if (!userHasAccessToAttachment(attachmentId, mailboxSession)) {
             throw new AttachmentNotFoundException(attachmentId.getId());
         }
@@ -68,7 +68,7 @@ public class StoreAttachmentManager implements AttachmentManager {
     }
 
     @Override
-    public List<Attachment> getAttachments(List<AttachmentId> attachmentIds, MailboxSession mailboxSession) throws MailboxException {
+    public List<AttachmentMetadata> getAttachments(List<AttachmentId> attachmentIds, MailboxSession mailboxSession) throws MailboxException {
         List<AttachmentId> accessibleAttachmentIds = attachmentIds.stream()
             .filter(attachmentId -> userHasAccessToAttachment(attachmentId, mailboxSession))
             .collect(Guavate.toImmutableList());
@@ -77,7 +77,7 @@ public class StoreAttachmentManager implements AttachmentManager {
     }
 
     @Override
-    public Publisher<Attachment> storeAttachment(String contentType, InputStream attachmentContent, MailboxSession mailboxSession) {
+    public Publisher<AttachmentMetadata> storeAttachment(String contentType, InputStream attachmentContent, MailboxSession mailboxSession) {
         return attachmentMapperFactory.getAttachmentMapper(mailboxSession)
             .storeAttachmentForOwner(contentType, attachmentContent, mailboxSession.getUser());
     }
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
index 34b8f83..90674b1 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreBlobManager.java
@@ -30,8 +30,8 @@ import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.BlobNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 import org.apache.james.mailbox.model.Blob;
 import org.apache.james.mailbox.model.BlobId;
 import org.apache.james.mailbox.model.Content;
@@ -70,7 +70,7 @@ public class StoreBlobManager implements BlobManager {
     private Optional<Blob> getBlobFromAttachment(BlobId blobId, MailboxSession mailboxSession) throws MailboxException {
         try {
             AttachmentId attachmentId = AttachmentId.from(blobId);
-            Attachment attachment = attachmentManager.getAttachment(attachmentId, mailboxSession);
+            AttachmentMetadata attachment = attachmentManager.getAttachment(attachmentId, mailboxSession);
 
             Blob blob = Blob.builder()
                 .id(blobId)
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
index b09725c..9fd3ad4 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
@@ -66,7 +66,7 @@ import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxCounters;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.MessageMoves;
@@ -432,7 +432,7 @@ public class StoreMessageManager implements MessageManager {
             new QuotaChecker(quotaManager, quotaRootResolver, mailbox).tryAddition(1, size);
 
             return locker.executeWithLock(getMailboxPath(), () -> {
-                Pair<MessageMetaData, Optional<List<MessageAttachment>>> data = messageStorer.appendMessageToStore(mailbox, internalDate, size, bodyStartOctet, contentIn, flags, propertyBuilder, mailboxSession);
+                Pair<MessageMetaData, Optional<List<MessageAttachmentMetadata>>> data = messageStorer.appendMessageToStore(mailbox, internalDate, size, bodyStartOctet, contentIn, flags, propertyBuilder, mailboxSession);
 
                 Mailbox mailbox = getMailboxEntity();
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageResultIterator.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageResultIterator.java
index a392954..02a3b19 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageResultIterator.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageResultIterator.java
@@ -37,7 +37,7 @@ import org.apache.james.mailbox.model.Header;
 import org.apache.james.mailbox.model.Headers;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.MessageRange;
@@ -293,7 +293,7 @@ public class StoreMessageResultIterator implements MessageResultIterator {
         }
 
         @Override
-        public List<MessageAttachment> getLoadedAttachments() throws MailboxException {
+        public List<MessageAttachmentMetadata> getLoadedAttachments() throws MailboxException {
             throw exception;
         }
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
index a25714a..377651b 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
@@ -26,9 +26,9 @@ import java.util.List;
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.AttachmentMetadata;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.store.transaction.Mapper;
@@ -38,13 +38,13 @@ public interface AttachmentMapper extends Mapper {
 
     InputStream loadAttachmentContent(AttachmentId attachmentId) throws AttachmentNotFoundException, IOException;
 
-    Attachment getAttachment(AttachmentId attachmentId) throws AttachmentNotFoundException;
+    AttachmentMetadata getAttachment(AttachmentId attachmentId) throws AttachmentNotFoundException;
 
-    List<Attachment> getAttachments(Collection<AttachmentId> attachmentIds);
+    List<AttachmentMetadata> getAttachments(Collection<AttachmentId> attachmentIds);
 
-    Publisher<Attachment> storeAttachmentForOwner(String contentType, InputStream attachmentContent, Username owner);
+    Publisher<AttachmentMetadata> storeAttachmentForOwner(String contentType, InputStream attachmentContent, Username owner);
 
-    List<MessageAttachment> storeAttachmentsForMessage(Collection<ParsedAttachment> attachments, MessageId ownerMessageId) throws MailboxException;
+    List<MessageAttachmentMetadata> storeAttachmentsForMessage(Collection<ParsedAttachment> attachments, MessageId ownerMessageId) throws MailboxException;
 
     Collection<MessageId> getRelatedMessageIds(AttachmentId attachmentId) throws MailboxException;
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/DelegatingMailboxMessage.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/DelegatingMailboxMessage.java
index 4f09b14..398ec51 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/DelegatingMailboxMessage.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/DelegatingMailboxMessage.java
@@ -25,7 +25,7 @@ import java.util.List;
 
 import javax.mail.Flags;
 
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 
 public abstract class DelegatingMailboxMessage implements MailboxMessage {
@@ -116,7 +116,7 @@ public abstract class DelegatingMailboxMessage implements MailboxMessage {
     }
 
     @Override
-    public List<MessageAttachment> getAttachments() {
+    public List<MessageAttachmentMetadata> getAttachments() {
         return message.getAttachments();
     }
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Message.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Message.java
index e732d21..c2e3fb8 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Message.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Message.java
@@ -23,7 +23,7 @@ import java.io.InputStream;
 import java.util.Date;
 import java.util.List;
 
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 
 public interface Message {
@@ -107,7 +107,7 @@ public interface Message {
      * 
      * @return a read only list of attachments
      */
-    List<MessageAttachment> getAttachments();
+    List<MessageAttachmentMetadata> getAttachments();
 
     boolean hasAttachment();
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessage.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessage.java
index 1a198d2..c19d5c2 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessage.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessage.java
@@ -36,7 +36,7 @@ import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
 import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.mail.model.DelegatingMailboxMessage;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
@@ -64,7 +64,7 @@ public class SimpleMailboxMessage extends DelegatingMailboxMessage {
         private MailboxId mailboxId;
         private Optional<MessageUid> uid = Optional.empty();
         private Optional<ModSeq> modseq = Optional.empty();
-        private ImmutableList.Builder<MessageAttachment> attachments = ImmutableList.builder();
+        private ImmutableList.Builder<MessageAttachmentMetadata> attachments = ImmutableList.builder();
         private Optional<Boolean> hasAttachment = Optional.empty();
 
         public Builder messageId(MessageId messageId) {
@@ -129,7 +129,7 @@ public class SimpleMailboxMessage extends DelegatingMailboxMessage {
             return this;
         }
 
-        public Builder addAttachments(Collection<MessageAttachment> attachments) {
+        public Builder addAttachments(Collection<MessageAttachmentMetadata> attachments) {
             this.attachments.addAll(attachments);
             return this;
         }
@@ -144,7 +144,7 @@ public class SimpleMailboxMessage extends DelegatingMailboxMessage {
             Preconditions.checkNotNull(propertyBuilder, "propertyBuilder is required");
             Preconditions.checkNotNull(mailboxId, "mailboxId is required");
 
-            ImmutableList<MessageAttachment> attachments = this.attachments.build();
+            ImmutableList<MessageAttachmentMetadata> attachments = this.attachments.build();
             boolean hasAttachment = this.hasAttachment.orElse(!attachments.isEmpty());
             SimpleMailboxMessage simpleMailboxMessage = new SimpleMailboxMessage(messageId, internalDate, size,
                 bodyStartOctet, content, flags, propertyBuilder, mailboxId, attachments, hasAttachment);
@@ -205,7 +205,7 @@ public class SimpleMailboxMessage extends DelegatingMailboxMessage {
 
     public SimpleMailboxMessage(MessageId messageId, Date internalDate, long size, int bodyStartOctet,
             SharedInputStream content, Flags flags,
-            PropertyBuilder propertyBuilder, MailboxId mailboxId, List<MessageAttachment> attachments,
+            PropertyBuilder propertyBuilder, MailboxId mailboxId, List<MessageAttachmentMetadata> attachments,
             boolean hasAttachment) {
         super(new SimpleMessage(
                 messageId,
@@ -224,7 +224,7 @@ public class SimpleMailboxMessage extends DelegatingMailboxMessage {
 
     public SimpleMailboxMessage(MessageId messageId, Date internalDate, long size, int bodyStartOctet,
             SharedInputStream content, Flags flags,
-            PropertyBuilder propertyBuilder, MailboxId mailboxId, List<MessageAttachment> attachments) {
+            PropertyBuilder propertyBuilder, MailboxId mailboxId, List<MessageAttachmentMetadata> attachments) {
         this(messageId, internalDate, size, bodyStartOctet,
             content, flags,
             propertyBuilder, mailboxId, attachments, !attachments.isEmpty());
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMessage.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMessage.java
index 0302fe5..36042a3 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMessage.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMessage.java
@@ -25,7 +25,7 @@ import java.util.List;
 
 import javax.mail.internet.SharedInputStream;
 
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.mail.model.Message;
 import org.apache.james.mailbox.store.mail.model.Property;
@@ -41,10 +41,10 @@ public class SimpleMessage implements Message {
     private final long size;
     private final Long textualLineCount;
     private final List<Property> properties;
-    private final List<MessageAttachment> attachments;
+    private final List<MessageAttachmentMetadata> attachments;
     private final boolean hasAttachments;
 
-    public SimpleMessage(MessageId messageId, SharedInputStream content, long size, Date internalDate, String subType, String mediaType, int bodyStartOctet, Long textualLineCount, List<Property> properties, List<MessageAttachment> attachments, boolean hasAttachments) {
+    public SimpleMessage(MessageId messageId, SharedInputStream content, long size, Date internalDate, String subType, String mediaType, int bodyStartOctet, Long textualLineCount, List<Property> properties, List<MessageAttachmentMetadata> attachments, boolean hasAttachments) {
         this.messageId = messageId;
         this.subType = subType;
         this.mediaType = mediaType;
@@ -123,7 +123,7 @@ public class SimpleMessage implements Message {
     }
 
     @Override
-    public List<MessageAttachment> getAttachments() {
+    public List<MessageAttachmentMetadata> getAttachments() {
         return attachments;
     }
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
index 07d18c6..559cfd1 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
@@ -46,9 +46,9 @@ import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.UnsupportedSearchException;
 import org.apache.james.mailbox.extractor.TextExtractor;
-import org.apache.james.mailbox.model.Attachment;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 import org.apache.james.mailbox.model.Header;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.model.SearchQuery.AddressType;
 import org.apache.james.mailbox.model.SearchQuery.DateResolution;
@@ -245,25 +245,25 @@ public class MessageSearches implements Iterable<SimpleMessageSearchIndex.Search
     }
 
     private boolean attachmentsContain(String value, MailboxMessage message) throws IOException, MimeException {
-        List<MessageAttachment> attachments = message.getAttachments();
+        List<MessageAttachmentMetadata> attachments = message.getAttachments();
         return isInAttachments(value, attachments);
     }
 
     private boolean hasFileName(String value, MailboxMessage message) throws IOException, MimeException {
         return message.getAttachments()
             .stream()
-            .map(MessageAttachment::getName)
+            .map(MessageAttachmentMetadata::getName)
             .anyMatch(nameOptional -> nameOptional.map(value::equals).orElse(false));
     }
 
-    private boolean isInAttachments(String value, List<MessageAttachment> attachments) {
+    private boolean isInAttachments(String value, List<MessageAttachmentMetadata> attachments) {
         return attachments.stream()
-            .map(MessageAttachment::getAttachment)
+            .map(MessageAttachmentMetadata::getAttachment)
             .flatMap(attachment -> toAttachmentContent(attachment, mailboxSession))
             .anyMatch(string -> string.contains(value));
     }
 
-    private Stream<String> toAttachmentContent(Attachment attachment, MailboxSession mailboxSession) {
+    private Stream<String> toAttachmentContent(AttachmentMetadata attachment, MailboxSession mailboxSession) {
         try (InputStream rawData = attachmentContentLoader.load(attachment, mailboxSession)) {
             return OptionalUtils.toStream(
                 textExtractor
@@ -547,7 +547,7 @@ public class MessageSearches implements Iterable<SimpleMessageSearchIndex.Search
 
 
     private boolean matches(SearchQuery.AttachmentCriterion criterion, MailboxMessage message) throws UnsupportedSearchException {
-        boolean mailHasAttachments = MessageAttachment.hasNonInlinedAttachment(message.getAttachments());
+        boolean mailHasAttachments = MessageAttachmentMetadata.hasNonInlinedAttachment(message.getAttachments());
         return mailHasAttachments == criterion.getOperator().isSet();
     }
 
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
index ea6bef1..0e5821d 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
@@ -34,10 +34,10 @@ import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageManager;
-import org.apache.james.mailbox.model.Attachment;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
@@ -114,7 +114,7 @@ public abstract class AbstractMailboxManagerAttachmentTest {
         Optional<String> expectedName = Optional.of("exploits_of_a_mom.png");
 
         Iterator<MailboxMessage> messages = messageMapper.findInMailbox(inbox, MessageRange.all(), FetchType.Full, 1);
-        List<MessageAttachment> attachments = messages.next().getAttachments();
+        List<MessageAttachmentMetadata> attachments = messages.next().getAttachments();
         assertThat(attachments.get(0).getName()).isEqualTo(expectedName);
     }
 
@@ -127,7 +127,7 @@ public abstract class AbstractMailboxManagerAttachmentTest {
         
         Iterator<MailboxMessage> messages = messageMapper.findInMailbox(inbox, MessageRange.all(), FetchType.Full, 1);
         assertThat(messages.hasNext()).isTrue();
-        List<MessageAttachment> attachments = messages.next().getAttachments();
+        List<MessageAttachmentMetadata> attachments = messages.next().getAttachments();
         assertThat(attachments).hasSize(1);
         assertThat(attachmentMapper.loadAttachmentContent(attachments.get(0).getAttachmentId()))
             .hasSameContentAs(ClassLoader.getSystemResourceAsStream("eml/gimp.png"));
@@ -154,13 +154,13 @@ public abstract class AbstractMailboxManagerAttachmentTest {
         
         Iterator<MailboxMessage> messages = messageMapper.findInMailbox(inbox, MessageRange.all(), FetchType.Full, 1);
         assertThat(messages.hasNext()).isTrue();
-        List<MessageAttachment> attachments = messages.next().getAttachments();
+        List<MessageAttachmentMetadata> attachments = messages.next().getAttachments();
         assertThat(attachments).hasSize(2);
         ImmutableList<byte[]> attachmentContents = attachments
             .stream()
-            .map(MessageAttachment::getAttachmentId)
+            .map(MessageAttachmentMetadata::getAttachmentId)
             .map(Throwing.function(attachmentMapper::getAttachment))
-            .map(Attachment::getAttachmentId)
+            .map(AttachmentMetadata::getAttachmentId)
             .map(Throwing.function(attachmentMapper::loadAttachmentContent))
             .map(Throwing.function(IOUtils::toByteArray))
             .collect(ImmutableList.toImmutableList());
@@ -197,7 +197,7 @@ public abstract class AbstractMailboxManagerAttachmentTest {
 
         Iterator<MailboxMessage> messages = messageMapper.findInMailbox(inbox, MessageRange.all(), FetchType.Full, 1);
         assertThat(messages.hasNext()).isTrue();
-        List<MessageAttachment> attachments = messages.next().getAttachments();
+        List<MessageAttachmentMetadata> attachments = messages.next().getAttachments();
         assertThat(attachments).hasSize(0);
     }
 }
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageBuilder.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageBuilder.java
index 3c800a5..9e593c5 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageBuilder.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageBuilder.java
@@ -31,7 +31,7 @@ import javax.mail.Flags;
 import javax.mail.util.SharedByteArrayInputStream;
 
 import org.apache.james.mailbox.MessageUid;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.store.mail.model.DefaultMessageId;
@@ -44,7 +44,7 @@ import com.google.common.primitives.Bytes;
 
 public class MessageBuilder {
     private static final char[] NEW_LINE = { 0x0D, 0x0A };
-    private static final ImmutableList<MessageAttachment> NO_ATTACHMENTS = ImmutableList.of();
+    private static final ImmutableList<MessageAttachmentMetadata> NO_ATTACHMENTS = ImmutableList.of();
 
     private TestId mailboxId = TestId.of(113);
     private MessageUid uid = MessageUid.of(776);
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreAttachmentManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreAttachmentManagerTest.java
index 66131d0..2883a4e 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreAttachmentManagerTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreAttachmentManagerTest.java
@@ -27,8 +27,8 @@ import static org.mockito.Mockito.when;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
@@ -43,7 +43,7 @@ class StoreAttachmentManagerTest {
     static final TestMessageId MESSAGE_ID = TestMessageId.of(1L);
     static final ImmutableList<MessageId> MESSAGE_IDS = ImmutableList.of(MESSAGE_ID);
     static final AttachmentId ATTACHMENT_ID = AttachmentId.from("1");
-    static final Attachment ATTACHMENT = Attachment.builder()
+    static final AttachmentMetadata ATTACHMENT = AttachmentMetadata.builder()
         .attachmentId(ATTACHMENT_ID)
         .size(48)
         .type("type")
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
index 5b5dece..3390947 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
@@ -38,8 +38,8 @@ import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.BlobNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 import org.apache.james.mailbox.model.Blob;
 import org.apache.james.mailbox.model.BlobId;
 import org.apache.james.mailbox.model.Content;
@@ -80,7 +80,7 @@ class StoreBlobManagerTest {
     @Test
     void retrieveShouldReturnBlobWhenAttachment() throws Exception {
         when(attachmentManager.getAttachment(ATTACHMENT_ID, session))
-            .thenReturn(Attachment.builder()
+            .thenReturn(AttachmentMetadata.builder()
                 .attachmentId(ATTACHMENT_ID)
                 .size(BYTES.length)
                 .type(CONTENT_TYPE)
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
index d63ee0c..0bf9af7 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
@@ -29,8 +29,8 @@ import java.util.List;
 
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
@@ -75,7 +75,7 @@ public abstract class AttachmentMapperTest {
         String content = "content";
         byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
 
-        Attachment stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
+        AttachmentMetadata stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
 
         SoftAssertions.assertSoftly(solftly -> {
             solftly.assertThat(stored.getSize()).isEqualTo(bytes.length);
@@ -88,9 +88,9 @@ public abstract class AttachmentMapperTest {
         String content = "content";
         byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
 
-        Attachment stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
+        AttachmentMetadata stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
 
-        Attachment attachment = attachmentMapper.getAttachment(stored.getAttachmentId());
+        AttachmentMetadata attachment = attachmentMapper.getAttachment(stored.getAttachmentId());
 
         SoftAssertions.assertSoftly(solftly -> {
             solftly.assertThat(attachment.getAttachmentId()).isEqualTo(stored.getAttachmentId());
@@ -104,7 +104,7 @@ public abstract class AttachmentMapperTest {
         String content = "content";
         byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
 
-        Attachment stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
+        AttachmentMetadata stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
 
         assertThat(attachmentMapper.loadAttachmentContent(stored.getAttachmentId()))
             .hasSameContentAs(new ByteArrayInputStream(bytes));
@@ -118,7 +118,7 @@ public abstract class AttachmentMapperTest {
 
     @Test
     void getAttachmentsShouldReturnEmptyListWhenNonReferencedAttachmentId() {
-        List<Attachment> attachments = attachmentMapper.getAttachments(ImmutableList.of(UNKNOWN_ATTACHMENT_ID));
+        List<AttachmentMetadata> attachments = attachmentMapper.getAttachments(ImmutableList.of(UNKNOWN_ATTACHMENT_ID));
 
         assertThat(attachments).isEmpty();
     }
@@ -128,10 +128,10 @@ public abstract class AttachmentMapperTest {
         //Given
         String content1 = "content";
         byte[] bytes1 = "payload".getBytes(StandardCharsets.UTF_8);
-        Attachment stored1 = Mono.from(attachmentMapper.storeAttachmentForOwner(content1, new ByteArrayInputStream(bytes1), OWNER)).block();
+        AttachmentMetadata stored1 = Mono.from(attachmentMapper.storeAttachmentForOwner(content1, new ByteArrayInputStream(bytes1), OWNER)).block();
         String content2 = "content";
         byte[] bytes2 = "payload".getBytes(StandardCharsets.UTF_8);
-        Attachment stored2 = Mono.from(attachmentMapper.storeAttachmentForOwner(content2, new ByteArrayInputStream(bytes2), OWNER)).block();
+        AttachmentMetadata stored2 = Mono.from(attachmentMapper.storeAttachmentForOwner(content2, new ByteArrayInputStream(bytes2), OWNER)).block();
 
         assertThat(attachmentMapper.getAttachments(ImmutableList.of(stored1.getAttachmentId(), stored2.getAttachmentId())))
             .contains(stored1, stored2);
@@ -148,7 +148,7 @@ public abstract class AttachmentMapperTest {
     void getOwnerMessageIdsShouldReturnEmptyWhenStoredWithoutMessageId() throws Exception {
         String content = "content";
         byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
-        Attachment stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
+        AttachmentMetadata stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
 
         assertThat(attachmentMapper.getRelatedMessageIds(stored.getAttachmentId())).isEmpty();
     }
@@ -192,7 +192,7 @@ public abstract class AttachmentMapperTest {
     void getOwnersShouldBeRetrievedWhenExplicitlySpecified() throws Exception {
         String content = "content";
         byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
-        Attachment stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
+        AttachmentMetadata stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
 
         Collection<Username> actualOwners = attachmentMapper.getOwners(stored.getAttachmentId());
 
@@ -203,10 +203,10 @@ public abstract class AttachmentMapperTest {
     void getOwnersShouldNotReturnUnrelatedOwners() throws Exception {
         String content = "content";
         byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
-        Attachment stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
+        AttachmentMetadata stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
         String content2 = "content";
         byte[] bytes2 = "payload".getBytes(StandardCharsets.UTF_8);
-        Attachment stored2 = Mono.from(attachmentMapper.storeAttachmentForOwner(content2, new ByteArrayInputStream(bytes2), ADDITIONAL_OWNER)).block();
+        AttachmentMetadata stored2 = Mono.from(attachmentMapper.storeAttachmentForOwner(content2, new ByteArrayInputStream(bytes2), ADDITIONAL_OWNER)).block();
 
         Collection<Username> actualOwners = attachmentMapper.getOwners(stored.getAttachmentId());
 
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageWithAttachmentMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageWithAttachmentMapperTest.java
index 41269e2..0c241b6 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageWithAttachmentMapperTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageWithAttachmentMapperTest.java
@@ -36,11 +36,11 @@ import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Cid;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageRange;
-import org.apache.james.mailbox.model.UidValidity;
 import org.apache.james.mailbox.model.ParsedAttachment;
+import org.apache.james.mailbox.model.UidValidity;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
@@ -101,8 +101,8 @@ public abstract class MessageWithAttachmentMapperTest {
 
         MessageId messageId1 = mapperProvider.generateMessageId();
         MessageId messageId2 = mapperProvider.generateMessageId();
-        List<MessageAttachment> message1Attachments = attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment1), messageId1);
-        List<MessageAttachment> message2Attachments = attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment2, attachment3), messageId2);
+        List<MessageAttachmentMetadata> message1Attachments = attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment1), messageId1);
+        List<MessageAttachmentMetadata> message2Attachments = attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment2, attachment3), messageId2);
 
         messageWith1Attachment = createMessage(attachmentsMailbox, messageId1, "Subject: Test7 \n\nBody7\n.\n", BODY_START, new PropertyBuilder(),
                 message1Attachments);
@@ -192,7 +192,7 @@ public abstract class MessageWithAttachmentMapperTest {
         messageWith2Attachments.setModSeq(messageMapper.getHighestModSeq(attachmentsMailbox));
     }
 
-    private SimpleMailboxMessage createMessage(Mailbox mailbox, MessageId messageId, String content, int bodyStart, PropertyBuilder propertyBuilder, List<MessageAttachment> attachments) {
+    private SimpleMailboxMessage createMessage(Mailbox mailbox, MessageId messageId, String content, int bodyStart, PropertyBuilder propertyBuilder, List<MessageAttachmentMetadata> attachments) {
         return new SimpleMailboxMessage(messageId, new Date(), content.length(), bodyStart, new SharedByteArrayInputStream(content.getBytes()), new Flags(), propertyBuilder, mailbox.getMailboxId(), attachments);
     }
 
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessageTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessageTest.java
index c1f5d9e..3b7a0d1 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessageTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessageTest.java
@@ -35,9 +35,9 @@ import org.apache.commons.io.output.ByteArrayOutputStream;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.AttachmentMetadata;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.TestId;
 import org.apache.james.mailbox.model.TestMessageId;
@@ -176,8 +176,8 @@ class SimpleMailboxMessageTest {
         PropertyBuilder propertyBuilder = new PropertyBuilder();
         ModSeq modseq = ModSeq.of(145);
         MessageUid uid = MessageUid.of(45);
-        MessageAttachment messageAttachment = MessageAttachment.builder()
-            .attachment(Attachment.builder()
+        MessageAttachmentMetadata messageAttachment = MessageAttachmentMetadata.builder()
+            .attachment(AttachmentMetadata.builder()
                 .attachmentId(AttachmentId.from("1"))
                 .type("type")
                 .size(485)
diff --git a/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/MessageIdProbe.java b/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/MessageIdProbe.java
index 9d7dc4b..d5f10e8 100644
--- a/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/MessageIdProbe.java
+++ b/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/MessageIdProbe.java
@@ -33,7 +33,7 @@ import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.FetchGroup;
 import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageResult;
 import org.apache.james.utils.GuiceProbe;
@@ -69,7 +69,7 @@ public class MessageIdProbe implements GuiceProbe {
 
         return messages.stream()
             .flatMap(Throwing.function(messageResult -> messageResult.getLoadedAttachments().stream()))
-            .map(MessageAttachment::getAttachmentId)
+            .map(MessageAttachmentMetadata::getAttachmentId)
             .collect(Guavate.toImmutableList());
     }
 }
diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/MessageFastViewPrecomputedProperties.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/MessageFastViewPrecomputedProperties.java
index f3dbe8b..3c1cee9 100644
--- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/MessageFastViewPrecomputedProperties.java
+++ b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/MessageFastViewPrecomputedProperties.java
@@ -27,7 +27,7 @@ import javax.inject.Inject;
 
 import org.apache.james.jmap.api.model.Preview;
 import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageResult;
 
 import com.google.common.base.MoreObjects;
@@ -88,7 +88,7 @@ public class MessageFastViewPrecomputedProperties {
                 .build();
         }
 
-        private boolean hasAttachment(List<MessageAttachment> attachments) {
+        private boolean hasAttachment(List<MessageAttachmentMetadata> attachments) {
             return attachments.stream()
                 .anyMatch(attachment -> !attachment.isInlinedWithCid());
         }
diff --git a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
index c448ee5..bf18630 100644
--- a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
+++ b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
@@ -66,7 +66,6 @@ import java.time.ZonedDateTime;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
@@ -91,8 +90,8 @@ import org.apache.james.mailbox.Role;
 import org.apache.james.mailbox.events.Event;
 import org.apache.james.mailbox.events.MailboxListener;
 import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxConstants;
@@ -2097,7 +2096,7 @@ public abstract class SetMessagesMethodTest {
         String messageCreationId = "creationId1337";
         String fromAddress = USERNAME.asString();
         String bytes = "attachment";
-        Attachment uploadedAttachment = uploadAttachment(OCTET_CONTENT_TYPE, bytes.getBytes(StandardCharsets.UTF_8));
+        AttachmentMetadata uploadedAttachment = uploadAttachment(OCTET_CONTENT_TYPE, bytes.getBytes(StandardCharsets.UTF_8));
         String requestBody = "[" +
             "  [" +
             "    \"setMessages\"," +
@@ -3964,8 +3963,8 @@ public abstract class SetMessagesMethodTest {
     public void setMessagesShouldReturnAttachmentsWhenMessageHasAttachment() throws Exception {
         String bytes1 = "attachment";
         String bytes2 = "attachment2";
-        Attachment uploadedAttachment1 = uploadAttachment(OCTET_CONTENT_TYPE, bytes1.getBytes(StandardCharsets.UTF_8));
-        Attachment uploadedAttachment2 = uploadAttachment(OCTET_CONTENT_TYPE, bytes2.getBytes(StandardCharsets.UTF_8));
+        AttachmentMetadata uploadedAttachment1 = uploadAttachment(OCTET_CONTENT_TYPE, bytes1.getBytes(StandardCharsets.UTF_8));
+        AttachmentMetadata uploadedAttachment2 = uploadAttachment(OCTET_CONTENT_TYPE, bytes2.getBytes(StandardCharsets.UTF_8));
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -4034,9 +4033,9 @@ public abstract class SetMessagesMethodTest {
         String bytes1 = "attachment";
         String bytes2 = "attachment2";
         String bytes3 = "attachment3";
-        Attachment uploadedAttachment1 = uploadAttachment(OCTET_CONTENT_TYPE, bytes1.getBytes(StandardCharsets.UTF_8));
-        Attachment uploadedAttachment2 = uploadAttachment(OCTET_CONTENT_TYPE, bytes2.getBytes(StandardCharsets.UTF_8));
-        Attachment uploadedAttachment3 = uploadAttachment(OCTET_CONTENT_TYPE, bytes3.getBytes(StandardCharsets.UTF_8));
+        AttachmentMetadata uploadedAttachment1 = uploadAttachment(OCTET_CONTENT_TYPE, bytes1.getBytes(StandardCharsets.UTF_8));
+        AttachmentMetadata uploadedAttachment2 = uploadAttachment(OCTET_CONTENT_TYPE, bytes2.getBytes(StandardCharsets.UTF_8));
+        AttachmentMetadata uploadedAttachment3 = uploadAttachment(OCTET_CONTENT_TYPE, bytes3.getBytes(StandardCharsets.UTF_8));
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -4111,9 +4110,9 @@ public abstract class SetMessagesMethodTest {
         String bytes1 = "attachment";
         String bytes2 = "attachment2";
         String bytes3 = "attachment3";
-        Attachment uploadedAttachment1 = uploadAttachment(OCTET_CONTENT_TYPE, bytes1.getBytes(StandardCharsets.UTF_8));
-        Attachment uploadedAttachment2 = uploadAttachment(OCTET_CONTENT_TYPE, bytes2.getBytes(StandardCharsets.UTF_8));
-        Attachment uploadedAttachment3 = uploadAttachment(OCTET_CONTENT_TYPE, bytes3.getBytes(StandardCharsets.UTF_8));
+        AttachmentMetadata uploadedAttachment1 = uploadAttachment(OCTET_CONTENT_TYPE, bytes1.getBytes(StandardCharsets.UTF_8));
+        AttachmentMetadata uploadedAttachment2 = uploadAttachment(OCTET_CONTENT_TYPE, bytes2.getBytes(StandardCharsets.UTF_8));
+        AttachmentMetadata uploadedAttachment3 = uploadAttachment(OCTET_CONTENT_TYPE, bytes3.getBytes(StandardCharsets.UTF_8));
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -4201,7 +4200,7 @@ public abstract class SetMessagesMethodTest {
             .body(thirdAttachment + ".name", equalTo("进化还是不.png"));
     }
 
-    private Attachment uploadAttachment(String contentType, byte[] content) {
+    private AttachmentMetadata uploadAttachment(String contentType, byte[] content) {
         JsonPath json = with()
             .header("Authorization", accessToken.asString())
             .contentType(contentType)
@@ -4212,14 +4211,14 @@ public abstract class SetMessagesMethodTest {
             .body()
             .jsonPath();
 
-        return Attachment.builder()
+        return AttachmentMetadata.builder()
             .attachmentId(AttachmentId.from(json.getString("blobId")))
             .size(json.getLong("size"))
             .type(json.getString("type"))
             .build();
     }
 
-    private Attachment uploadTextAttachment(String contentType, String content) {
+    private AttachmentMetadata uploadTextAttachment(String contentType, String content) {
         JsonPath json = with()
             .header("Authorization", accessToken.asString())
             .contentType(contentType)
@@ -4230,7 +4229,7 @@ public abstract class SetMessagesMethodTest {
             .body()
             .jsonPath();
 
-        return Attachment.builder()
+        return AttachmentMetadata.builder()
             .attachmentId(AttachmentId.from(json.getString("blobId")))
             .size(json.getLong("size"))
             .type(json.getString("type"))
@@ -4246,7 +4245,7 @@ public abstract class SetMessagesMethodTest {
             50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,
             100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127};
 
-        Attachment uploadedAttachment = uploadAttachment(OCTET_CONTENT_TYPE, rawBytes);
+        AttachmentMetadata uploadedAttachment = uploadAttachment(OCTET_CONTENT_TYPE, rawBytes);
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -4318,7 +4317,7 @@ public abstract class SetMessagesMethodTest {
     @Test
     public void attachmentsShouldBeRetrievedWhenChainingSetMessagesAndGetMessagesTextAttachment() throws Exception {
         byte[] rawBytes = ByteStreams.toByteArray(new ZeroedInputStream(_1MB));
-        Attachment uploadedAttachment = uploadAttachment(OCTET_CONTENT_TYPE, rawBytes);
+        AttachmentMetadata uploadedAttachment = uploadAttachment(OCTET_CONTENT_TYPE, rawBytes);
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -4412,7 +4411,7 @@ public abstract class SetMessagesMethodTest {
             "  <body>attachment</body>\n" + // needed indentation, else restassured is adding some
             "</html>";
         String contentType = "text/html; charset=UTF-8";
-        Attachment uploadedAttachment = uploadTextAttachment(contentType, text);
+        AttachmentMetadata uploadedAttachment = uploadTextAttachment(contentType, text);
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -4488,7 +4487,7 @@ public abstract class SetMessagesMethodTest {
             "  <body>attachment</body>\n" + // needed indentation, else restassured is adding some
             "</html>";
         String contentType = "text/html; charset=UTF-8";
-        Attachment uploadedAttachment = uploadTextAttachment(contentType, text);
+        AttachmentMetadata uploadedAttachment = uploadTextAttachment(contentType, text);
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -4574,7 +4573,7 @@ public abstract class SetMessagesMethodTest {
     public void attachmentAndEmptyBodyShouldBeRetrievedWhenChainingSetMessagesAndGetMessagesWithTextAttachmentWithoutMailBody() throws Exception {
         String text = "some text";
         String contentType = "text/plain; charset=UTF-8";
-        Attachment uploadedAttachment = uploadTextAttachment(contentType, text);
+        AttachmentMetadata uploadedAttachment = uploadTextAttachment(contentType, text);
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -5334,7 +5333,7 @@ public abstract class SetMessagesMethodTest {
     public void setMessagesShouldCreateMessageWhenSendingMessageWithNonIndexableAttachment() throws Exception {
         byte[] bytes = ClassLoaderUtils.getSystemResourceAsByteArray("attachment/nonIndexableAttachment.html");
         String contentType = "text/html";
-        Attachment uploadedAttachment = uploadAttachment(contentType, bytes);
+        AttachmentMetadata uploadedAttachment = uploadAttachment(contentType, bytes);
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -5383,7 +5382,7 @@ public abstract class SetMessagesMethodTest {
     public void messageWithNonIndexableAttachmentShouldBeRetrievedWhenChainingSetMessagesAndGetMessages() throws Exception {
         byte[] bytes = ClassLoaderUtils.getSystemResourceAsByteArray("attachment/nonIndexableAttachment.html");
         String contentType = "text/html";
-        Attachment uploadedAttachment = uploadAttachment(contentType, bytes);
+        AttachmentMetadata uploadedAttachment = uploadAttachment(contentType, bytes);
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -5441,7 +5440,7 @@ public abstract class SetMessagesMethodTest {
     public void messageWithNonIndexableAttachmentShouldHaveItsEmailBodyIndexed() throws Exception {
         byte[] bytes = ClassLoaderUtils.getSystemResourceAsByteArray("attachment/nonIndexableAttachment.html");
         String contentType = "text/html";
-        Attachment uploadedAttachment = uploadAttachment(contentType, bytes);
+        AttachmentMetadata uploadedAttachment = uploadAttachment(contentType, bytes);
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -5494,9 +5493,9 @@ public abstract class SetMessagesMethodTest {
     @Test
     public void setMessagesShouldReturnAttachmentsWhenMessageHasInlinedAttachmentButNoCid() throws Exception {
         String bytes = "attachment";
-        Attachment uploadedAttachment1 = uploadAttachment(OCTET_CONTENT_TYPE, bytes.getBytes(StandardCharsets.UTF_8));
+        AttachmentMetadata uploadedAttachment1 = uploadAttachment(OCTET_CONTENT_TYPE, bytes.getBytes(StandardCharsets.UTF_8));
         String bytes2 = "attachment2";
-        Attachment uploadedAttachment2 = uploadAttachment(OCTET_CONTENT_TYPE, bytes2.getBytes(StandardCharsets.UTF_8));
+        AttachmentMetadata uploadedAttachment2 = uploadAttachment(OCTET_CONTENT_TYPE, bytes2.getBytes(StandardCharsets.UTF_8));
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MIMEMessageConverter.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MIMEMessageConverter.java
index e83b561..d5690f8 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MIMEMessageConverter.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MIMEMessageConverter.java
@@ -38,7 +38,7 @@ import org.apache.james.jmap.draft.model.message.view.MessageViewFactory;
 import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mime4j.codec.DecodeMonitor;
 import org.apache.james.mime4j.codec.EncoderUtil;
 import org.apache.james.mime4j.codec.EncoderUtil.Usage;
@@ -113,7 +113,7 @@ public class MIMEMessageConverter {
         this.bodyFactory = new BasicBodyFactory();
     }
 
-    public byte[] convert(ValueWithId.CreationMessageEntry creationMessageEntry, ImmutableList<MessageAttachment> messageAttachments, MailboxSession session) {
+    public byte[] convert(ValueWithId.CreationMessageEntry creationMessageEntry, ImmutableList<MessageAttachmentMetadata> messageAttachments, MailboxSession session) {
         return asBytes(convertToMime(creationMessageEntry, messageAttachments, session));
     }
 
@@ -125,7 +125,7 @@ public class MIMEMessageConverter {
         }
     }
 
-    @VisibleForTesting Message convertToMime(ValueWithId.CreationMessageEntry creationMessageEntry, ImmutableList<MessageAttachment> messageAttachments, MailboxSession session) {
+    @VisibleForTesting Message convertToMime(ValueWithId.CreationMessageEntry creationMessageEntry, ImmutableList<MessageAttachmentMetadata> messageAttachments, MailboxSession session) {
         if (creationMessageEntry == null || creationMessageEntry.getValue() == null) {
             throw new IllegalArgumentException("creationMessageEntry is either null or has null message");
         }
@@ -141,7 +141,7 @@ public class MIMEMessageConverter {
         return messageBuilder.build();
     }
 
-    private void buildMimeHeaders(Message.Builder messageBuilder, CreationMessage newMessage, ImmutableList<MessageAttachment> messageAttachments) {
+    private void buildMimeHeaders(Message.Builder messageBuilder, CreationMessage newMessage, ImmutableList<MessageAttachmentMetadata> messageAttachments) {
         Optional<Mailbox> fromAddress = newMessage.getFrom().filter(DraftEmailer::hasValidEmail).map(this::convertEmailToMimeHeader);
         fromAddress.ifPresent(messageBuilder::setFrom);
         fromAddress.ifPresent(messageBuilder::setSender);
@@ -195,12 +195,12 @@ public class MIMEMessageConverter {
         messageBuilder.addField(parser.parse(rawField, DecodeMonitor.SILENT));
     }
 
-    private boolean isMultipart(CreationMessage newMessage, ImmutableList<MessageAttachment> messageAttachments) {
+    private boolean isMultipart(CreationMessage newMessage, ImmutableList<MessageAttachmentMetadata> messageAttachments) {
         return (newMessage.getTextBody().isPresent() && newMessage.getHtmlBody().isPresent())
                 || hasAttachment(messageAttachments);
     }
 
-    private boolean hasAttachment(ImmutableList<MessageAttachment> messageAttachments) {
+    private boolean hasAttachment(ImmutableList<MessageAttachmentMetadata> messageAttachments) {
         return !messageAttachments.isEmpty();
     }
 
@@ -211,7 +211,7 @@ public class MIMEMessageConverter {
         return bodyFactory.textBody(body, StandardCharsets.UTF_8);
     }
 
-    private Multipart createMultipart(CreationMessage newMessage, ImmutableList<MessageAttachment> messageAttachments, MailboxSession session) {
+    private Multipart createMultipart(CreationMessage newMessage, ImmutableList<MessageAttachmentMetadata> messageAttachments, MailboxSession session) {
         try {
             if (hasAttachment(messageAttachments)) {
                 return createMultipartWithAttachments(newMessage, messageAttachments, session);
@@ -224,12 +224,12 @@ public class MIMEMessageConverter {
         }
     }
 
-    private Multipart createMultipartWithAttachments(CreationMessage newMessage, ImmutableList<MessageAttachment> messageAttachments, MailboxSession session) throws IOException {
+    private Multipart createMultipartWithAttachments(CreationMessage newMessage, ImmutableList<MessageAttachmentMetadata> messageAttachments, MailboxSession session) throws IOException {
         MultipartBuilder mixedMultipartBuilder = MultipartBuilder.create(MIXED_SUB_TYPE);
-        List<MessageAttachment> inlineAttachments = messageAttachments.stream()
-            .filter(MessageAttachment::isInline)
+        List<MessageAttachmentMetadata> inlineAttachments = messageAttachments.stream()
+            .filter(MessageAttachmentMetadata::isInline)
             .collect(Guavate.toImmutableList());
-        List<MessageAttachment> besideAttachments = messageAttachments.stream()
+        List<MessageAttachmentMetadata> besideAttachments = messageAttachments.stream()
             .filter(attachment -> !attachment.isInline())
             .collect(Guavate.toImmutableList());
 
@@ -244,7 +244,7 @@ public class MIMEMessageConverter {
         return mixedMultipartBuilder.build();
     }
 
-    private Message relatedInnerMessage(CreationMessage newMessage, List<MessageAttachment> inlines, MailboxSession session) throws IOException {
+    private Message relatedInnerMessage(CreationMessage newMessage, List<MessageAttachmentMetadata> inlines, MailboxSession session) throws IOException {
         MultipartBuilder relatedMultipart = MultipartBuilder.create(RELATED_SUB_TYPE);
         addBody(newMessage, relatedMultipart);
 
@@ -254,7 +254,7 @@ public class MIMEMessageConverter {
             .build();
     }
 
-    private MultipartBuilder addAttachments(List<MessageAttachment> messageAttachments,
+    private MultipartBuilder addAttachments(List<MessageAttachmentMetadata> messageAttachments,
                                             MultipartBuilder multipartBuilder, MailboxSession session) {
         messageAttachments.forEach(addAttachment(multipartBuilder, session));
 
@@ -298,7 +298,7 @@ public class MIMEMessageConverter {
         }
     }
 
-    private Consumer<MessageAttachment> addAttachment(MultipartBuilder builder, MailboxSession session) {
+    private Consumer<MessageAttachmentMetadata> addAttachment(MultipartBuilder builder, MailboxSession session) {
         return att -> { 
             try {
                 builder.addBodyPart(attachmentBodyPart(att, session));
@@ -309,7 +309,7 @@ public class MIMEMessageConverter {
         };
     }
 
-    private BodyPart attachmentBodyPart(MessageAttachment att, MailboxSession session) throws IOException, AttachmentNotFoundException {
+    private BodyPart attachmentBodyPart(MessageAttachmentMetadata att, MailboxSession session) throws IOException, AttachmentNotFoundException {
         try (InputStream attachmentStream = attachmentContentLoader.load(att.getAttachment(), session)) {
             BodyPartBuilder builder = BodyPartBuilder.create()
                 .use(bodyFactory)
@@ -322,13 +322,13 @@ public class MIMEMessageConverter {
         }
     }
 
-    private void contentId(BodyPartBuilder builder, MessageAttachment att) {
+    private void contentId(BodyPartBuilder builder, MessageAttachmentMetadata att) {
         if (att.getCid().isPresent()) {
             builder.setField(new RawField("Content-ID", att.getCid().get().getValue()));
         }
     }
 
-    private ContentTypeField contentTypeField(MessageAttachment att) {
+    private ContentTypeField contentTypeField(MessageAttachmentMetadata att) {
         Builder<String, String> parameters = ImmutableMap.builder();
         if (att.getName().isPresent()) {
             parameters.put("name", encode(att.getName().get()));
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageAppender.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageAppender.java
index f816549..c7f60f6 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageAppender.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageAppender.java
@@ -45,7 +45,7 @@ import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.Cid;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mime4j.dom.Message;
 import org.apache.james.mime4j.message.DefaultMessageWriter;
 import org.apache.james.util.OptionalUtils;
@@ -78,7 +78,7 @@ public class MessageAppender {
                                                         List<MailboxId> targetMailboxes,
                                                         MailboxSession session) throws MailboxException {
         Preconditions.checkArgument(!targetMailboxes.isEmpty());
-        ImmutableList<MessageAttachment> messageAttachments = getMessageAttachments(session, createdEntry.getValue().getAttachments());
+        ImmutableList<MessageAttachmentMetadata> messageAttachments = getMessageAttachments(session, createdEntry.getValue().getAttachments());
         byte[] messageContent = mimeMessageConverter.convert(createdEntry, messageAttachments, session);
         SharedByteArrayInputStream content = new SharedByteArrayInputStream(messageContent);
         Date internalDate = Date.from(createdEntry.getValue().getDate().toInstant());
@@ -147,17 +147,17 @@ public class MessageAppender {
         return message.getKeywords().asFlags();
     }
 
-    private ImmutableList<MessageAttachment> getMessageAttachments(MailboxSession session, ImmutableList<Attachment> attachments) throws MailboxException {
-        ThrowingFunction<Attachment, Optional<MessageAttachment>> toMessageAttachment = att -> messageAttachment(session, att);
+    private ImmutableList<MessageAttachmentMetadata> getMessageAttachments(MailboxSession session, ImmutableList<Attachment> attachments) throws MailboxException {
+        ThrowingFunction<Attachment, Optional<MessageAttachmentMetadata>> toMessageAttachment = att -> messageAttachment(session, att);
         return attachments.stream()
             .map(Throwing.function(toMessageAttachment).sneakyThrow())
             .flatMap(OptionalUtils::toStream)
             .collect(Guavate.toImmutableList());
     }
 
-    private Optional<MessageAttachment> messageAttachment(MailboxSession session, Attachment attachment) throws MailboxException {
+    private Optional<MessageAttachmentMetadata> messageAttachment(MailboxSession session, Attachment attachment) throws MailboxException {
         try {
-            return Optional.of(MessageAttachment.builder()
+            return Optional.of(MessageAttachmentMetadata.builder()
                 .attachment(attachmentManager.getAttachment(AttachmentId.from(attachment.getBlobId().getRawValue()), session))
                 .name(attachment.getName().orElse(null))
                 .cid(attachment.getCid().map(Cid::from).orElse(null))
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactory.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactory.java
index 0f974bc..027090a 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactory.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactory.java
@@ -46,7 +46,7 @@ import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Cid;
 import org.apache.james.mailbox.model.FetchGroup;
 import org.apache.james.mailbox.model.MailboxId;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageResult;
 import org.apache.james.mime4j.dom.Message;
@@ -200,13 +200,13 @@ public class MessageFullViewFactory implements MessageViewFactory<MessageFullVie
             .orElse(messageContent.getTextBody());
     }
     
-    private List<Attachment> getAttachments(List<MessageAttachment> attachments) {
+    private List<Attachment> getAttachments(List<MessageAttachmentMetadata> attachments) {
         return attachments.stream()
                 .map(this::fromMailboxAttachment)
                 .collect(Guavate.toImmutableList());
     }
 
-    private Attachment fromMailboxAttachment(MessageAttachment attachment) {
+    private Attachment fromMailboxAttachment(MessageAttachmentMetadata attachment) {
         return Attachment.builder()
                     .blobId(BlobId.of(attachment.getAttachmentId().getId()))
                     .type(attachment.getAttachment().getType())
@@ -243,7 +243,7 @@ public class MessageFullViewFactory implements MessageViewFactory<MessageFullVie
             private Instant internalDate;
             private InputStream content;
             private SharedInputStream sharedContent;
-            private List<MessageAttachment> attachments;
+            private List<MessageAttachmentMetadata> attachments;
             private Set<MailboxId> mailboxIds = Sets.newHashSet();
             private MessageId messageId;
 
@@ -277,7 +277,7 @@ public class MessageFullViewFactory implements MessageViewFactory<MessageFullVie
                 return this;
             }
             
-            public Builder attachments(List<MessageAttachment> attachments) {
+            public Builder attachments(List<MessageAttachmentMetadata> attachments) {
                 this.attachments = attachments;
                 return this;
             }
@@ -316,7 +316,7 @@ public class MessageFullViewFactory implements MessageViewFactory<MessageFullVie
         private final Instant internalDate;
         private final InputStream content;
         private final SharedInputStream sharedContent;
-        private final List<MessageAttachment> attachments;
+        private final List<MessageAttachmentMetadata> attachments;
         private final Set<MailboxId> mailboxIds;
         private final MessageId messageId;
 
@@ -326,7 +326,7 @@ public class MessageFullViewFactory implements MessageViewFactory<MessageFullVie
                                     Instant internalDate,
                                     InputStream content,
                                     SharedInputStream sharedContent,
-                                    List<MessageAttachment> attachments,
+                                    List<MessageAttachmentMetadata> attachments,
                                     Set<MailboxId> mailboxIds,
                                     MessageId messageId) {
             this.uid = uid;
@@ -365,7 +365,7 @@ public class MessageFullViewFactory implements MessageViewFactory<MessageFullVie
             return content;
         }
 
-        public List<MessageAttachment> getAttachments() {
+        public List<MessageAttachmentMetadata> getAttachments() {
             return attachments;
         }
 
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/MIMEMessageConverterTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/MIMEMessageConverterTest.java
index 8a8f83b..efca590 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/MIMEMessageConverterTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/MIMEMessageConverterTest.java
@@ -40,8 +40,9 @@ import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 import org.apache.james.mailbox.model.Cid;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mime4j.codec.EncoderUtil;
 import org.apache.james.mime4j.codec.EncoderUtil.Usage;
 import org.apache.james.mime4j.dom.Entity;
@@ -614,8 +615,8 @@ class MIMEMessageConverterTest {
             String text = "123456";
             TextBody expectedBody = new BasicBodyFactory().textBody(text.getBytes(), StandardCharsets.UTF_8);
             AttachmentId blodId = AttachmentId.from("blodId");
-            MessageAttachment attachment = MessageAttachment.builder()
-                .attachment(org.apache.james.mailbox.model.Attachment.builder()
+            MessageAttachmentMetadata attachment = MessageAttachmentMetadata.builder()
+                .attachment(AttachmentMetadata.builder()
                     .attachmentId(blodId)
                     .size(text.getBytes().length)
                     .type(expectedMimeType)
@@ -663,8 +664,8 @@ class MIMEMessageConverterTest {
             String expectedMimeType = "image/png";
             String text = "123456";
             TextBody expectedAttachmentBody = new BasicBodyFactory().textBody(text.getBytes(), StandardCharsets.UTF_8);
-            MessageAttachment attachment = MessageAttachment.builder()
-                .attachment(org.apache.james.mailbox.model.Attachment.builder()
+            MessageAttachmentMetadata attachment = MessageAttachmentMetadata.builder()
+                .attachment(AttachmentMetadata.builder()
                     .attachmentId(AttachmentId.from("blodId"))
                     .size(text.getBytes().length)
                     .type(expectedMimeType)
@@ -715,7 +716,7 @@ class MIMEMessageConverterTest {
                     .build();
 
             // When
-            ImmutableList<MessageAttachment> attachments = ImmutableList.of();
+            ImmutableList<MessageAttachmentMetadata> attachments = ImmutableList.of();
             byte[] convert = sut.convert(new ValueWithId.CreationMessageEntry(
                     CreationMessageId.of("user|mailbox|1"), testMessage), attachments, session);
 
@@ -743,9 +744,9 @@ class MIMEMessageConverterTest {
             String text = "123456";
             String name = "ديناصور.png";
             String expectedName = EncoderUtil.encodeEncodedWord(name, Usage.TEXT_TOKEN);
-            MessageAttachment attachment = MessageAttachment.builder()
+            MessageAttachmentMetadata attachment = MessageAttachmentMetadata.builder()
                 .name(name)
-                .attachment(org.apache.james.mailbox.model.Attachment.builder()
+                .attachment(AttachmentMetadata.builder()
                     .attachmentId(AttachmentId.from("blodId"))
                     .size(text.getBytes().length)
                     .type(expectedMimeType)
@@ -782,9 +783,9 @@ class MIMEMessageConverterTest {
                 .build();
 
             String text = "123456";
-            MessageAttachment attachment = MessageAttachment.builder()
+            MessageAttachmentMetadata attachment = MessageAttachmentMetadata.builder()
                 .name("ديناصور.png")
-                .attachment(org.apache.james.mailbox.model.Attachment.builder()
+                .attachment(AttachmentMetadata.builder()
                     .attachmentId(AttachmentId.from("blodId"))
                     .size(text.getBytes().length)
                     .type("image/png")
@@ -815,9 +816,9 @@ class MIMEMessageConverterTest {
                 .build();
 
             String text = "123456";
-            MessageAttachment attachment = MessageAttachment.builder()
+            MessageAttachmentMetadata attachment = MessageAttachmentMetadata.builder()
                 .name("ديناصور.png")
-                .attachment(org.apache.james.mailbox.model.Attachment.builder()
+                .attachment(AttachmentMetadata.builder()
                     .attachmentId(AttachmentId.from("blodId"))
                     .size(text.getBytes().length)
                     .type("image/png")
@@ -848,9 +849,9 @@ class MIMEMessageConverterTest {
                 .build();
 
             String text = "123456";
-            MessageAttachment attachment = MessageAttachment.builder()
+            MessageAttachmentMetadata attachment = MessageAttachmentMetadata.builder()
                 .name("ديناصور.png")
-                .attachment(org.apache.james.mailbox.model.Attachment.builder()
+                .attachment(AttachmentMetadata.builder()
                     .attachmentId(AttachmentId.from("blodId"))
                     .size(text.getBytes().length)
                     .type("image/png")
@@ -883,9 +884,9 @@ class MIMEMessageConverterTest {
 
             String name = "ديناصور.png";
             String text = "123456";
-            MessageAttachment attachment = MessageAttachment.builder()
+            MessageAttachmentMetadata attachment = MessageAttachmentMetadata.builder()
                 .name(name)
-                .attachment(org.apache.james.mailbox.model.Attachment.builder()
+                .attachment(AttachmentMetadata.builder()
                     .attachmentId(AttachmentId.from("blodId"))
                     .size(text.getBytes().length)
                     .type("image/png")
@@ -920,9 +921,9 @@ class MIMEMessageConverterTest {
                 .build();
 
             String text = "inline data";
-            MessageAttachment inline = MessageAttachment.builder()
+            MessageAttachmentMetadata inline = MessageAttachmentMetadata.builder()
                 .name("ديناصور.png")
-                .attachment(org.apache.james.mailbox.model.Attachment.builder()
+                .attachment(AttachmentMetadata.builder()
                     .attachmentId(AttachmentId.from("blodId"))
                     .size(text.getBytes().length)
                     .type("image/png")
@@ -935,9 +936,9 @@ class MIMEMessageConverterTest {
 
 
             String text2 = "attachment data";
-            MessageAttachment attachment = MessageAttachment.builder()
+            MessageAttachmentMetadata attachment = MessageAttachmentMetadata.builder()
                 .name("att.pdf")
-                .attachment(org.apache.james.mailbox.model.Attachment.builder()
+                .attachment(AttachmentMetadata.builder()
                     .attachmentId(AttachmentId.from("blodId2"))
                     .size(text2.getBytes().length)
                     .type("image/png")
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java
index 48846ea..02b67d2 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java
@@ -60,12 +60,13 @@ import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.inmemory.InMemoryMailboxManager;
 import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.AttachmentMetadata;
 import org.apache.james.mailbox.model.Cid;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.FetchGroup;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageAttachmentMetadata;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.MessageResult;
@@ -493,8 +494,8 @@ class MessageFullViewFactoryTest {
                 .size(0)
                 .internalDate(INTERNAL_DATE)
                 .content(ClassLoader.getSystemResourceAsStream("spamMail.eml"))
-                .attachments(ImmutableList.of(MessageAttachment.builder()
-                        .attachment(org.apache.james.mailbox.model.Attachment.builder()
+                .attachments(ImmutableList.of(MessageAttachmentMetadata.builder()
+                        .attachment(AttachmentMetadata.builder()
                                 .attachmentId(AttachmentId.from(blodId.getRawValue()))
                                 .size(payload.length())
                                 .type(type)


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


[james-project] 28/37: JAMES-2997 step #8 Stop relying on Attachment byte array in AttachmentMapper::storeAttachmentsForMessage

Posted by bt...@apache.org.
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 d260409bde3ececdcd239d32ad5c6d7b19d5e611
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Feb 4 11:59:01 2020 +0700

    JAMES-2997 step #8 Stop relying on Attachment byte array in AttachmentMapper::storeAttachmentsForMessage
---
 .../james/mailbox/model/ParsedAttachment.java      | 16 +++++----------
 .../cassandra/mail/CassandraAttachmentMapper.java  |  6 +++---
 .../inmemory/mail/InMemoryAttachmentMapper.java    | 24 +++++++++-------------
 .../store/mail/model/impl/MessageParser.java       | 10 ++-------
 .../store/mail/model/AttachmentMapperTest.java     |  8 ++++----
 .../model/MessageWithAttachmentMapperTest.java     |  7 +++----
 .../store/mail/model/impl/MessageParserTest.java   |  3 ++-
 7 files changed, 29 insertions(+), 45 deletions(-)

diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java
index 96dd66d..7c269e5 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java
@@ -20,12 +20,8 @@
 package org.apache.james.mailbox.model;
 
 import java.io.IOException;
-import java.io.InputStream;
 import java.util.Optional;
 
-import org.apache.james.util.io.InputStreamConsummer;
-import org.apache.james.util.io.SizeInputStream;
-
 public class ParsedAttachment {
     interface Builder {
         @FunctionalInterface
@@ -35,7 +31,7 @@ public class ParsedAttachment {
 
         @FunctionalInterface
         interface RequireContent {
-            RequireName content(InputStream stream);
+            RequireName content(byte[] bytes);
         }
 
         @FunctionalInterface
@@ -79,12 +75,12 @@ public class ParsedAttachment {
     }
 
     private final String contentType;
-    private final InputStream content;
+    private final byte[] content;
     private final Optional<String> name;
     private final Optional<Cid> cid;
     private final boolean isInline;
 
-    private ParsedAttachment(String contentType, InputStream content, Optional<String> name, Optional<Cid> cid, boolean isInline) {
+    private ParsedAttachment(String contentType, byte[] content, Optional<String> name, Optional<Cid> cid, boolean isInline) {
         this.contentType = contentType;
         this.content = content;
         this.name = name;
@@ -96,7 +92,7 @@ public class ParsedAttachment {
         return contentType;
     }
 
-    public InputStream getContent() {
+    public byte[] getContent() {
         return content;
     }
 
@@ -126,13 +122,11 @@ public class ParsedAttachment {
     }
 
     public MessageAttachment asMessageAttachment(AttachmentId attachmentId) throws IOException {
-        SizeInputStream sizeInputStream = new SizeInputStream(content);
-        InputStreamConsummer.consume(sizeInputStream);
         return MessageAttachment.builder()
             .attachment(Attachment.builder()
                 .attachmentId(attachmentId)
                 .type(contentType)
-                .size(sizeInputStream.getSize())
+                .size(content.length)
                 .build())
             .name(name)
             .cid(cid)
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
index 7cd1484..84e6022 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
@@ -148,11 +148,11 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
 
     private Mono<MessageAttachment> storeAttachmentAsync(ParsedAttachment parsedAttachment, MessageId ownerMessageId) {
         AttachmentId attachmentId = AttachmentId.random();
-        SizeInputStream content = new SizeInputStream(parsedAttachment.getContent());
+        byte[] content = parsedAttachment.getContent();
         return Mono.from(blobStore.save(blobStore.getDefaultBucketName(), content, LOW_COST))
-            .map(blobId -> new DAOAttachment(attachmentId, blobId, parsedAttachment.getContentType(), content.getSize()))
+            .map(blobId -> new DAOAttachment(attachmentId, blobId, parsedAttachment.getContentType(), content.length))
             .flatMap(daoAttachment -> storeAttachmentWithIndex(daoAttachment, ownerMessageId))
-            .then(Mono.defer(() -> Mono.just(parsedAttachment.asMessageAttachment(attachmentId, content.getSize()))));
+            .then(Mono.defer(() -> Mono.just(parsedAttachment.asMessageAttachment(attachmentId, content.length))));
     }
 
     private Mono<Void> storeAttachmentWithIndex(DAOAttachment daoAttachment, MessageId ownerMessageId) {
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
index ac192f8..ed3c749 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
@@ -130,20 +130,16 @@ public class InMemoryAttachmentMapper implements AttachmentMapper {
 
     private MessageAttachment storeAttachmentForMessage(MessageId ownerMessageId, ParsedAttachment parsedAttachment) throws MailboxException {
         AttachmentId attachmentId = AttachmentId.random();
-        try {
-            byte[] bytes = IOUtils.toByteArray(parsedAttachment.getContent());
-
-            attachmentsById.put(attachmentId, Attachment.builder()
-                .attachmentId(attachmentId)
-                .type(parsedAttachment.getContentType())
-                .size(bytes.length)
-                .build());
-            attachmentsRawContentById.put(attachmentId, bytes);
-            messageIdsByAttachmentId.put(attachmentId, ownerMessageId);
-            return parsedAttachment.asMessageAttachment(attachmentId, bytes.length);
-        } catch (IOException e) {
-            throw new MailboxException(String.format("Failed to persist attachment %s of message %s", attachmentId, ownerMessageId.serialize()), e);
-        }
+        byte[] bytes = parsedAttachment.getContent();
+
+        attachmentsById.put(attachmentId, Attachment.builder()
+            .attachmentId(attachmentId)
+            .type(parsedAttachment.getContentType())
+            .size(bytes.length)
+            .build());
+        attachmentsRawContentById.put(attachmentId, bytes);
+        messageIdsByAttachmentId.put(attachmentId, ownerMessageId);
+        return parsedAttachment.asMessageAttachment(attachmentId, bytes.length);
     }
 
     @Override
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
index 39a3c75..33d3406 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
@@ -19,7 +19,6 @@
 
 package org.apache.james.mailbox.store.mail.model.impl;
 
-import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -35,7 +34,6 @@ import org.apache.james.mime4j.dom.Body;
 import org.apache.james.mime4j.dom.Entity;
 import org.apache.james.mime4j.dom.Message;
 import org.apache.james.mime4j.dom.Multipart;
-import org.apache.james.mime4j.dom.SingleBody;
 import org.apache.james.mime4j.dom.field.ContentDispositionField;
 import org.apache.james.mime4j.dom.field.ContentIdField;
 import org.apache.james.mime4j.dom.field.ContentTypeField;
@@ -218,15 +216,11 @@ public class MessageParser {
         return readHeader(part, CONTENT_ID, ContentIdField.class).isPresent();
     }
 
-    private InputStream getContent(Body body) throws IOException {
-        if (body instanceof SingleBody) {
-            SingleBody singleBody = (SingleBody) body;
-            return singleBody.getInputStream();
-        }
+    private byte[] getContent(Body body) throws IOException {
         DefaultMessageWriter messageWriter = new DefaultMessageWriter();
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         messageWriter.writeBody(body, out);
-        return new ByteArrayInputStream(out.toByteArray());
+        return out.toByteArray();
     }
 
     private enum Context {
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
index 9299fe3..d63ee0c 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
@@ -158,7 +158,7 @@ public abstract class AttachmentMapperTest {
         MessageId messageId = generateMessageId();
         AttachmentId attachmentId = attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(ParsedAttachment.builder()
             .contentType("content")
-            .content(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)))
+            .content("".getBytes(StandardCharsets.UTF_8))
             .noName()
             .noCid()
             .inline(false)), messageId)
@@ -172,14 +172,14 @@ public abstract class AttachmentMapperTest {
         MessageId messageId1 = generateMessageId();
         AttachmentId attachmentId1 = attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(ParsedAttachment.builder()
             .contentType("content")
-            .content(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)))
+            .content("".getBytes(StandardCharsets.UTF_8))
             .noName()
             .noCid()
             .inline(false)), messageId1)
             .get(0).getAttachmentId();
         attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(ParsedAttachment.builder()
             .contentType("content")
-            .content(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)))
+            .content("".getBytes(StandardCharsets.UTF_8))
             .noName()
             .noCid()
             .inline(false)), generateMessageId())
@@ -217,7 +217,7 @@ public abstract class AttachmentMapperTest {
     void getOwnersShouldReturnEmptyWhenMessageIdReferenced() throws Exception {
         AttachmentId attachmentId = attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(ParsedAttachment.builder()
             .contentType("content")
-            .content(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)))
+            .content("".getBytes(StandardCharsets.UTF_8))
             .noName()
             .noCid()
             .inline(false)), generateMessageId())
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageWithAttachmentMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageWithAttachmentMapperTest.java
index f8d24ba..41269e2 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageWithAttachmentMapperTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageWithAttachmentMapperTest.java
@@ -22,7 +22,6 @@ package org.apache.james.mailbox.store.mail.model;
 import static org.apache.james.mailbox.store.mail.model.MessageAssert.assertThat;
 import static org.assertj.core.api.Assertions.assertThat;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.util.Date;
@@ -83,19 +82,19 @@ public abstract class MessageWithAttachmentMapperTest {
         attachmentsMailbox = createMailbox(MailboxPath.forUser(Username.of("benwa"), "Attachments"));
         ParsedAttachment attachment1 = ParsedAttachment.builder()
             .contentType("content")
-            .content(new ByteArrayInputStream("attachment".getBytes(StandardCharsets.UTF_8)))
+            .content("attachment".getBytes(StandardCharsets.UTF_8))
             .noName()
             .cid(Cid.from("cid"))
             .inline();
         ParsedAttachment attachment2 = ParsedAttachment.builder()
             .contentType("content")
-            .content(new ByteArrayInputStream("attachment2".getBytes(StandardCharsets.UTF_8)))
+            .content("attachment2".getBytes(StandardCharsets.UTF_8))
             .noName()
             .cid(Cid.from("cid"))
             .inline();
         ParsedAttachment attachment3 = ParsedAttachment.builder()
             .contentType("content")
-            .content(new ByteArrayInputStream("attachment3".getBytes(StandardCharsets.UTF_8)))
+            .content("attachment3".getBytes(StandardCharsets.UTF_8))
             .noName()
             .cid(Cid.from("cid"))
             .inline(false);
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
index 32eb1eb..721b8b7 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
@@ -136,7 +136,8 @@ class MessageParserTest {
         List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeTextInlined.eml"));
 
         ParsedAttachment attachment = attachments.get(0);
-        assertThat(attachment.getContent()).hasSameContentAs(ClassLoader.getSystemResourceAsStream("eml/gimp.png"));
+        assertThat(new ByteArrayInputStream(attachment.getContent()))
+            .hasSameContentAs(ClassLoader.getSystemResourceAsStream("eml/gimp.png"));
     }
 
     @Test


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


[james-project] 24/37: JAMES-2997 Renable and relocate search tests

Posted by bt...@apache.org.
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 acf750d6b7e45a23d340fe4b2ff1b54649d261b9
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Jan 21 11:31:20 2020 +0700

    JAMES-2997 Renable and relocate search tests
---
 .../store/{ => search}/SearchUtilsMultipartMixedTest.java  | 13 ++++++-------
 .../mailbox/store/{ => search}/SearchUtilsRFC822Test.java  | 12 +++++-------
 .../james/mailbox/store/{ => search}/SearchUtilsTest.java  | 14 ++++++--------
 3 files changed, 17 insertions(+), 22 deletions(-)

diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsMultipartMixedTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/SearchUtilsMultipartMixedTest.java
similarity index 97%
rename from mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsMultipartMixedTest.java
rename to mailbox/store/src/test/java/org/apache/james/mailbox/store/search/SearchUtilsMultipartMixedTest.java
index 126ff8a..c39e743 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsMultipartMixedTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/SearchUtilsMultipartMixedTest.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.store;
+package org.apache.james.mailbox.store.search;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -27,18 +27,17 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.Locale;
 
+import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.extractor.TextExtractor;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.SearchQuery;
+import org.apache.james.mailbox.store.MessageBuilder;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
-import org.apache.james.mailbox.store.search.MessageSearches;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 class SearchUtilsMultipartMixedTest {
-/*
     static final String SAMPLE_INNER_MAIL_BODY_ONE = "far a modern quill doth come too";
 
     static final String SAMPLE_PART_ONE = "The better angel is a man right fair,\r\n";
@@ -132,7 +131,9 @@ class SearchUtilsMultipartMixedTest {
         SearchQuery query = null; 
         TextExtractor textExtractor = null;
         MailboxSession session = null;
-        messageSearches = new MessageSearches(messages, query, textExtractor, (attachment, ignore) -> attachment.getStream(), session);
+
+        AttachmentContentLoader attachmentContentLoader = null;
+        messageSearches = new MessageSearches(messages, query, textExtractor, attachmentContentLoader, session);
     }
     
 
@@ -229,6 +230,4 @@ class SearchUtilsMultipartMixedTest {
         assertThat(messageSearches.isMatch(SearchQuery
                 .mailContains(SAMPLE_PART_TWO_FIELD), row, recent)).isTrue();
     }
-
- */
 }
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsRFC822Test.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/SearchUtilsRFC822Test.java
similarity index 95%
rename from mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsRFC822Test.java
rename to mailbox/store/src/test/java/org/apache/james/mailbox/store/search/SearchUtilsRFC822Test.java
index c02ff3b..5c33cff 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsRFC822Test.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/SearchUtilsRFC822Test.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.store;
+package org.apache.james.mailbox.store.search;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -27,18 +27,17 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.Locale;
 
+import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.extractor.TextExtractor;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.SearchQuery;
+import org.apache.james.mailbox.store.MessageBuilder;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
-import org.apache.james.mailbox.store.search.MessageSearches;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 class SearchUtilsRFC822Test {
-/*
     static final String FROM_ADDRESS = "Harry <harry@example.org";
 
     static final String SUBJECT_PART = "Mixed";
@@ -72,7 +71,8 @@ class SearchUtilsRFC822Test {
         SearchQuery query = null; 
         TextExtractor textExtractor = null;
         MailboxSession session = null;
-        messageSearches = new MessageSearches(messages, query, textExtractor, (attachment, ignore) -> attachment.getStream(), session);
+        AttachmentContentLoader attachmentContentLoader = null;
+        messageSearches = new MessageSearches(messages, query, textExtractor, attachmentContentLoader, session);
     }
 
 
@@ -127,6 +127,4 @@ class SearchUtilsRFC822Test {
         assertThat(messageSearches.isMatch(SearchQuery.mailContains(SUBJECT_PART),
                 row, recent)).isTrue();
     }
-
- */
 }
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/SearchUtilsTest.java
similarity index 99%
rename from mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java
rename to mailbox/store/src/test/java/org/apache/james/mailbox/store/search/SearchUtilsTest.java
index 579201d..f622d1f 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/SearchUtilsTest.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.store;
+package org.apache.james.mailbox.store.search;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -31,20 +31,19 @@ import java.util.TimeZone;
 
 import javax.mail.Flags;
 
+import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.extractor.TextExtractor;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.model.SearchQuery.AddressType;
 import org.apache.james.mailbox.model.SearchQuery.DateResolution;
+import org.apache.james.mailbox.store.MessageBuilder;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
-import org.apache.james.mailbox.store.search.MessageSearches;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 class SearchUtilsTest {
-/*
     static final String RHUBARD = "Rhubard";
 
     static final String CUSTARD = "Custard";
@@ -87,7 +86,9 @@ class SearchUtilsTest {
         SearchQuery query = null; 
         TextExtractor textExtractor = null;
         MailboxSession session = null;
-        messageSearches = new MessageSearches(messages, query, textExtractor, (attachment, ignore) -> attachment.getStream(), session);
+
+        AttachmentContentLoader attachmentContentLoader = null;
+        messageSearches = new MessageSearches(messages, query, textExtractor, attachmentContentLoader, session);
     }
     
     @Test
@@ -809,7 +810,4 @@ class SearchUtilsTest {
         assertThat(messageSearches.isMatch(SearchQuery.address(AddressType.To, "user-from@domain.org"), row, recent)).isTrue();
         assertThat(messageSearches.isMatch(SearchQuery.address(AddressType.From, "user-from@domain.org"), row, recent)).isFalse();
     }
-
-
- */
 }


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


[james-project] 19/37: JAMES-2997 Renable AttachmentMapperTest

Posted by bt...@apache.org.
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 aad93ebb28fd0f53f6e4e25b5911f4abf3b50790
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Jan 17 17:03:47 2020 +0700

    JAMES-2997 Renable AttachmentMapperTest
---
 .../mail/CassandraAttachmentMapperTest.java        |   3 -
 .../inmemory/mail/MemoryAttachmentMapperTest.java  |   3 -
 .../store/mail/model/AttachmentMapperTest.java     | 294 +++++++--------------
 3 files changed, 100 insertions(+), 200 deletions(-)

diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapperTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapperTest.java
index 4edf53e..8935848 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapperTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapperTest.java
@@ -31,7 +31,6 @@ import org.apache.james.mailbox.store.mail.model.AttachmentMapperTest;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
 class CassandraAttachmentMapperTest extends AttachmentMapperTest {
-/*
     private static final CassandraModule MODULES = CassandraModule.aggregateModules(
         CassandraAttachmentModule.MODULE,
         CassandraBlobModule.MODULE);
@@ -49,6 +48,4 @@ class CassandraAttachmentMapperTest extends AttachmentMapperTest {
     protected MessageId generateMessageId() {
         return new CassandraMessageId.Factory().generate();
     }
-    
- */
 }
diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/MemoryAttachmentMapperTest.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/MemoryAttachmentMapperTest.java
index e3ece02..f65fc8f 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/MemoryAttachmentMapperTest.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/MemoryAttachmentMapperTest.java
@@ -25,7 +25,6 @@ import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.mailbox.store.mail.model.AttachmentMapperTest;
 
 class MemoryAttachmentMapperTest extends AttachmentMapperTest {
-/*
     @Override
     protected AttachmentMapper createAttachmentMapper() {
         return new InMemoryAttachmentMapper();
@@ -35,6 +34,4 @@ class MemoryAttachmentMapperTest extends AttachmentMapperTest {
     protected MessageId generateMessageId() {
         return new InMemoryMessageId.Factory().generate();
     }
-
- */
 }
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
index 93f4c21..9299fe3 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentMapperTest.java
@@ -22,6 +22,7 @@ package org.apache.james.mailbox.store.mail.model;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
+import java.io.ByteArrayInputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.Collection;
 import java.util.List;
@@ -31,7 +32,9 @@ import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
+import org.assertj.core.api.SoftAssertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -40,7 +43,6 @@ import com.google.common.collect.ImmutableList;
 import reactor.core.publisher.Mono;
 
 public abstract class AttachmentMapperTest {
-    /*
     private static final AttachmentId UNKNOWN_ATTACHMENT_ID = AttachmentId.from("unknown");
     private static final Username OWNER = Username.of("owner");
     private static final Username ADDITIONAL_OWNER = Username.of("additionalOwner");
@@ -69,40 +71,43 @@ public abstract class AttachmentMapperTest {
     }
 
     @Test
+    void storeAttachmentForOwnerShouldReturnSuppliedInformation() throws Exception {
+        String content = "content";
+        byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
+
+        Attachment stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
+
+        SoftAssertions.assertSoftly(solftly -> {
+            solftly.assertThat(stored.getSize()).isEqualTo(bytes.length);
+            solftly.assertThat(stored.getType()).isEqualTo(content);
+        });
+    }
+
+    @Test
     void getAttachmentShouldReturnTheAttachmentWhenReferenced() throws Exception {
-        //Given
-        Attachment expected = Attachment.builder()
-                .bytes("payload".getBytes(StandardCharsets.UTF_8))
-                .type("content")
-                .build();
-        AttachmentId attachmentId = expected.getAttachmentId();
-        Mono.from(attachmentMapper.storeAttachmentForOwner(expected, OWNER)).block();
-        //When
-        Attachment attachment = attachmentMapper.getAttachment(attachmentId);
-        //Then
-        assertThat(attachment).isEqualTo(expected);
+        String content = "content";
+        byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
+
+        Attachment stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
+
+        Attachment attachment = attachmentMapper.getAttachment(stored.getAttachmentId());
+
+        SoftAssertions.assertSoftly(solftly -> {
+            solftly.assertThat(attachment.getAttachmentId()).isEqualTo(stored.getAttachmentId());
+            solftly.assertThat(attachment.getSize()).isEqualTo(bytes.length);
+            solftly.assertThat(attachment.getType()).isEqualTo(content);
+        });
     }
 
     @Test
-    void getAttachmentShouldReturnTheAttachmentsWhenMultipleStored() throws Exception {
-        //Given
-        Attachment expected1 = Attachment.builder()
-                .bytes("payload1".getBytes(StandardCharsets.UTF_8))
-                .type("content1")
-                .build();
-        Attachment expected2 = Attachment.builder()
-                .bytes("payload2".getBytes(StandardCharsets.UTF_8))
-                .type("content2")
-                .build();
-        AttachmentId attachmentId1 = expected1.getAttachmentId();
-        AttachmentId attachmentId2 = expected2.getAttachmentId();
-        //When
-        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(expected1, expected2), generateMessageId());
-        //Then
-        Attachment attachment1 = attachmentMapper.getAttachment(attachmentId1);
-        Attachment attachment2 = attachmentMapper.getAttachment(attachmentId2);
-        assertThat(attachment1).isEqualTo(expected1);
-        assertThat(attachment2).isEqualTo(expected2);
+    void loadAttachmentContentShouldReturnStoredContent() throws Exception {
+        String content = "content";
+        byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
+
+        Attachment stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
+
+        assertThat(attachmentMapper.loadAttachmentContent(stored.getAttachmentId()))
+            .hasSameContentAs(new ByteArrayInputStream(bytes));
     }
 
     @Test
@@ -121,24 +126,15 @@ public abstract class AttachmentMapperTest {
     @Test
     void getAttachmentsShouldReturnTheAttachmentsWhenSome() {
         //Given
-        Attachment expected = Attachment.builder()
-                .bytes("payload".getBytes(StandardCharsets.UTF_8))
-                .type("content")
-                .build();
-        AttachmentId attachmentId = expected.getAttachmentId();
-        Mono.from(attachmentMapper.storeAttachmentForOwner(expected, OWNER)).block();
-
-        Attachment expected2 = Attachment.builder()
-                .bytes("payload2".getBytes(StandardCharsets.UTF_8))
-                .type("content")
-                .build();
-        AttachmentId attachmentId2 = expected2.getAttachmentId();
-        Mono.from(attachmentMapper.storeAttachmentForOwner(expected2, OWNER)).block();
-
-        //When
-        List<Attachment> attachments = attachmentMapper.getAttachments(ImmutableList.of(attachmentId, attachmentId2));
-        //Then
-        assertThat(attachments).contains(expected, expected2);
+        String content1 = "content";
+        byte[] bytes1 = "payload".getBytes(StandardCharsets.UTF_8);
+        Attachment stored1 = Mono.from(attachmentMapper.storeAttachmentForOwner(content1, new ByteArrayInputStream(bytes1), OWNER)).block();
+        String content2 = "content";
+        byte[] bytes2 = "payload".getBytes(StandardCharsets.UTF_8);
+        Attachment stored2 = Mono.from(attachmentMapper.storeAttachmentForOwner(content2, new ByteArrayInputStream(bytes2), OWNER)).block();
+
+        assertThat(attachmentMapper.getAttachments(ImmutableList.of(stored1.getAttachmentId(), stored2.getAttachmentId())))
+            .contains(stored1, stored2);
     }
 
     @Test
@@ -150,172 +146,84 @@ public abstract class AttachmentMapperTest {
 
     @Test
     void getOwnerMessageIdsShouldReturnEmptyWhenStoredWithoutMessageId() throws Exception {
-        //Given
-        Attachment attachment = Attachment.builder()
-                .bytes("payload".getBytes(StandardCharsets.UTF_8))
-                .type("content")
-                .build();
-        AttachmentId attachmentId = attachment.getAttachmentId();
-        Mono.from(attachmentMapper.storeAttachmentForOwner(attachment, OWNER)).block();
-        
-        //When
-        Collection<MessageId> messageIds = attachmentMapper.getRelatedMessageIds(attachmentId);
-        //Then
-        assertThat(messageIds).isEmpty();
+        String content = "content";
+        byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
+        Attachment stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
+
+        assertThat(attachmentMapper.getRelatedMessageIds(stored.getAttachmentId())).isEmpty();
     }
 
     @Test
-    void getOwnerMessageIdsShouldReturnMessageIdWhenStoredWithMessageId() throws Exception {
-        //Given
-        Attachment attachment = Attachment.builder()
-                .bytes("payload".getBytes(StandardCharsets.UTF_8))
-                .type("content")
-                .build();
-        AttachmentId attachmentId = attachment.getAttachmentId();
+    void getRelatedMessageIdsShouldReturnMessageIdWhenStoredWithMessageId() throws Exception {
         MessageId messageId = generateMessageId();
-        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment), messageId);
-        
-        //When
-        Collection<MessageId> messageIds = attachmentMapper.getRelatedMessageIds(attachmentId);
-        //Then
-        assertThat(messageIds).containsOnly(messageId);
-    }
+        AttachmentId attachmentId = attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(ParsedAttachment.builder()
+            .contentType("content")
+            .content(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)))
+            .noName()
+            .noCid()
+            .inline(false)), messageId)
+            .get(0).getAttachmentId();
 
-    @Test
-    void getOwnerMessageIdsShouldReturnTwoMessageIdsWhenStoredTwice() throws Exception {
-        //Given
-        Attachment attachment = Attachment.builder()
-                .bytes("payload".getBytes(StandardCharsets.UTF_8))
-                .type("content")
-                .build();
-        AttachmentId attachmentId = attachment.getAttachmentId();
-        MessageId messageId1 = generateMessageId();
-        MessageId messageId2 = generateMessageId();
-        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment), messageId1);
-        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment), messageId2);
-        
-        //When
-        Collection<MessageId> messageIds = attachmentMapper.getRelatedMessageIds(attachmentId);
-        //Then
-        assertThat(messageIds).containsOnly(messageId1, messageId2);
+        assertThat(attachmentMapper.getRelatedMessageIds(attachmentId)).containsOnly(messageId);
     }
 
     @Test
     void getOwnerMessageIdsShouldReturnOnlyMatchingMessageId() throws Exception {
-        //Given
-        Attachment attachment = Attachment.builder()
-                .bytes("payload".getBytes(StandardCharsets.UTF_8))
-                .type("content")
-                .build();
-        Attachment otherAttachment = Attachment.builder()
-                .bytes("something different".getBytes(StandardCharsets.UTF_8))
-                .type("content")
-                .build();
-        AttachmentId attachmentId = attachment.getAttachmentId();
         MessageId messageId1 = generateMessageId();
-        MessageId messageId2 = generateMessageId();
-        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment), messageId1);
-        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(otherAttachment), messageId2);
-        
-        //When
-        Collection<MessageId> messageIds = attachmentMapper.getRelatedMessageIds(attachmentId);
-        //Then
-        assertThat(messageIds).containsOnly(messageId1);
-    }
-
-    @Test
-    void getOwnerMessageIdsShouldReturnOnlyOneMessageIdWhenStoredTwice() throws Exception {
-        //Given
-        Attachment attachment = Attachment.builder()
-                .bytes("payload".getBytes(StandardCharsets.UTF_8))
-                .type("content")
-                .build();
-        AttachmentId attachmentId = attachment.getAttachmentId();
-        MessageId messageId = generateMessageId();
-        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment), messageId);
-        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment), messageId);
-        
-        //When
-        Collection<MessageId> messageIds = attachmentMapper.getRelatedMessageIds(attachmentId);
-        //Then
-        assertThat(messageIds).containsOnly(messageId);
-    }
+        AttachmentId attachmentId1 = attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(ParsedAttachment.builder()
+            .contentType("content")
+            .content(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)))
+            .noName()
+            .noCid()
+            .inline(false)), messageId1)
+            .get(0).getAttachmentId();
+        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(ParsedAttachment.builder()
+            .contentType("content")
+            .content(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)))
+            .noName()
+            .noCid()
+            .inline(false)), generateMessageId())
+            .get(0).getAttachmentId();
 
-    @Test
-    void getOwnerMessageIdsShouldReturnMessageIdForTwoAttachmentsWhenBothStoredAtTheSameTime() throws Exception {
-        //Given
-        Attachment attachment = Attachment.builder()
-                .bytes("payload".getBytes(StandardCharsets.UTF_8))
-                .type("content")
-                .build();
-        Attachment attachment2 = Attachment.builder()
-                .bytes("other payload".getBytes(StandardCharsets.UTF_8))
-                .type("content")
-                .build();
-        AttachmentId attachmentId = attachment.getAttachmentId();
-        AttachmentId attachmentId2 = attachment2.getAttachmentId();
-        MessageId messageId = generateMessageId();
-        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment, attachment2), messageId);
-        
-        //When
-        Collection<MessageId> messageIds = attachmentMapper.getRelatedMessageIds(attachmentId);
-        Collection<MessageId> messageIds2 = attachmentMapper.getRelatedMessageIds(attachmentId2);
-        //Then
-        assertThat(messageIds).isEqualTo(messageIds2);
+        assertThat(attachmentMapper.getRelatedMessageIds(attachmentId1)).containsOnly(messageId1);
     }
 
     @Test
     void getOwnersShouldBeRetrievedWhenExplicitlySpecified() throws Exception {
-        //Given
-        Attachment attachment = Attachment.builder()
-            .bytes("payload".getBytes(StandardCharsets.UTF_8))
-            .type("content")
-            .build();
-
-        AttachmentId attachmentId = attachment.getAttachmentId();
-        Mono.from(attachmentMapper.storeAttachmentForOwner(attachment, OWNER)).block();
-
-        //When
-        Collection<Username> expectedOwners = ImmutableList.of(OWNER);
-        Collection<Username> actualOwners = attachmentMapper.getOwners(attachmentId);
-        //Then
-        assertThat(actualOwners).containsOnlyElementsOf(expectedOwners);
+        String content = "content";
+        byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
+        Attachment stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
+
+        Collection<Username> actualOwners = attachmentMapper.getOwners(stored.getAttachmentId());
+
+        assertThat(actualOwners).containsOnly(OWNER);
     }
 
     @Test
-    void getOwnersShouldReturnEmptyWhenMessageIdReferenced() throws Exception {
-        //Given
-        Attachment attachment = Attachment.builder()
-            .bytes("payload".getBytes(StandardCharsets.UTF_8))
-            .type("content")
-            .build();
+    void getOwnersShouldNotReturnUnrelatedOwners() throws Exception {
+        String content = "content";
+        byte[] bytes = "payload".getBytes(StandardCharsets.UTF_8);
+        Attachment stored = Mono.from(attachmentMapper.storeAttachmentForOwner(content, new ByteArrayInputStream(bytes), OWNER)).block();
+        String content2 = "content";
+        byte[] bytes2 = "payload".getBytes(StandardCharsets.UTF_8);
+        Attachment stored2 = Mono.from(attachmentMapper.storeAttachmentForOwner(content2, new ByteArrayInputStream(bytes2), ADDITIONAL_OWNER)).block();
 
-        AttachmentId attachmentId = attachment.getAttachmentId();
-        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment), generateMessageId());
+        Collection<Username> actualOwners = attachmentMapper.getOwners(stored.getAttachmentId());
 
-        //When
-        Collection<Username> actualOwners = attachmentMapper.getOwners(attachmentId);
-        //Then
-        assertThat(actualOwners).isEmpty();
+        assertThat(actualOwners).containsOnly(OWNER);
     }
 
     @Test
-    void getOwnersShouldReturnAllOwners() throws Exception {
-        //Given
-        Attachment attachment = Attachment.builder()
-            .bytes("payload".getBytes(StandardCharsets.UTF_8))
-            .type("content")
-            .build();
-
-        AttachmentId attachmentId = attachment.getAttachmentId();
-        Mono.from(attachmentMapper.storeAttachmentForOwner(attachment, OWNER)).block();
-        Mono.from(attachmentMapper.storeAttachmentForOwner(attachment, ADDITIONAL_OWNER)).block();
-
-        //When
-        Collection<Username> expectedOwners = ImmutableList.of(OWNER, ADDITIONAL_OWNER);
-        Collection<Username> actualOwners = attachmentMapper.getOwners(attachmentId);
-        //Then
-        assertThat(actualOwners).containsOnlyElementsOf(expectedOwners);
+    void getOwnersShouldReturnEmptyWhenMessageIdReferenced() throws Exception {
+        AttachmentId attachmentId = attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(ParsedAttachment.builder()
+            .contentType("content")
+            .content(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)))
+            .noName()
+            .noCid()
+            .inline(false)), generateMessageId())
+            .get(0).getAttachmentId();
+
+        assertThat(attachmentMapper.getOwners(attachmentId)).isEmpty();
     }
 
     @Test
@@ -324,6 +232,4 @@ public abstract class AttachmentMapperTest {
 
         assertThat(actualOwners).isEmpty();
     }
-
-     */
 }


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


[james-project] 03/37: JAMES-2997 step #1 Rely on AttachmentContentLoader within scanning search

Posted by bt...@apache.org.
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 75e04cd0924d956e27039f69525738052c74b31c
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Mon Dec 9 09:45:27 2019 +0100

    JAMES-2997 step #1 Rely on AttachmentContentLoader within scanning search
---
 ...ntManager.java => AttachmentContentLoader.java} | 19 +++----------
 .../apache/james/mailbox/AttachmentManager.java    | 12 ++++++++-
 .../cassandra/CassandraMailboxManagerProvider.java |  4 ++-
 .../cassandra/CassandraTestSystemFixture.java      |  4 ++-
 .../CassandraMailboxManagerAttachmentTest.java     |  4 ++-
 .../mailbox/jpa/JPAAttachmentContentLoader.java}   | 29 +++++++-------------
 .../mailbox/jpa/JpaMailboxManagerProvider.java     |  2 +-
 .../maildir/MaildirAttachmentContentLoader.java}   | 31 ++++++++--------------
 .../maildir/MaildirMailboxManagerProvider.java     |  2 +-
 .../manager/InMemoryIntegrationResources.java      |  2 +-
 .../store/search/SimpleMessageSearchIndexTest.java |  3 ++-
 .../mailbox/store/StoreAttachmentManager.java      |  9 +++++++
 .../james/mailbox/store/mail/AttachmentMapper.java |  6 +++++
 .../mailbox/store/search/MessageSearches.java      | 26 +++++++++++-------
 .../store/search/SimpleMessageSearchIndex.java     |  9 ++++---
 .../store/SearchUtilsMultipartMixedTest.java       |  5 +++-
 .../james/mailbox/store/SearchUtilsRFC822Test.java |  5 +++-
 .../james/mailbox/store/SearchUtilsTest.java       |  5 +++-
 .../mailbox/store/StoreMailboxManagerTest.java     |  4 ++-
 .../cassandra/host/CassandraHostSystem.java        |  2 +-
 .../mpt/imapmailbox/jpa/host/JPAHostSystem.java    |  4 ++-
 .../maildir/host/MaildirHostSystem.java            |  2 +-
 .../modules/mailbox/CassandraMailboxModule.java    |  2 ++
 .../james/modules/mailbox/JPAMailboxModule.java    |  3 +++
 .../james/modules/mailbox/MemoryMailboxModule.java |  2 ++
 25 files changed, 114 insertions(+), 82 deletions(-)

diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentContentLoader.java
similarity index 60%
copy from mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
copy to mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentContentLoader.java
index 83e0094..1c084d5 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentContentLoader.java
@@ -19,25 +19,14 @@
 
 package org.apache.james.mailbox;
 
-import java.util.Collection;
-import java.util.List;
+import java.io.IOException;
+import java.io.InputStream;
 
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
-import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Attachment;
-import org.apache.james.mailbox.model.AttachmentId;
-import org.apache.james.mailbox.model.MessageId;
-import org.reactivestreams.Publisher;
 
-public interface AttachmentManager {
+public interface AttachmentContentLoader {
 
-    boolean exists(AttachmentId attachmentId, MailboxSession session) throws MailboxException;
+    InputStream load(Attachment attachment, MailboxSession mailboxSession) throws IOException, AttachmentNotFoundException;
 
-    Attachment getAttachment(AttachmentId attachmentId, MailboxSession mailboxSession) throws MailboxException, AttachmentNotFoundException;
-
-    List<Attachment> getAttachments(List<AttachmentId> attachmentIds, MailboxSession mailboxSession) throws MailboxException;
-
-    Publisher<Void> storeAttachment(Attachment attachment, MailboxSession mailboxSession);
-
-    void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId, MailboxSession mailboxSession) throws MailboxException;
 }
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
index 83e0094..a23f2c7 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.mailbox;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.Collection;
 import java.util.List;
 
@@ -29,7 +31,7 @@ import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.MessageId;
 import org.reactivestreams.Publisher;
 
-public interface AttachmentManager {
+public interface AttachmentManager extends AttachmentContentLoader {
 
     boolean exists(AttachmentId attachmentId, MailboxSession session) throws MailboxException;
 
@@ -40,4 +42,12 @@ public interface AttachmentManager {
     Publisher<Void> storeAttachment(Attachment attachment, MailboxSession mailboxSession);
 
     void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId, MailboxSession mailboxSession) throws MailboxException;
+
+    InputStream loadAttachmentContent(AttachmentId attachmentId, MailboxSession mailboxSession) throws AttachmentNotFoundException, IOException;
+
+    @Override
+    default InputStream load(Attachment attachment, MailboxSession mailboxSession) throws IOException, AttachmentNotFoundException {
+        return loadAttachmentContent(attachment.getAttachmentId(), mailboxSession);
+    }
+
 }
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java
index 0c1b448..f2bdb06 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraMailboxManagerProvider.java
@@ -20,6 +20,7 @@
 package org.apache.james.mailbox.cassandra;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.acl.GroupMembershipResolver;
 import org.apache.james.mailbox.acl.MailboxACLResolver;
 import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
@@ -97,7 +98,8 @@ public class CassandraMailboxManagerProvider {
         ListeningCurrentQuotaUpdater quotaUpdater = new ListeningCurrentQuotaUpdater(currentQuotaUpdater, quotaRootResolver, eventBus, storeQuotaManager);
         QuotaComponents quotaComponents = new QuotaComponents(maxQuotaManager, storeQuotaManager, quotaRootResolver);
 
-        MessageSearchIndex index = new SimpleMessageSearchIndex(mapperFactory, mapperFactory, new DefaultTextExtractor());
+        AttachmentContentLoader attachmentContentLoader = null;
+        MessageSearchIndex index = new SimpleMessageSearchIndex(mapperFactory, mapperFactory, new DefaultTextExtractor(), attachmentContentLoader);
 
         CassandraMailboxManager manager = new CassandraMailboxManager(mapperFactory, sessionProvider, new NoMailboxPathLocker(),
             messageParser, messageIdFactory, eventBus, annotationManager, storeRightManager,
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java
index 5acf657..b55ea11 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraTestSystemFixture.java
@@ -22,6 +22,7 @@ package org.apache.james.mailbox.cassandra;
 import static org.mockito.Mockito.mock;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
 import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
@@ -72,7 +73,8 @@ class CassandraTestSystemFixture {
         SessionProviderImpl sessionProvider = new SessionProviderImpl(mock(Authenticator.class), mock(Authorizator.class));
 
         QuotaComponents quotaComponents = QuotaComponents.disabled(sessionProvider, mapperFactory);
-        MessageSearchIndex index = new SimpleMessageSearchIndex(mapperFactory, mapperFactory, new DefaultTextExtractor());
+        AttachmentContentLoader attachmentContentLoader = null;
+        MessageSearchIndex index = new SimpleMessageSearchIndex(mapperFactory, mapperFactory, new DefaultTextExtractor(), attachmentContentLoader);
         CassandraMailboxManager cassandraMailboxManager = new CassandraMailboxManager(mapperFactory, sessionProvider,
             new NoMailboxPathLocker(), new MessageParser(), new CassandraMessageId.Factory(),
             eventBus, annotationManager, storeRightManager, quotaComponents, index, MailboxManagerConfiguration.DEFAULT, PreDeletionHooks.NO_PRE_DELETION_HOOK);
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java
index 63fa332..1c90f3a 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
 import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
@@ -83,7 +84,8 @@ class CassandraMailboxManagerAttachmentTest extends AbstractMailboxManagerAttach
 
         SessionProviderImpl sessionProvider = new SessionProviderImpl(noAuthenticator, noAuthorizator);
         QuotaComponents quotaComponents = QuotaComponents.disabled(sessionProvider, mailboxSessionMapperFactory);
-        MessageSearchIndex index = new SimpleMessageSearchIndex(mailboxSessionMapperFactory, mailboxSessionMapperFactory, new DefaultTextExtractor());
+        AttachmentContentLoader attachmentContentLoader = null;
+        MessageSearchIndex index = new SimpleMessageSearchIndex(mailboxSessionMapperFactory, mailboxSessionMapperFactory, new DefaultTextExtractor(), attachmentContentLoader);
 
         mailboxManager = new CassandraMailboxManager(mailboxSessionMapperFactory, sessionProvider, new NoMailboxPathLocker(), new MessageParser(),
             messageIdFactory, eventBus, annotationManager, storeRightManager, quotaComponents,
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAAttachmentContentLoader.java
similarity index 55%
copy from mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
copy to mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAAttachmentContentLoader.java
index 83e0094..b368084 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAAttachmentContentLoader.java
@@ -17,27 +17,18 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox;
+package org.apache.james.mailbox.jpa;
 
-import java.util.Collection;
-import java.util.List;
+import java.io.InputStream;
 
-import org.apache.james.mailbox.exception.AttachmentNotFoundException;
-import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.commons.lang3.NotImplementedException;
+import org.apache.james.mailbox.AttachmentContentLoader;
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.model.Attachment;
-import org.apache.james.mailbox.model.AttachmentId;
-import org.apache.james.mailbox.model.MessageId;
-import org.reactivestreams.Publisher;
 
-public interface AttachmentManager {
-
-    boolean exists(AttachmentId attachmentId, MailboxSession session) throws MailboxException;
-
-    Attachment getAttachment(AttachmentId attachmentId, MailboxSession mailboxSession) throws MailboxException, AttachmentNotFoundException;
-
-    List<Attachment> getAttachments(List<AttachmentId> attachmentIds, MailboxSession mailboxSession) throws MailboxException;
-
-    Publisher<Void> storeAttachment(Attachment attachment, MailboxSession mailboxSession);
-
-    void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId, MailboxSession mailboxSession) throws MailboxException;
+public class JPAAttachmentContentLoader implements AttachmentContentLoader {
+    @Override
+    public InputStream load(Attachment attachment, MailboxSession mailboxSession) {
+        throw new NotImplementedException("JPA doesn't support loading attachment separately from Message");
+    }
 }
diff --git a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JpaMailboxManagerProvider.java b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JpaMailboxManagerProvider.java
index d881da5..8c23ea2 100644
--- a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JpaMailboxManagerProvider.java
+++ b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/JpaMailboxManagerProvider.java
@@ -68,7 +68,7 @@ public class JpaMailboxManagerProvider {
             LIMIT_ANNOTATIONS, LIMIT_ANNOTATION_SIZE);
         SessionProviderImpl sessionProvider = new SessionProviderImpl(noAuthenticator, noAuthorizator);
         QuotaComponents quotaComponents = QuotaComponents.disabled(sessionProvider, mf);
-        MessageSearchIndex index = new SimpleMessageSearchIndex(mf, mf, new DefaultTextExtractor());
+        MessageSearchIndex index = new SimpleMessageSearchIndex(mf, mf, new DefaultTextExtractor(), new JPAAttachmentContentLoader());
 
         return new OpenJPAMailboxManager(mf, sessionProvider,
             messageParser, new DefaultMessageId.Factory(),
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirAttachmentContentLoader.java
similarity index 55%
copy from mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
copy to mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirAttachmentContentLoader.java
index 83e0094..f3e486a 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
+++ b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirAttachmentContentLoader.java
@@ -17,27 +17,18 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox;
+package org.apache.james.mailbox.maildir;
 
-import java.util.Collection;
-import java.util.List;
+import java.io.InputStream;
 
-import org.apache.james.mailbox.exception.AttachmentNotFoundException;
-import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.commons.lang3.NotImplementedException;
+import org.apache.james.mailbox.AttachmentContentLoader;
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.model.Attachment;
-import org.apache.james.mailbox.model.AttachmentId;
-import org.apache.james.mailbox.model.MessageId;
-import org.reactivestreams.Publisher;
 
-public interface AttachmentManager {
-
-    boolean exists(AttachmentId attachmentId, MailboxSession session) throws MailboxException;
-
-    Attachment getAttachment(AttachmentId attachmentId, MailboxSession mailboxSession) throws MailboxException, AttachmentNotFoundException;
-
-    List<Attachment> getAttachments(List<AttachmentId> attachmentIds, MailboxSession mailboxSession) throws MailboxException;
-
-    Publisher<Void> storeAttachment(Attachment attachment, MailboxSession mailboxSession);
-
-    void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId, MailboxSession mailboxSession) throws MailboxException;
-}
+public class MaildirAttachmentContentLoader implements AttachmentContentLoader {
+    @Override
+    public InputStream load(Attachment attachment, MailboxSession mailboxSession) {
+        throw new NotImplementedException("Maildir doesn't support loading attachment separately from Message");
+    }
+}
\ No newline at end of file
diff --git a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirMailboxManagerProvider.java b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirMailboxManagerProvider.java
index c5da05b..6c02820 100644
--- a/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirMailboxManagerProvider.java
+++ b/mailbox/maildir/src/test/java/org/apache/james/mailbox/maildir/MaildirMailboxManagerProvider.java
@@ -65,7 +65,7 @@ public class MaildirMailboxManagerProvider {
 
         StoreMailboxAnnotationManager annotationManager = new StoreMailboxAnnotationManager(mf, storeRightManager);
         QuotaComponents quotaComponents = QuotaComponents.disabled(sessionProvider, mf);
-        MessageSearchIndex index = new SimpleMessageSearchIndex(mf, mf, new DefaultTextExtractor());
+        MessageSearchIndex index = new SimpleMessageSearchIndex(mf, mf, new DefaultTextExtractor(), new MaildirAttachmentContentLoader());
 
         StoreMailboxManager manager = new StoreMailboxManager(mf, sessionProvider, new JVMMailboxPathLocker(),
             messageParser, new DefaultMessageId.Factory(), annotationManager, eventBus, storeRightManager,
diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryIntegrationResources.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryIntegrationResources.java
index fcb95e7..7d702ff 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryIntegrationResources.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryIntegrationResources.java
@@ -129,7 +129,7 @@ public class InMemoryIntegrationResources implements IntegrationResources<StoreM
             RequirePreDeletionHooks listeningSearchIndex(Function<MailboxManagerPreInstanciationStage, ListeningMessageSearchIndex> searchIndex);
 
             default RequirePreDeletionHooks scanningSearchIndex() {
-                return searchIndex(stage -> new SimpleMessageSearchIndex(stage.mapperFactory, stage.mapperFactory, new DefaultTextExtractor()));
+                return searchIndex(stage -> new SimpleMessageSearchIndex(stage.mapperFactory, stage.mapperFactory, new DefaultTextExtractor(), null));
             }
         }
 
diff --git a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
index 81dc1de..4cadd0e 100644
--- a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
+++ b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
@@ -39,7 +39,8 @@ class SimpleMessageSearchIndexTest extends AbstractMessageSearchIndexTest {
             .searchIndex(preInstanciationStage -> new SimpleMessageSearchIndex(
                 preInstanciationStage.getMapperFactory(),
                 preInstanciationStage.getMapperFactory(),
-                new PDFTextExtractor()))
+                new PDFTextExtractor(),
+                null))
             .noPreDeletionHooks()
             .storeQuotaManager()
             .build();
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
index f32d60b..75e1552 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.mailbox.store;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.Collection;
 import java.util.List;
 
@@ -113,4 +115,11 @@ public class StoreAttachmentManager implements AttachmentManager {
         return attachmentMapperFactory.getAttachmentMapper(mailboxSession).getRelatedMessageIds(attachmentId);
     }
 
+    @Override
+    public InputStream loadAttachmentContent(AttachmentId attachmentId, MailboxSession mailboxSession) throws AttachmentNotFoundException, IOException {
+        if (!userHasAccessToAttachment(attachmentId, mailboxSession)) {
+            throw new AttachmentNotFoundException(attachmentId.getId());
+        }
+        return attachmentMapperFactory.getAttachmentMapper(mailboxSession).loadAttachmentContent(attachmentId);
+    }
 }
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
index ced1530..eb495ae 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
@@ -18,6 +18,8 @@
  ****************************************************************/
 package org.apache.james.mailbox.store.mail;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.Collection;
 import java.util.List;
 
@@ -32,6 +34,10 @@ import org.reactivestreams.Publisher;
 
 public interface AttachmentMapper extends Mapper {
 
+    default InputStream loadAttachmentContent(AttachmentId attachmentId) throws AttachmentNotFoundException, IOException {
+        return getAttachment(attachmentId).getStream();
+    }
+
     Attachment getAttachment(AttachmentId attachmentId) throws AttachmentNotFoundException;
 
     List<Attachment> getAttachments(Collection<AttachmentId> attachmentIds);
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
index a255e61..03915fb 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
@@ -39,6 +39,8 @@ import java.util.stream.Stream;
 
 import javax.mail.Flags;
 
+import org.apache.james.mailbox.AttachmentContentLoader;
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
@@ -92,11 +94,15 @@ public class MessageSearches implements Iterable<SimpleMessageSearchIndex.Search
     private final Iterator<MailboxMessage> messages;
     private final SearchQuery query;
     private final TextExtractor textExtractor;
+    private final AttachmentContentLoader attachmentContentLoader;
+    private final MailboxSession mailboxSession;
 
-    public MessageSearches(Iterator<MailboxMessage> messages, SearchQuery query, TextExtractor textExtractor) {
+    public MessageSearches(Iterator<MailboxMessage> messages, SearchQuery query, TextExtractor textExtractor, AttachmentContentLoader attachmentContentLoader, MailboxSession mailboxSession) {
         this.messages = messages;
         this.query = query;
         this.textExtractor = textExtractor;
+        this.attachmentContentLoader = attachmentContentLoader;
+        this.mailboxSession = mailboxSession;
     }
 
     @Override
@@ -254,19 +260,19 @@ public class MessageSearches implements Iterable<SimpleMessageSearchIndex.Search
     private boolean isInAttachments(String value, List<MessageAttachment> attachments) {
         return attachments.stream()
             .map(MessageAttachment::getAttachment)
-            .flatMap(this::toAttachmentContent)
+            .flatMap(attachment -> toAttachmentContent(attachment, mailboxSession))
             .anyMatch(string -> string.contains(value));
     }
 
-    private Stream<String> toAttachmentContent(Attachment attachment) {
-        try {
+    private Stream<String> toAttachmentContent(Attachment attachment, MailboxSession mailboxSession) {
+        try (InputStream rawData = attachmentContentLoader.load(attachment, mailboxSession)) {
             return OptionalUtils.toStream(
-                    textExtractor
-                         .extractContent(
-                             attachment.getStream(),
-                             attachment.getType())
-                        .getTextualContent());
-            } catch (Exception e) {
+                textExtractor
+                    .extractContent(
+                        rawData,
+                        attachment.getType())
+                    .getTextualContent());
+        } catch (Exception e) {
             LOGGER.error("Error while parsing attachment content", e);
             return Stream.of();
         }
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndex.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndex.java
index ed6fd17..b33f980 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndex.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndex.java
@@ -30,6 +30,7 @@ import java.util.stream.Stream;
 
 import javax.inject.Inject;
 
+import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.MailboxManager.MessageCapabilities;
 import org.apache.james.mailbox.MailboxManager.SearchCapabilities;
 import org.apache.james.mailbox.MailboxSession;
@@ -70,12 +71,14 @@ public class SimpleMessageSearchIndex implements MessageSearchIndex {
     private final MessageMapperFactory messageMapperFactory;
     private final MailboxMapperFactory mailboxMapperFactory;
     private final TextExtractor textExtractor;
-    
+    private final AttachmentContentLoader attachmentContentLoader;
+
     @Inject
-    public SimpleMessageSearchIndex(MessageMapperFactory messageMapperFactory, MailboxMapperFactory mailboxMapperFactory, TextExtractor textExtractor) {
+    public SimpleMessageSearchIndex(MessageMapperFactory messageMapperFactory, MailboxMapperFactory mailboxMapperFactory, TextExtractor textExtractor, AttachmentContentLoader attachmentContentLoader) {
         this.messageMapperFactory = messageMapperFactory;
         this.mailboxMapperFactory = mailboxMapperFactory;
         this.textExtractor = textExtractor;
+        this.attachmentContentLoader = attachmentContentLoader;
     }
     
     @Override
@@ -139,7 +142,7 @@ public class SimpleMessageSearchIndex implements MessageSearchIndex {
                 hitSet.add(m);
             }
         }
-        return ImmutableList.copyOf(new MessageSearches(hitSet.iterator(), query, textExtractor).iterator());
+        return ImmutableList.copyOf(new MessageSearches(hitSet.iterator(), query, textExtractor, attachmentContentLoader, session).iterator());
     }
 
     @Override
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsMultipartMixedTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsMultipartMixedTest.java
index 5fae690..ff26f19 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsMultipartMixedTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsMultipartMixedTest.java
@@ -27,8 +27,10 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.Locale;
 
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.extractor.TextExtractor;
+import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.search.MessageSearches;
@@ -129,7 +131,8 @@ class SearchUtilsMultipartMixedTest {
         Iterator<MailboxMessage> messages = null;
         SearchQuery query = null; 
         TextExtractor textExtractor = null;
-        messageSearches = new MessageSearches(messages, query, textExtractor);
+        MailboxSession session = null;
+        messageSearches = new MessageSearches(messages, query, textExtractor, (attachment, ignore) -> attachment.getStream(), session);
     }
     
 
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsRFC822Test.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsRFC822Test.java
index f983904..62b8921 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsRFC822Test.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsRFC822Test.java
@@ -27,8 +27,10 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.Locale;
 
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.extractor.TextExtractor;
+import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.search.MessageSearches;
@@ -69,7 +71,8 @@ class SearchUtilsRFC822Test {
         Iterator<MailboxMessage> messages = null;
         SearchQuery query = null; 
         TextExtractor textExtractor = null;
-        messageSearches = new MessageSearches(messages, query, textExtractor);
+        MailboxSession session = null;
+        messageSearches = new MessageSearches(messages, query, textExtractor, (attachment, ignore) -> attachment.getStream(), session);
     }
 
 
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java
index f71d8df..d263af7 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java
@@ -31,8 +31,10 @@ import java.util.TimeZone;
 
 import javax.mail.Flags;
 
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.extractor.TextExtractor;
+import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.model.SearchQuery.AddressType;
 import org.apache.james.mailbox.model.SearchQuery.DateResolution;
@@ -84,7 +86,8 @@ class SearchUtilsTest {
         Iterator<MailboxMessage> messages = null;
         SearchQuery query = null; 
         TextExtractor textExtractor = null;
-        messageSearches = new MessageSearches(messages, query, textExtractor);
+        MailboxSession session = null;
+        messageSearches = new MessageSearches(messages, query, textExtractor, (attachment, ignore) -> attachment.getStream(), session);
     }
     
     @Test
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java
index 9ffdee2..7feaceb 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import org.apache.james.core.Username;
+import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageManager;
@@ -96,7 +97,8 @@ class StoreMailboxManagerTest {
         StoreMailboxAnnotationManager annotationManager = new StoreMailboxAnnotationManager(mockedMapperFactory, storeRightManager);
         SessionProviderImpl sessionProvider = new SessionProviderImpl(authenticator, FakeAuthorizator.forUserAndAdmin(ADMIN, CURRENT_USER));
         QuotaComponents quotaComponents = QuotaComponents.disabled(sessionProvider, mockedMapperFactory);
-        MessageSearchIndex index = new SimpleMessageSearchIndex(mockedMapperFactory, mockedMapperFactory, new DefaultTextExtractor());
+        AttachmentContentLoader attachmentContentLoader = null;
+        MessageSearchIndex index = new SimpleMessageSearchIndex(mockedMapperFactory, mockedMapperFactory, new DefaultTextExtractor(), attachmentContentLoader);
 
         storeMailboxManager = new StoreMailboxManager(mockedMapperFactory, sessionProvider,
                 new JVMMailboxPathLocker(), new MessageParser(), messageIdFactory,
diff --git a/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/host/CassandraHostSystem.java b/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/host/CassandraHostSystem.java
index d2ba763..f79b732 100644
--- a/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/host/CassandraHostSystem.java
+++ b/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/host/CassandraHostSystem.java
@@ -109,7 +109,7 @@ public class CassandraHostSystem extends JamesImapHostSystem {
         ListeningCurrentQuotaUpdater quotaUpdater = new ListeningCurrentQuotaUpdater(currentQuotaManager, quotaRootResolver, eventBus, quotaManager);
         QuotaComponents quotaComponents = new QuotaComponents(perUserMaxQuotaManager, quotaManager, quotaRootResolver);
 
-        MessageSearchIndex index = new SimpleMessageSearchIndex(mapperFactory, mapperFactory, new DefaultTextExtractor());
+        MessageSearchIndex index = new SimpleMessageSearchIndex(mapperFactory, mapperFactory, new DefaultTextExtractor(), null);
 
         mailboxManager = new CassandraMailboxManager(mapperFactory, sessionProvider,
             new JVMMailboxPathLocker(), new MessageParser(), messageIdFactory,
diff --git a/mpt/impl/imap-mailbox/jpa/src/test/java/org/apache/james/mpt/imapmailbox/jpa/host/JPAHostSystem.java b/mpt/impl/imap-mailbox/jpa/src/test/java/org/apache/james/mpt/imapmailbox/jpa/host/JPAHostSystem.java
index b8d8aa8..e97a29c 100644
--- a/mpt/impl/imap-mailbox/jpa/src/test/java/org/apache/james/mpt/imapmailbox/jpa/host/JPAHostSystem.java
+++ b/mpt/impl/imap-mailbox/jpa/src/test/java/org/apache/james/mpt/imapmailbox/jpa/host/JPAHostSystem.java
@@ -28,6 +28,7 @@ import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.encode.main.DefaultImapEncoderFactory;
 import org.apache.james.imap.main.DefaultImapDecoderFactory;
 import org.apache.james.imap.processor.main.DefaultImapProcessorFactory;
+import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.SubscriptionManager;
 import org.apache.james.mailbox.acl.GroupMembershipResolver;
@@ -113,7 +114,8 @@ public class JPAHostSystem extends JamesImapHostSystem {
         StoreQuotaManager storeQuotaManager = new StoreQuotaManager(currentQuotaManager, maxQuotaManager);
         ListeningCurrentQuotaUpdater quotaUpdater = new ListeningCurrentQuotaUpdater(currentQuotaManager, quotaRootResolver, eventBus, storeQuotaManager);
         QuotaComponents quotaComponents = new QuotaComponents(maxQuotaManager, storeQuotaManager, quotaRootResolver);
-        MessageSearchIndex index = new SimpleMessageSearchIndex(mapperFactory, mapperFactory, new DefaultTextExtractor());
+        AttachmentContentLoader attachmentContentLoader = null;
+        MessageSearchIndex index = new SimpleMessageSearchIndex(mapperFactory, mapperFactory, new DefaultTextExtractor(), attachmentContentLoader);
 
         mailboxManager = new OpenJPAMailboxManager(mapperFactory, sessionProvider, messageParser, new DefaultMessageId.Factory(),
             eventBus, annotationManager, storeRightManager, quotaComponents, index);
diff --git a/mpt/impl/imap-mailbox/maildir/src/test/java/org/apache/james/mpt/imapmailbox/maildir/host/MaildirHostSystem.java b/mpt/impl/imap-mailbox/maildir/src/test/java/org/apache/james/mpt/imapmailbox/maildir/host/MaildirHostSystem.java
index 2f52724..be3d8f1 100644
--- a/mpt/impl/imap-mailbox/maildir/src/test/java/org/apache/james/mpt/imapmailbox/maildir/host/MaildirHostSystem.java
+++ b/mpt/impl/imap-mailbox/maildir/src/test/java/org/apache/james/mpt/imapmailbox/maildir/host/MaildirHostSystem.java
@@ -84,7 +84,7 @@ public class MaildirHostSystem extends JamesImapHostSystem {
         StoreMailboxAnnotationManager annotationManager = new StoreMailboxAnnotationManager(mailboxSessionMapperFactory, storeRightManager);
         SessionProviderImpl sessionProvider = new SessionProviderImpl(authenticator, authorizator);
         QuotaComponents quotaComponents = QuotaComponents.disabled(sessionProvider, mailboxSessionMapperFactory);
-        MessageSearchIndex index = new SimpleMessageSearchIndex(mailboxSessionMapperFactory, mailboxSessionMapperFactory, new DefaultTextExtractor());
+        MessageSearchIndex index = new SimpleMessageSearchIndex(mailboxSessionMapperFactory, mailboxSessionMapperFactory, new DefaultTextExtractor(), null);
 
         mailboxManager = new StoreMailboxManager(mailboxSessionMapperFactory, sessionProvider, locker,
             messageParser, new DefaultMessageId.Factory(), annotationManager, eventBus, storeRightManager, quotaComponents,
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
index 80d5579..03f864e 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
@@ -25,6 +25,7 @@ import javax.inject.Singleton;
 import org.apache.james.adapter.mailbox.store.UserRepositoryAuthenticator;
 import org.apache.james.adapter.mailbox.store.UserRepositoryAuthorizator;
 import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.AttachmentManager;
 import org.apache.james.mailbox.BlobManager;
 import org.apache.james.mailbox.MailboxManager;
@@ -169,6 +170,7 @@ public class CassandraMailboxModule extends AbstractModule {
         bind(AttachmentManager.class).to(StoreAttachmentManager.class);
         bind(RightManager.class).to(StoreRightManager.class);
         bind(SessionProvider.class).to(SessionProviderImpl.class);
+        bind(AttachmentContentLoader.class).to(AttachmentManager.class);
 
         bind(ReIndexer.class).to(ReIndexerImpl.class);
         bind(MessageIdReIndexer.class).to(MessageIdReIndexerImpl.class);
diff --git a/server/container/guice/jpa-guice/src/main/java/org/apache/james/modules/mailbox/JPAMailboxModule.java b/server/container/guice/jpa-guice/src/main/java/org/apache/james/modules/mailbox/JPAMailboxModule.java
index f405a03..3a9dd02 100644
--- a/server/container/guice/jpa-guice/src/main/java/org/apache/james/modules/mailbox/JPAMailboxModule.java
+++ b/server/container/guice/jpa-guice/src/main/java/org/apache/james/modules/mailbox/JPAMailboxModule.java
@@ -24,6 +24,7 @@ import javax.inject.Singleton;
 
 import org.apache.james.adapter.mailbox.store.UserRepositoryAuthenticator;
 import org.apache.james.adapter.mailbox.store.UserRepositoryAuthorizator;
+import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.SessionProvider;
@@ -34,6 +35,7 @@ import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
 import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
 import org.apache.james.mailbox.events.MailboxListener;
 import org.apache.james.mailbox.indexer.ReIndexer;
+import org.apache.james.mailbox.jpa.JPAAttachmentContentLoader;
 import org.apache.james.mailbox.jpa.JPAId;
 import org.apache.james.mailbox.jpa.JPAMailboxSessionMapperFactory;
 import org.apache.james.mailbox.jpa.mail.JPAModSeqProvider;
@@ -107,6 +109,7 @@ public class JPAMailboxModule extends AbstractModule {
         bind(MailboxId.Factory.class).to(JPAId.Factory.class);
         bind(GroupMembershipResolver.class).to(SimpleGroupMembershipResolver.class);
         bind(MailboxACLResolver.class).to(UnionMailboxACLResolver.class);
+        bind(AttachmentContentLoader.class).to(JPAAttachmentContentLoader.class);
 
         bind(ReIndexer.class).to(ReIndexerImpl.class);
         
diff --git a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java
index b683510..5433f94 100644
--- a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java
+++ b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java
@@ -25,6 +25,7 @@ import javax.inject.Singleton;
 
 import org.apache.james.adapter.mailbox.store.UserRepositoryAuthenticator;
 import org.apache.james.adapter.mailbox.store.UserRepositoryAuthorizator;
+import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.AttachmentManager;
 import org.apache.james.mailbox.BlobManager;
 import org.apache.james.mailbox.MailboxManager;
@@ -109,6 +110,7 @@ public class MemoryMailboxModule extends AbstractModule {
         bind(MessageSearchIndex.class).to(SimpleMessageSearchIndex.class);
         bind(TextExtractor.class).to(JsoupTextExtractor.class);
         bind(RightManager.class).to(StoreRightManager.class);
+        bind(AttachmentContentLoader.class).to(AttachmentManager.class);
 
         bind(DeletedMessageMetadataVault.class).to(MemoryDeletedMessageMetadataVault.class);
 


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


[james-project] 08/37: JAMES-2997 step #6 Remove AttachmentManager::storeAttachmentsForMessage unused method

Posted by bt...@apache.org.
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 af96d34897b32a24a8353e727f28987a93e7c03d
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Jan 17 10:29:58 2020 +0700

    JAMES-2997 step #6 Remove AttachmentManager::storeAttachmentsForMessage unused method
    
    Correlating the inputs with the generated message ids is non trivial (might
    require some 'temporary' correlation ids), and is unused nor tested.
    
    Thus I would rather not like to pay the price of this complexity in an already
    that big changeset.
---
 .../src/main/java/org/apache/james/mailbox/AttachmentManager.java    | 4 ----
 .../java/org/apache/james/mailbox/store/StoreAttachmentManager.java  | 5 -----
 2 files changed, 9 deletions(-)

diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
index 946ea37..99722a1 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentManager.java
@@ -21,14 +21,12 @@ package org.apache.james.mailbox;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.Collection;
 import java.util.List;
 
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
-import org.apache.james.mailbox.model.MessageId;
 import org.reactivestreams.Publisher;
 
 public interface AttachmentManager extends AttachmentContentLoader {
@@ -41,8 +39,6 @@ public interface AttachmentManager extends AttachmentContentLoader {
 
     Publisher<Attachment> storeAttachment(String contentType, InputStream attachmentContent, MailboxSession mailboxSession);
 
-    void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId, MailboxSession mailboxSession) throws MailboxException;
-
     InputStream loadAttachmentContent(AttachmentId attachmentId, MailboxSession mailboxSession) throws AttachmentNotFoundException, IOException;
 
     @Override
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
index 98ca7f1..9d281fb 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentManager.java
@@ -82,11 +82,6 @@ public class StoreAttachmentManager implements AttachmentManager {
             .storeAttachmentForOwner(contentType, attachmentContent, mailboxSession.getUser());
     }
 
-    @Override
-    public void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId, MailboxSession mailboxSession) throws MailboxException {
-        attachmentMapperFactory.getAttachmentMapper(mailboxSession).storeAttachmentsForMessage(attachments, ownerMessageId);
-    }
-
     private boolean userHasAccessToAttachment(AttachmentId attachmentId, MailboxSession mailboxSession) {
         try {
             return isExplicitlyAOwner(attachmentId, mailboxSession)


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


[james-project] 18/37: JAMES-2997 Renable BlobTest

Posted by bt...@apache.org.
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 5ed32bfca007aa9944eebcc774b0b5d2fcfc62dc
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Jan 17 16:44:35 2020 +0700

    JAMES-2997 Renable BlobTest
---
 .../java/org/apache/james/mailbox/model/BlobTest.java   | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobTest.java
index 32e87e0..55c3b3c 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/BlobTest.java
@@ -22,17 +22,19 @@ package org.apache.james.mailbox.model;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
+import java.io.ByteArrayInputStream;
 import java.nio.charset.StandardCharsets;
 
+import org.apache.james.mailbox.model.Blob.InputStreamSupplier;
 import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
 
 class BlobTest {
-
-    public static final BlobId ID = BlobId.fromString("123");
-    public static final String CONTENT_TYPE = "text/plain";
-    public static final byte[] PAYLOAD = "abc".getBytes(StandardCharsets.UTF_8);
+    static final BlobId ID = BlobId.fromString("123");
+    static final String CONTENT_TYPE = "text/plain";
+    static final InputStreamSupplier PAYLOAD = () -> new ByteArrayInputStream("abc".getBytes(StandardCharsets.UTF_8));
+    static final int LENGTH = 3;
 
     @Test
     void shouldMatchBeanContract() {
@@ -40,7 +42,7 @@ class BlobTest {
             .withIgnoredFields("payload", "size")
             .verify();
     }
-/*
+
     @Test
     void buildShouldConstructValidBlob() {
         assertThat(
@@ -48,9 +50,10 @@ class BlobTest {
                 .id(ID)
                 .contentType(CONTENT_TYPE)
                 .payload(PAYLOAD)
+                .size(LENGTH)
                 .build())
             .isEqualTo(
-                new Blob(ID, PAYLOAD, CONTENT_TYPE, length));
+                new Blob(ID, PAYLOAD, CONTENT_TYPE, LENGTH));
     }
 
     @Test
@@ -81,5 +84,5 @@ class BlobTest {
                 .contentType(CONTENT_TYPE)
                 .build())
             .isInstanceOf(IllegalStateException.class);
-    }*/
+    }
 }


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


[james-project] 15/37: JAMES-2997 step #13 StoreMessageIdManager should rely on StoreRightManager

Posted by bt...@apache.org.
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 c75ecc3ab507b6be71d53e200a445428e25eb94b
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 20 10:46:25 2020 +0700

    JAMES-2997 step #13 StoreMessageIdManager should rely on StoreRightManager
    
    This enables cutting a dependency loop:
    
    searchIndex -> AttachmentLoader -> AttachmentManager -> MessageIdManager
    -> MailboxManager -> SearchIndex
    
    Note also that InMemoryIntegrationResources needs to instanciate PreDeletionHooks earlier.
---
 .../manager/InMemoryIntegrationResources.java      | 74 ++++++++++++++--------
 .../store/search/SimpleMessageSearchIndexTest.java |  2 +-
 .../james/mailbox/store/StoreMessageIdManager.java | 12 ++--
 .../cassandra/host/CassandraHostSystem.java        | 10 ++-
 4 files changed, 64 insertions(+), 34 deletions(-)

diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryIntegrationResources.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryIntegrationResources.java
index 7d702ff..61e0c8f 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryIntegrationResources.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/manager/InMemoryIntegrationResources.java
@@ -23,7 +23,9 @@ import java.util.Collection;
 import java.util.Optional;
 import java.util.function.Function;
 
+import org.apache.james.mailbox.AttachmentContentLoader;
 import org.apache.james.mailbox.MessageIdManager;
+import org.apache.james.mailbox.SessionProvider;
 import org.apache.james.mailbox.acl.GroupMembershipResolver;
 import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
 import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
@@ -124,12 +126,12 @@ public class InMemoryIntegrationResources implements IntegrationResources<StoreM
         }
 
         interface RequireSearchIndex {
-            RequirePreDeletionHooks searchIndex(Function<MailboxManagerPreInstanciationStage, MessageSearchIndex> searchIndex);
+            RequirePreDeletionHooks searchIndex(Function<MailboxManagerSearchIndexStage, MessageSearchIndex> searchIndex);
 
-            RequirePreDeletionHooks listeningSearchIndex(Function<MailboxManagerPreInstanciationStage, ListeningMessageSearchIndex> searchIndex);
+            RequirePreDeletionHooks listeningSearchIndex(Function<MailboxManagerSearchIndexStage, ListeningMessageSearchIndex> searchIndex);
 
             default RequirePreDeletionHooks scanningSearchIndex() {
-                return searchIndex(stage -> new SimpleMessageSearchIndex(stage.mapperFactory, stage.mapperFactory, new DefaultTextExtractor(), null));
+                return searchIndex(stage -> new SimpleMessageSearchIndex(stage.mapperFactory, stage.mapperFactory, new DefaultTextExtractor(), stage.attachmentContentLoader));
             }
         }
 
@@ -204,7 +206,7 @@ public class InMemoryIntegrationResources implements IntegrationResources<StoreM
         private Optional<Function<BaseQuotaComponentsStage, QuotaManager>> quotaManager;
         private Optional<Integer> limitAnnotationSize;
         private Optional<MessageParser> messageParser;
-        private Optional<Function<MailboxManagerPreInstanciationStage, MessageSearchIndex>> searchIndexFactory;
+        private Optional<Function<MailboxManagerSearchIndexStage, MessageSearchIndex>> searchIndexFactory;
         private ImmutableSet.Builder<Function<MailboxManagerPreInstanciationStage, PreDeletionHook>> preDeletionHooksFactories;
         private ImmutableList.Builder<MailboxListener.GroupMailboxListener> listenersToBeRegistered;
 
@@ -265,13 +267,13 @@ public class InMemoryIntegrationResources implements IntegrationResources<StoreM
         }
 
         @Override
-        public Builder searchIndex(Function<MailboxManagerPreInstanciationStage, MessageSearchIndex> searchIndex) {
+        public Builder searchIndex(Function<MailboxManagerSearchIndexStage, MessageSearchIndex> searchIndex) {
             this.searchIndexFactory = Optional.of(searchIndex);
             return this;
         }
 
         @Override
-        public Builder listeningSearchIndex(Function<MailboxManagerPreInstanciationStage, ListeningMessageSearchIndex> searchIndex) {
+        public Builder listeningSearchIndex(Function<MailboxManagerSearchIndexStage, ListeningMessageSearchIndex> searchIndex) {
             this.searchIndexFactory = Optional.of(stage -> {
                 ListeningMessageSearchIndex listeningMessageSearchIndex = searchIndex.apply(stage);
                 listenersToBeRegistered.add(listeningMessageSearchIndex);
@@ -309,28 +311,38 @@ public class InMemoryIntegrationResources implements IntegrationResources<StoreM
             ListeningCurrentQuotaUpdater listeningCurrentQuotaUpdater = new ListeningCurrentQuotaUpdater(currentQuotaManager, quotaRootResolver, eventBus, quotaManager);
             QuotaComponents quotaComponents = new QuotaComponents(maxQuotaManager, quotaManager, quotaRootResolver);
 
+            InMemoryMessageId.Factory messageIdFactory = new InMemoryMessageId.Factory();
+
             MailboxManagerPreInstanciationStage preInstanciationStage = new MailboxManagerPreInstanciationStage(mailboxSessionMapperFactory, sessionProvider);
-            MessageSearchIndex index = searchIndexFactory.get().apply(preInstanciationStage);
+            PreDeletionHooks hooks = createHooks(preInstanciationStage);
+            StoreMessageIdManager messageIdManager = new StoreMessageIdManager(storeRightManager, mailboxSessionMapperFactory,
+                eventBus, messageIdFactory, quotaManager, quotaRootResolver, hooks);
+
+            StoreAttachmentManager attachmentManager = new StoreAttachmentManager(mailboxSessionMapperFactory, messageIdManager);
+            MailboxManagerSearchIndexStage searchIndexStage = new MailboxManagerSearchIndexStage(mailboxSessionMapperFactory, sessionProvider, attachmentManager);
+            MessageSearchIndex index = searchIndexFactory.get().apply(searchIndexStage);
 
             InMemoryMailboxManager manager = new InMemoryMailboxManager(
                 mailboxSessionMapperFactory,
                 sessionProvider,
                 new JVMMailboxPathLocker(),
                 messageParser.get(),
-                new InMemoryMessageId.Factory(),
+                messageIdFactory,
                 eventBus,
                 annotationManager,
                 storeRightManager,
                 quotaComponents,
                 index,
-                createHooks(preInstanciationStage));
+                hooks);
 
             eventBus.register(listeningCurrentQuotaUpdater);
             eventBus.register(new MailboxAnnotationListener(mailboxSessionMapperFactory, sessionProvider));
 
             listenersToBeRegistered.build().forEach(eventBus::register);
 
-            return new InMemoryIntegrationResources(manager, storeRightManager, new InMemoryMessageId.Factory(), currentQuotaManager, quotaRootResolver, maxQuotaManager, quotaManager, index, eventBus);
+            StoreBlobManager blobManager = new StoreBlobManager(attachmentManager, messageIdManager, messageIdFactory);
+
+            return new InMemoryIntegrationResources(manager, storeRightManager, messageIdFactory, currentQuotaManager, quotaRootResolver, maxQuotaManager, quotaManager, messageIdManager, index, eventBus, blobManager);
         }
 
         private PreDeletionHooks createHooks(MailboxManagerPreInstanciationStage preInstanciationStage) {
@@ -378,6 +390,30 @@ public class InMemoryIntegrationResources implements IntegrationResources<StoreM
         }
     }
 
+    public static class MailboxManagerSearchIndexStage {
+        private final InMemoryMailboxSessionMapperFactory mapperFactory;
+        private final SessionProvider sessionProvider;
+        private final AttachmentContentLoader attachmentContentLoader;
+
+        MailboxManagerSearchIndexStage(InMemoryMailboxSessionMapperFactory mapperFactory, SessionProvider sessionProvider, AttachmentContentLoader attachmentContentLoader) {
+            this.mapperFactory = mapperFactory;
+            this.sessionProvider = sessionProvider;
+            this.attachmentContentLoader = attachmentContentLoader;
+        }
+
+        public InMemoryMailboxSessionMapperFactory getMapperFactory() {
+            return mapperFactory;
+        }
+
+        public SessionProvider getSessionProvider() {
+            return sessionProvider;
+        }
+
+        public AttachmentContentLoader getAttachmentContentLoader() {
+            return attachmentContentLoader;
+        }
+    }
+
     private final InMemoryMailboxManager mailboxManager;
     private final StoreRightManager storeRightManager;
     private final MessageId.Factory messageIdFactory;
@@ -390,7 +426,7 @@ public class InMemoryIntegrationResources implements IntegrationResources<StoreM
     private final EventBus eventBus;
     private final StoreBlobManager blobManager;
 
-    InMemoryIntegrationResources(InMemoryMailboxManager mailboxManager, StoreRightManager storeRightManager, MessageId.Factory messageIdFactory, InMemoryCurrentQuotaManager currentQuotaManager, DefaultUserQuotaRootResolver defaultUserQuotaRootResolver, InMemoryPerUserMaxQuotaManager maxQuotaManager, QuotaManager quotaManager, MessageSearchIndex searchIndex, EventBus eventBus) {
+    InMemoryIntegrationResources(InMemoryMailboxManager mailboxManager, StoreRightManager storeRightManager, MessageId.Factory messageIdFactory, InMemoryCurrentQuotaManager currentQuotaManager, DefaultUserQuotaRootResolver defaultUserQuotaRootResolver, InMemoryPerUserMaxQuotaManager maxQuotaManager, QuotaManager quotaManager, StoreMessageIdManager storeMessageIdManager, MessageSearchIndex searchIndex, EventBus eventBus, StoreBlobManager blobManager) {
         this.mailboxManager = mailboxManager;
         this.storeRightManager = storeRightManager;
         this.messageIdFactory = messageIdFactory;
@@ -398,22 +434,10 @@ public class InMemoryIntegrationResources implements IntegrationResources<StoreM
         this.defaultUserQuotaRootResolver = defaultUserQuotaRootResolver;
         this.maxQuotaManager = maxQuotaManager;
         this.quotaManager = quotaManager;
+        this.storeMessageIdManager = storeMessageIdManager;
         this.searchIndex = searchIndex;
         this.eventBus = eventBus;
-
-        this.storeMessageIdManager = new StoreMessageIdManager(
-            mailboxManager,
-            mailboxManager.getMapperFactory(),
-            mailboxManager.getEventBus(),
-            messageIdFactory,
-            quotaManager,
-            defaultUserQuotaRootResolver,
-            mailboxManager.getPreDeletionHooks());
-
-        this.blobManager = new StoreBlobManager(
-            new StoreAttachmentManager((InMemoryMailboxSessionMapperFactory) mailboxManager.getMapperFactory(), storeMessageIdManager),
-            storeMessageIdManager,
-            messageIdFactory);
+        this.blobManager = blobManager;
     }
 
     public DefaultUserQuotaRootResolver getDefaultUserQuotaRootResolver() {
diff --git a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
index 4cadd0e..40a9152 100644
--- a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
+++ b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
@@ -40,7 +40,7 @@ class SimpleMessageSearchIndexTest extends AbstractMessageSearchIndexTest {
                 preInstanciationStage.getMapperFactory(),
                 preInstanciationStage.getMapperFactory(),
                 new PDFTextExtractor(),
-                null))
+                preInstanciationStage.getAttachmentContentLoader()))
             .noPreDeletionHooks()
             .storeQuotaManager()
             .build();
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
index 7e37bf8..cb90c15 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
@@ -30,13 +30,13 @@ import java.util.function.Predicate;
 import javax.inject.Inject;
 import javax.mail.Flags;
 
-import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.MetadataWithMailboxId;
 import org.apache.james.mailbox.ModSeq;
+import org.apache.james.mailbox.RightManager;
 import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.exception.MailboxException;
@@ -91,7 +91,7 @@ public class StoreMessageIdManager implements MessageIdManager {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(StoreMessageIdManager.class);
 
-    private final MailboxManager mailboxManager;
+    private final RightManager rightManager;
     private final MailboxSessionMapperFactory mailboxSessionMapperFactory;
     private final EventBus eventBus;
     private final MessageId.Factory messageIdFactory;
@@ -100,10 +100,10 @@ public class StoreMessageIdManager implements MessageIdManager {
     private final PreDeletionHooks preDeletionHooks;
 
     @Inject
-    public StoreMessageIdManager(MailboxManager mailboxManager, MailboxSessionMapperFactory mailboxSessionMapperFactory,
+    public StoreMessageIdManager(RightManager rightManager, MailboxSessionMapperFactory mailboxSessionMapperFactory,
                                  EventBus eventBus, MessageId.Factory messageIdFactory,
                                  QuotaManager quotaManager, QuotaRootResolver quotaRootResolver, PreDeletionHooks preDeletionHooks) {
-        this.mailboxManager = mailboxManager;
+        this.rightManager = rightManager;
         this.mailboxSessionMapperFactory = mailboxSessionMapperFactory;
         this.eventBus = eventBus;
         this.messageIdFactory = messageIdFactory;
@@ -372,7 +372,7 @@ public class StoreMessageIdManager implements MessageIdManager {
         MailboxMapper mailboxMapper = mailboxSessionMapperFactory.getMailboxMapper(mailboxSession);
 
         for (MailboxId mailboxId : mailboxIds) {
-            boolean shouldPreserveFlags = mailboxManager.myRights(mailboxId, mailboxSession).contains(Right.Write);
+            boolean shouldPreserveFlags = rightManager.myRights(mailboxId, mailboxSession).contains(Right.Write);
             SimpleMailboxMessage copy =
                 SimpleMailboxMessage.from(mailboxMessage)
                     .mailboxId(mailboxId)
@@ -422,7 +422,7 @@ public class StoreMessageIdManager implements MessageIdManager {
 
 
     private Predicate<MailboxId> hasRightsOnMailbox(MailboxSession session, Right... rights) {
-        return Throwing.predicate((MailboxId mailboxId) -> mailboxManager.myRights(mailboxId, session).contains(rights))
+        return Throwing.predicate((MailboxId mailboxId) -> rightManager.myRights(mailboxId, session).contains(rights))
             .fallbackTo(any -> false);
     }
 
diff --git a/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/host/CassandraHostSystem.java b/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/host/CassandraHostSystem.java
index f79b732..4cb76d0 100644
--- a/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/host/CassandraHostSystem.java
+++ b/mpt/impl/imap-mailbox/cassandra/src/test/java/org/apache/james/mpt/imapmailbox/cassandra/host/CassandraHostSystem.java
@@ -47,7 +47,9 @@ import org.apache.james.mailbox.store.JVMMailboxPathLocker;
 import org.apache.james.mailbox.store.MailboxManagerConfiguration;
 import org.apache.james.mailbox.store.PreDeletionHooks;
 import org.apache.james.mailbox.store.SessionProviderImpl;
+import org.apache.james.mailbox.store.StoreAttachmentManager;
 import org.apache.james.mailbox.store.StoreMailboxAnnotationManager;
+import org.apache.james.mailbox.store.StoreMessageIdManager;
 import org.apache.james.mailbox.store.StoreRightManager;
 import org.apache.james.mailbox.store.StoreSubscriptionManager;
 import org.apache.james.mailbox.store.extractor.DefaultTextExtractor;
@@ -109,11 +111,15 @@ public class CassandraHostSystem extends JamesImapHostSystem {
         ListeningCurrentQuotaUpdater quotaUpdater = new ListeningCurrentQuotaUpdater(currentQuotaManager, quotaRootResolver, eventBus, quotaManager);
         QuotaComponents quotaComponents = new QuotaComponents(perUserMaxQuotaManager, quotaManager, quotaRootResolver);
 
-        MessageSearchIndex index = new SimpleMessageSearchIndex(mapperFactory, mapperFactory, new DefaultTextExtractor(), null);
+        StoreMessageIdManager messageIdManager = new StoreMessageIdManager(storeRightManager, mapperFactory, eventBus, messageIdFactory, quotaManager, quotaRootResolver, PreDeletionHooks.NO_PRE_DELETION_HOOK);
+        StoreAttachmentManager attachmentManager = new StoreAttachmentManager(mapperFactory, messageIdManager);
+
+        MessageSearchIndex index = new SimpleMessageSearchIndex(mapperFactory, mapperFactory, new DefaultTextExtractor(), attachmentManager);
 
         mailboxManager = new CassandraMailboxManager(mapperFactory, sessionProvider,
             new JVMMailboxPathLocker(), new MessageParser(), messageIdFactory,
-            eventBus, annotationManager, storeRightManager, quotaComponents, index, MailboxManagerConfiguration.DEFAULT, PreDeletionHooks.NO_PRE_DELETION_HOOK);
+            eventBus, annotationManager, storeRightManager, quotaComponents, index, MailboxManagerConfiguration.DEFAULT,
+            PreDeletionHooks.NO_PRE_DELETION_HOOK);
 
         eventBus.register(quotaUpdater);
 


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


[james-project] 26/37: [REFACTORING] Favor composition over inheritance in order to instantiate messages

Posted by bt...@apache.org.
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 98e37199594fdce9b12b679231c4647f99ccfec0
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 20 11:26:47 2020 +0700

    [REFACTORING] Favor composition over inheritance in order to instantiate messages
    
    This was what OpenJPA mailbox implementation was actively relying on.
    
    I also took this opportunity to merge OpenJPA & JPA mailbox/message managers together.
---
 .../mailbox/cassandra/CassandraMessageManager.java |  3 +-
 .../james/mailbox/jpa/JPAMailboxManager.java       | 67 -----------------
 .../james/mailbox/jpa/JPAMessageManager.java       | 87 ----------------------
 .../mailbox/jpa/openjpa/OpenJPAMailboxManager.java | 31 +++++---
 .../mailbox/jpa/openjpa/OpenJPAMessageFactory.java | 66 ++++++++++++++++
 .../mailbox/jpa/openjpa/OpenJPAMessageManager.java | 55 ++++----------
 .../mailbox/inmemory/InMemoryMessageManager.java   |  3 +-
 .../apache/james/mailbox/store/MessageFactory.java | 50 +++++++++++++
 .../james/mailbox/store/StoreMailboxManager.java   |  2 +-
 .../james/mailbox/store/StoreMessageManager.java   | 18 ++---
 10 files changed, 163 insertions(+), 219 deletions(-)

diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
index d3cbdde..50159cd 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
@@ -35,6 +35,7 @@ import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
 import org.apache.james.mailbox.store.BatchSizes;
+import org.apache.james.mailbox.store.MessageFactory;
 import org.apache.james.mailbox.store.PreDeletionHooks;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.StoreRightManager;
@@ -57,7 +58,7 @@ public class CassandraMessageManager extends StoreMessageManager {
                             PreDeletionHooks preDeletionHooks) {
         super(CassandraMailboxManager.MESSAGE_CAPABILITIES, mapperFactory, index, eventBus, locker, mailbox,
             quotaManager, quotaRootResolver, messageParser, messageIdFactory, batchSizes, storeRightManager,
-            preDeletionHooks);
+            preDeletionHooks, new MessageFactory.StoreMessageFactory());
 
         this.mapperFactory = mapperFactory;
     }
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMailboxManager.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMailboxManager.java
deleted file mode 100644
index 1c606c4..0000000
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMailboxManager.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************
- * 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.                                           *
- ****************************************************************/
-package org.apache.james.mailbox.jpa;
-
-import java.util.EnumSet;
-
-import org.apache.james.mailbox.MailboxPathLocker;
-import org.apache.james.mailbox.SessionProvider;
-import org.apache.james.mailbox.events.EventBus;
-import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.mailbox.store.MailboxManagerConfiguration;
-import org.apache.james.mailbox.store.PreDeletionHooks;
-import org.apache.james.mailbox.store.StoreMailboxAnnotationManager;
-import org.apache.james.mailbox.store.StoreMailboxManager;
-import org.apache.james.mailbox.store.StoreRightManager;
-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;
-
-/**
- * JPA implementation of {@link StoreMailboxManager}
- */
-public abstract class JPAMailboxManager extends StoreMailboxManager {
-
-    public static final EnumSet<MailboxCapabilities> MAILBOX_CAPABILITIES = EnumSet.of(MailboxCapabilities.UserFlag,
-        MailboxCapabilities.Namespace,
-        MailboxCapabilities.Move,
-        MailboxCapabilities.Annotation);
-
-    public JPAMailboxManager(JPAMailboxSessionMapperFactory mailboxSessionMapperFactory,
-                             SessionProvider sessionProvider,
-                             MailboxPathLocker locker,
-                             MessageParser messageParser,
-                             MessageId.Factory messageIdFactory,
-                             EventBus eventBus,
-                             StoreMailboxAnnotationManager annotationManager,
-                             StoreRightManager storeRightManager,
-                             QuotaComponents quotaComponents,
-                             MessageSearchIndex index) {
-        super(mailboxSessionMapperFactory, sessionProvider, locker,
-            messageParser, messageIdFactory, annotationManager,
-            eventBus, storeRightManager, quotaComponents,
-            index, MailboxManagerConfiguration.DEFAULT, PreDeletionHooks.NO_PRE_DELETION_HOOK);
-    }
-
-    @Override
-    public EnumSet<MailboxCapabilities> getSupportedMailboxCapabilities() {
-        return MAILBOX_CAPABILITIES;
-    }
-
-}
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java
deleted file mode 100644
index 4dc500b..0000000
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************
- * 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.                                           *
- ****************************************************************/
-package org.apache.james.mailbox.jpa;
-
-import java.util.Date;
-import java.util.List;
-
-import javax.mail.Flags;
-import javax.mail.internet.SharedInputStream;
-
-import org.apache.james.mailbox.MailboxPathLocker;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.events.EventBus;
-import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
-import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMailboxMessage;
-import org.apache.james.mailbox.model.Mailbox;
-import org.apache.james.mailbox.model.MessageAttachment;
-import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.mailbox.quota.QuotaManager;
-import org.apache.james.mailbox.quota.QuotaRootResolver;
-import org.apache.james.mailbox.store.BatchSizes;
-import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
-import org.apache.james.mailbox.store.PreDeletionHooks;
-import org.apache.james.mailbox.store.StoreMessageManager;
-import org.apache.james.mailbox.store.StoreRightManager;
-import org.apache.james.mailbox.store.mail.model.MailboxMessage;
-import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
-import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
-import org.apache.james.mailbox.store.search.MessageSearchIndex;
-
-/**
- * Abstract base class which should be used from JPA implementations.
- */
-public class JPAMessageManager extends StoreMessageManager {
-    
-    public JPAMessageManager(MailboxSessionMapperFactory mapperFactory,
-                             MessageSearchIndex index,
-                             EventBus eventBus,
-                             MailboxPathLocker locker,
-                             Mailbox mailbox,
-                             QuotaManager quotaManager,
-                             QuotaRootResolver quotaRootResolver,
-                             MessageParser messageParser,
-                             MessageId.Factory messageIdFactory,
-                             BatchSizes batchSizes,
-                             StoreRightManager storeRightManager) {
-
-        super(JPAMailboxManager.DEFAULT_NO_MESSAGE_CAPABILITIES, mapperFactory, index, eventBus, locker, mailbox,
-            quotaManager, quotaRootResolver, messageParser, messageIdFactory, batchSizes, storeRightManager, PreDeletionHooks.NO_PRE_DELETION_HOOK);
-    }
-    
-    @Override
-    protected MailboxMessage createMessage(Date internalDate, int size, int bodyStartOctet, SharedInputStream content,
-                                                  final Flags flags, PropertyBuilder propertyBuilder, List<MessageAttachment> attachments) throws MailboxException {
-
-        return new JPAMailboxMessage(JPAMailbox.from(getMailboxEntity()), internalDate, size, flags, content,  bodyStartOctet,  propertyBuilder);
-    }
-
-
-    /**
-     * Support user flags
-     */
-    @Override
-    protected Flags getPermanentFlags(MailboxSession session) {
-        Flags flags =  super.getPermanentFlags(session);
-        flags.add(Flags.Flag.USER);
-        return flags;
-    }
-    
-}
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java
index 5db577c..3fec6d5 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java
@@ -19,18 +19,21 @@
 
 package org.apache.james.mailbox.jpa.openjpa;
 
+import java.util.EnumSet;
+
 import javax.inject.Inject;
 
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.SessionProvider;
 import org.apache.james.mailbox.events.EventBus;
-import org.apache.james.mailbox.jpa.JPAMailboxManager;
 import org.apache.james.mailbox.jpa.JPAMailboxSessionMapperFactory;
-import org.apache.james.mailbox.jpa.openjpa.OpenJPAMessageManager.AdvancedFeature;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.JVMMailboxPathLocker;
+import org.apache.james.mailbox.store.MailboxManagerConfiguration;
+import org.apache.james.mailbox.store.PreDeletionHooks;
 import org.apache.james.mailbox.store.StoreMailboxAnnotationManager;
+import org.apache.james.mailbox.store.StoreMailboxManager;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.StoreRightManager;
 import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
@@ -41,7 +44,11 @@ import org.apache.james.mailbox.store.search.MessageSearchIndex;
  * OpenJPA implementation of MailboxManager
  *
  */
-public class OpenJPAMailboxManager extends JPAMailboxManager {
+public class OpenJPAMailboxManager extends StoreMailboxManager {
+    public static final EnumSet<MailboxCapabilities> MAILBOX_CAPABILITIES = EnumSet.of(MailboxCapabilities.UserFlag,
+        MailboxCapabilities.Namespace,
+        MailboxCapabilities.Move,
+        MailboxCapabilities.Annotation);
 
     @Inject
     public OpenJPAMailboxManager(JPAMailboxSessionMapperFactory mapperFactory,
@@ -53,13 +60,10 @@ public class OpenJPAMailboxManager extends JPAMailboxManager {
                                  StoreRightManager storeRightManager,
                                  QuotaComponents quotaComponents,
                                  MessageSearchIndex index) {
-        super(mapperFactory, sessionProvider, new JVMMailboxPathLocker(), messageParser,
-            messageIdFactory, eventBus, annotationManager, storeRightManager,
-            quotaComponents, index);
-    }
-
-    protected AdvancedFeature getAdvancedFeature() {
-        return AdvancedFeature.None;
+        super(mapperFactory, sessionProvider, new JVMMailboxPathLocker(),
+            messageParser, messageIdFactory, annotationManager,
+            eventBus, storeRightManager, quotaComponents,
+            index, MailboxManagerConfiguration.DEFAULT, PreDeletionHooks.NO_PRE_DELETION_HOOK);
     }
 
     @Override
@@ -69,7 +73,6 @@ public class OpenJPAMailboxManager extends JPAMailboxManager {
             getEventBus(),
             getLocker(),
             mailboxRow,
-            getAdvancedFeature(),
             getQuotaComponents().getQuotaManager(),
             getQuotaComponents().getQuotaRootResolver(),
             getMessageParser(),
@@ -77,4 +80,10 @@ public class OpenJPAMailboxManager extends JPAMailboxManager {
             configuration.getBatchSizes(),
             getStoreRightManager());
     }
+
+    @Override
+    public EnumSet<MailboxCapabilities> getSupportedMailboxCapabilities() {
+        return MAILBOX_CAPABILITIES;
+    }
+
 }
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageFactory.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageFactory.java
new file mode 100644
index 0000000..2135a76
--- /dev/null
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageFactory.java
@@ -0,0 +1,66 @@
+/****************************************************************
+ * 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.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.jpa.openjpa;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.mail.Flags;
+import javax.mail.internet.SharedInputStream;
+
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
+import org.apache.james.mailbox.jpa.mail.model.openjpa.AbstractJPAMailboxMessage;
+import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAEncryptedMailboxMessage;
+import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMailboxMessage;
+import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAStreamingMailboxMessage;
+import org.apache.james.mailbox.model.Mailbox;
+import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.store.MessageFactory;
+import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+
+public class OpenJPAMessageFactory implements MessageFactory<AbstractJPAMailboxMessage> {
+    private final AdvancedFeature feature;
+
+    public OpenJPAMessageFactory(AdvancedFeature feature) {
+        this.feature = feature;
+    }
+
+    public enum AdvancedFeature {
+        None,
+        Streaming,
+        Encryption
+    }
+
+    @Override
+    public AbstractJPAMailboxMessage createMessage(MessageId messageId, Mailbox mailbox, Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, List<MessageAttachment> attachments) throws MailboxException {
+        switch (feature) {
+            case Streaming:
+                return new JPAStreamingMailboxMessage(JPAMailbox.from(mailbox), internalDate, size, flags, content,
+                    bodyStartOctet, propertyBuilder);
+            case Encryption:
+                return new JPAEncryptedMailboxMessage(JPAMailbox.from(mailbox), internalDate, size, flags, content,
+                    bodyStartOctet, propertyBuilder);
+            default:
+                return new JPAMailboxMessage(JPAMailbox.from(mailbox), internalDate, size, flags, content,  bodyStartOctet,  propertyBuilder);
+        }
+    }
+}
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
index 7494fb8..6db978a 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
@@ -19,70 +19,47 @@
 
 package org.apache.james.mailbox.jpa.openjpa;
 
-import java.util.Date;
-import java.util.List;
-
 import javax.mail.Flags;
-import javax.mail.internet.SharedInputStream;
 
 import org.apache.james.mailbox.MailboxPathLocker;
+import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.events.EventBus;
-import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.jpa.JPAMessageManager;
-import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
-import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAEncryptedMailboxMessage;
-import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAStreamingMailboxMessage;
 import org.apache.james.mailbox.model.Mailbox;
-import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
 import org.apache.james.mailbox.store.BatchSizes;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
+import org.apache.james.mailbox.store.PreDeletionHooks;
+import org.apache.james.mailbox.store.StoreMailboxManager;
+import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.StoreRightManager;
-import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
-import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
 import org.apache.james.mailbox.store.search.MessageSearchIndex;
 
 /**
  * OpenJPA implementation of Mailbox
  */
-public class OpenJPAMessageManager extends JPAMessageManager {
-
-    private final AdvancedFeature feature;
-
-    public enum AdvancedFeature {
-        None,
-        Streaming,
-        Encryption
-    }
+public class OpenJPAMessageManager extends StoreMessageManager {
 
     public OpenJPAMessageManager(MailboxSessionMapperFactory mapperFactory,
                                  MessageSearchIndex index, EventBus eventBus,
-                                 MailboxPathLocker locker, Mailbox mailbox, AdvancedFeature f,
+                                 MailboxPathLocker locker, Mailbox mailbox,
                                  QuotaManager quotaManager, QuotaRootResolver quotaRootResolver, MessageParser messageParser,
                                  MessageId.Factory messageIdFactory, BatchSizes batchSizes,
                                  StoreRightManager storeRightManager) {
-
-        super(mapperFactory,  index, eventBus, locker, mailbox, quotaManager, quotaRootResolver,
-            messageParser, messageIdFactory, batchSizes, storeRightManager);
-        this.feature = f;
+        super(StoreMailboxManager.DEFAULT_NO_MESSAGE_CAPABILITIES, mapperFactory, index, eventBus, locker, mailbox,
+            quotaManager, quotaRootResolver, messageParser, messageIdFactory, batchSizes, storeRightManager, PreDeletionHooks.NO_PRE_DELETION_HOOK,
+            new OpenJPAMessageFactory(OpenJPAMessageFactory.AdvancedFeature.None));
     }
 
+    /**
+     * Support user flags
+     */
     @Override
-    protected MailboxMessage createMessage(Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, List<MessageAttachment> attachments) throws MailboxException {
-        switch (feature) {
-        case Streaming:
-            return new JPAStreamingMailboxMessage(JPAMailbox.from(getMailboxEntity()), internalDate, size, flags, content, bodyStartOctet, propertyBuilder);
-        case Encryption:
-            return new JPAEncryptedMailboxMessage(JPAMailbox.from(getMailboxEntity()), internalDate, size, flags, content, bodyStartOctet, propertyBuilder);
-        default:
-            return super.createMessage(internalDate, size, bodyStartOctet, content, flags,  propertyBuilder, attachments);
-        }
-       
+    protected Flags getPermanentFlags(MailboxSession session) {
+        Flags flags =  super.getPermanentFlags(session);
+        flags.add(Flags.Flag.USER);
+        return flags;
     }
-
-    
-
 }
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
index ef84c37..d8d1a96 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
@@ -17,6 +17,7 @@ import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
 import org.apache.james.mailbox.store.BatchSizes;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
+import org.apache.james.mailbox.store.MessageFactory;
 import org.apache.james.mailbox.store.PreDeletionHooks;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.StoreRightManager;
@@ -41,7 +42,7 @@ public class InMemoryMessageManager extends StoreMessageManager {
                                   PreDeletionHooks preDeletionHooks) {
 
         super(InMemoryMailboxManager.MESSAGE_CAPABILITIES, mapperFactory, index, eventBus, locker, mailbox, quotaManager, quotaRootResolver,
-            messageParser, messageIdFactory, batchSizes, storeRightManager, preDeletionHooks);
+            messageParser, messageIdFactory, batchSizes, storeRightManager, preDeletionHooks, new MessageFactory.StoreMessageFactory());
         this.mapperFactory = (InMemoryMailboxSessionMapperFactory) mapperFactory;
     }
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageFactory.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageFactory.java
new file mode 100644
index 0000000..c2b3b2e
--- /dev/null
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageFactory.java
@@ -0,0 +1,50 @@
+/****************************************************************
+ * 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.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.store;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.mail.Flags;
+import javax.mail.internet.SharedInputStream;
+
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.Mailbox;
+import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.store.mail.model.MailboxMessage;
+import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
+
+public interface MessageFactory<T extends MailboxMessage> {
+    T createMessage(MessageId messageId, Mailbox mailbox, Date internalDate, int size, int bodyStartOctet,
+                                 SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder,
+                                 List<MessageAttachment> attachments) throws MailboxException;
+
+    class StoreMessageFactory implements MessageFactory<SimpleMailboxMessage> {
+        @Override
+        public SimpleMailboxMessage createMessage(MessageId messageId, Mailbox mailbox, Date internalDate, int size,
+                                            int bodyStartOctet, SharedInputStream content, Flags flags,
+                                            PropertyBuilder propertyBuilder, List<MessageAttachment> attachments) {
+            return new SimpleMailboxMessage(messageId, internalDate, size, bodyStartOctet, content, flags, propertyBuilder,
+                mailbox.getMailboxId(), attachments);
+        }
+    }
+}
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 4534422..aad8189 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
@@ -249,7 +249,7 @@ public class StoreMailboxManager implements MailboxManager {
         return new StoreMessageManager(DEFAULT_NO_MESSAGE_CAPABILITIES, getMapperFactory(), getMessageSearchIndex(), getEventBus(),
                 getLocker(), mailbox, quotaManager,
             getQuotaComponents().getQuotaRootResolver(), getMessageParser(), getMessageIdFactory(), configuration.getBatchSizes(),
-            getStoreRightManager(), preDeletionHooks);
+            getStoreRightManager(), preDeletionHooks, new MessageFactory.StoreMessageFactory());
     }
 
     @Override
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
index 19d2106..f37279a 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
@@ -85,7 +85,6 @@ import org.apache.james.mailbox.store.mail.MessageMapper.FetchType;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
 import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
-import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
 import org.apache.james.mailbox.store.quota.QuotaChecker;
 import org.apache.james.mailbox.store.search.MessageSearchIndex;
 import org.apache.james.mailbox.store.streaming.CountingInputStream;
@@ -164,12 +163,13 @@ public class StoreMessageManager implements MessageManager {
     private final Factory messageIdFactory;
     private final BatchSizes batchSizes;
     private final PreDeletionHooks preDeletionHooks;
+    private final MessageFactory messageFactory;
 
-    public StoreMessageManager(EnumSet<MailboxManager.MessageCapabilities> messageCapabilities, MailboxSessionMapperFactory mapperFactory,
+    public StoreMessageManager(EnumSet<MessageCapabilities> messageCapabilities, MailboxSessionMapperFactory mapperFactory,
                                MessageSearchIndex index, EventBus eventBus,
                                MailboxPathLocker locker, Mailbox mailbox,
-                               QuotaManager quotaManager, QuotaRootResolver quotaRootResolver, MessageParser messageParser, MessageId.Factory messageIdFactory, BatchSizes batchSizes,
-                               StoreRightManager storeRightManager, PreDeletionHooks preDeletionHooks) {
+                               QuotaManager quotaManager, QuotaRootResolver quotaRootResolver, MessageParser messageParser, Factory messageIdFactory, BatchSizes batchSizes,
+                               StoreRightManager storeRightManager, PreDeletionHooks preDeletionHooks, MessageFactory messageFactory) {
         this.messageCapabilities = messageCapabilities;
         this.eventBus = eventBus;
         this.mailbox = mailbox;
@@ -183,6 +183,7 @@ public class StoreMessageManager implements MessageManager {
         this.batchSizes = batchSizes;
         this.storeRightManager = storeRightManager;
         this.preDeletionHooks = preDeletionHooks;
+        this.messageFactory = messageFactory;
     }
 
     /**
@@ -500,13 +501,6 @@ public class StoreMessageManager implements MessageManager {
         }
     }
 
-    /**
-     * Create a new {@link MailboxMessage} for the given data
-     */
-    protected MailboxMessage createMessage(Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, List<MessageAttachment> attachments) throws MailboxException {
-        return new SimpleMailboxMessage(messageIdFactory.generate(), internalDate, size, bodyStartOctet, content, flags, propertyBuilder, getMailboxEntity().getMailboxId(), attachments);
-    }
-
     @Override
     public boolean isWriteable(MailboxSession session) throws MailboxException {
         return storeRightManager.isReadWrite(session, mailbox, getSharedPermanentFlags(session));
@@ -669,7 +663,7 @@ public class StoreMessageManager implements MessageManager {
 
         return mapperFactory.getMessageMapper(session).execute(() -> {
             List<MessageAttachment> attachments = storeAttachments(messageId, content, session);
-            MailboxMessage message = createMessage(internalDate, size, bodyStartOctet, content, flags, propertyBuilder, attachments);
+            MailboxMessage message = messageFactory.createMessage(messageId, getMailboxEntity(), internalDate, size, bodyStartOctet, content, flags, propertyBuilder, attachments);
             MessageMetaData metadata = messageMapper.add(getMailboxEntity(), message);
             return Pair.of(metadata, attachments);
         });


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


[james-project] 11/37: JAMES-2997 step #9 CassandraAttachmentDAO should not rely on bytes field

Posted by bt...@apache.org.
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 6a75ba790357243cdd8997b2a964155baab39903
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Jan 17 14:06:52 2020 +0700

    JAMES-2997 step #9 CassandraAttachmentDAO should not rely on bytes field
---
 .../apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java   | 1 -
 1 file changed, 1 deletion(-)

diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
index 74fe75c..dced0a0 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
@@ -21,7 +21,6 @@ package org.apache.james.mailbox.cassandra.mail;
 
 import static org.apache.james.blob.api.BlobStore.StoragePolicy.LOW_COST;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Collection;


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


[james-project] 06/37: JAMES-2997 step #4 Implement AttachmentMapper::loadAttachmentContent

Posted by bt...@apache.org.
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 0d0607defb545be4ee0591c6cd23828a8e29defc
Author: Matthieu Baechler <ma...@apache.org>
AuthorDate: Mon Dec 9 11:39:59 2019 +0100

    JAMES-2997 step #4 Implement AttachmentMapper::loadAttachmentContent
    
    Both for Memory and Cassandra
---
 .../java/org/apache/james/mailbox/model/Attachment.java  |  7 -------
 .../org/apache/james/mailbox/model/AttachmentTest.java   |  4 ++--
 .../cassandra/mail/CassandraAttachmentMapper.java        | 11 +++++++++++
 .../mail/CassandraMailboxManagerAttachmentTest.java      |  4 +++-
 .../mailbox/inmemory/mail/InMemoryAttachmentMapper.java  | 16 ++++++++++++++++
 .../mail/InMemoryMailboxManagerAttachmentTest.java       |  4 +++-
 .../james/mailbox/store/mail/AttachmentMapper.java       |  4 +---
 .../store/AbstractMailboxManagerAttachmentTest.java      |  3 +++
 .../mailbox/store/SearchUtilsMultipartMixedTest.java     |  4 +++-
 .../james/mailbox/store/SearchUtilsRFC822Test.java       |  4 +++-
 .../org/apache/james/mailbox/store/SearchUtilsTest.java  |  4 +++-
 .../mailbox/store/mail/model/impl/MessageParserTest.java |  3 +++
 .../jmap/cassandra/CassandraSetMessagesMethodTest.java   |  4 +++-
 .../draft/methods/integration/SetMessagesMethodTest.java |  4 +++-
 .../james/jmap/memory/MemorySetMessagesMethodTest.java   |  4 ++--
 .../rabbitmq/RabbitMQAwsS3SetMessagesMethodTest.java     |  4 +++-
 16 files changed, 62 insertions(+), 22 deletions(-)

diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
index 6cd578a..eb017c9 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
@@ -19,9 +19,6 @@
 
 package org.apache.james.mailbox.model;
 
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
 import java.util.Arrays;
 
 import com.google.common.base.MoreObjects;
@@ -103,10 +100,6 @@ public class Attachment {
         return size;
     }
 
-    public InputStream getStream() throws IOException {
-        return new ByteArrayInputStream(bytes);
-    }
-
     /**
      * Be careful the returned array is not a copy of the attachment byte array.
      * Mutating it will mutate the attachment!
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java
index 85beb1a..7d85b29 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/AttachmentTest.java
@@ -33,7 +33,7 @@ import org.junit.jupiter.api.Test;
 class AttachmentTest {
 
     private static Charset CHARSET = StandardCharsets.UTF_8;
-
+/*
     @Test
     void streamShouldBeConsumedOneTime() throws Exception {
         String input = "mystream";
@@ -135,5 +135,5 @@ class AttachmentTest {
 
         assertThat(attachment.getSize()).isEqualTo(input.getBytes(CHARSET).length);
     }
-
+*/
 }
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
index 9c7f0b2..03a1461 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
@@ -21,6 +21,9 @@ package org.apache.james.mailbox.cassandra.mail;
 
 import static org.apache.james.blob.api.BlobStore.StoragePolicy.LOW_COST;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.Collection;
 import java.util.List;
 
@@ -92,6 +95,14 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
             .block();
     }
 
+    @Override
+    public InputStream loadAttachmentContent(AttachmentId attachmentId) throws AttachmentNotFoundException, IOException {
+        return attachmentDAOV2.getAttachment(attachmentId)
+            .map(daoAttachment -> blobStore.read(blobStore.getDefaultBucketName(), daoAttachment.getBlobId()))
+            .blockOptional()
+            .orElseThrow(() -> new AttachmentNotFoundException(attachmentId.toString()));
+    }
+
     public Mono<Attachment> getAttachmentsAsMono(AttachmentId attachmentId) {
         return getAttachmentInternal(attachmentId)
             .switchIfEmpty(ReactorUtils.executeAndEmpty(() -> logNotFound((attachmentId))));
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java
index 1c90f3a..2e4821e 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java
@@ -56,7 +56,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
 class CassandraMailboxManagerAttachmentTest extends AbstractMailboxManagerAttachmentTest {
-
+/*
     @RegisterExtension
     static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(MailboxAggregateModule.MODULE);
 
@@ -117,4 +117,6 @@ class CassandraMailboxManagerAttachmentTest extends AbstractMailboxManagerAttach
     protected AttachmentMapperFactory getAttachmentMapperFactory() {
         return mailboxSessionMapperFactory;
     }
+
+ */
 }
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
index 3267824..7b07dfb 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
@@ -18,6 +18,9 @@
  ****************************************************************/
 package org.apache.james.mailbox.inmemory.mail;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -44,11 +47,13 @@ public class InMemoryAttachmentMapper implements AttachmentMapper {
     
     private static final int INITIAL_SIZE = 128;
     private final Map<AttachmentId, Attachment> attachmentsById;
+    private final Map<AttachmentId, byte[]> attachmentsRawContentById;
     private final Multimap<AttachmentId, MessageId> messageIdsByAttachmentId;
     private final Multimap<AttachmentId, Username> ownersByAttachmentId;
 
     public InMemoryAttachmentMapper() {
         attachmentsById = new ConcurrentHashMap<>(INITIAL_SIZE);
+        attachmentsRawContentById = new ConcurrentHashMap<>(INITIAL_SIZE);
         messageIdsByAttachmentId = Multimaps.synchronizedSetMultimap(HashMultimap.create());
         ownersByAttachmentId = Multimaps.synchronizedSetMultimap(HashMultimap.create());
     }
@@ -78,6 +83,7 @@ public class InMemoryAttachmentMapper implements AttachmentMapper {
     public Mono<Void> storeAttachmentForOwner(Attachment attachment, Username owner) {
         return Mono.fromRunnable(() -> {
             attachmentsById.put(attachment.getAttachmentId(), attachment);
+            attachmentsRawContentById.put(attachment.getAttachmentId(), attachment.getBytes());
             ownersByAttachmentId.put(attachment.getAttachmentId(), owner);
         });
     }
@@ -96,6 +102,7 @@ public class InMemoryAttachmentMapper implements AttachmentMapper {
     public void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId) throws MailboxException {
         for (Attachment attachment: attachments) {
             attachmentsById.put(attachment.getAttachmentId(), attachment);
+            attachmentsRawContentById.put(attachment.getAttachmentId(), attachment.getBytes());
             messageIdsByAttachmentId.put(attachment.getAttachmentId(), ownerMessageId);
         }
     }
@@ -109,4 +116,13 @@ public class InMemoryAttachmentMapper implements AttachmentMapper {
     public Collection<Username> getOwners(final AttachmentId attachmentId) throws MailboxException {
         return ownersByAttachmentId.get(attachmentId);
     }
+
+    @Override
+    public InputStream loadAttachmentContent(AttachmentId attachmentId) throws AttachmentNotFoundException, IOException {
+        byte[] buf = attachmentsRawContentById.get(attachmentId);
+        if (buf == null) {
+            throw new AttachmentNotFoundException(attachmentId.toString());
+        }
+        return new ByteArrayInputStream(buf);
+    }
 }
\ No newline at end of file
diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxManagerAttachmentTest.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxManagerAttachmentTest.java
index 4c1c16e..dcf5c69 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxManagerAttachmentTest.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxManagerAttachmentTest.java
@@ -35,10 +35,10 @@ import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
 import org.junit.jupiter.api.BeforeEach;
 
 class InMemoryMailboxManagerAttachmentTest extends AbstractMailboxManagerAttachmentTest {
+/*
     InMemoryMailboxManager mailboxManager;
     InMemoryMailboxManager parseFailingMailboxManager;
 
-
     @BeforeEach
     void setup() throws Exception {
         MessageParser failingMessageParser = mock(MessageParser.class);
@@ -80,4 +80,6 @@ class InMemoryMailboxManagerAttachmentTest extends AbstractMailboxManagerAttachm
     protected AttachmentMapperFactory getAttachmentMapperFactory() {
         return (AttachmentMapperFactory) mailboxManager.getMapperFactory();
     }
+
+ */
 }
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
index eb495ae..4e64abc 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
@@ -34,9 +34,7 @@ import org.reactivestreams.Publisher;
 
 public interface AttachmentMapper extends Mapper {
 
-    default InputStream loadAttachmentContent(AttachmentId attachmentId) throws AttachmentNotFoundException, IOException {
-        return getAttachment(attachmentId).getStream();
-    }
+    InputStream loadAttachmentContent(AttachmentId attachmentId) throws AttachmentNotFoundException, IOException;
 
     Attachment getAttachment(AttachmentId attachmentId) throws AttachmentNotFoundException;
 
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
index a55deae..a6c864d 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
@@ -51,6 +51,7 @@ import com.github.fge.lambdas.Throwing;
 import com.google.common.collect.ImmutableList;
 
 public abstract class AbstractMailboxManagerAttachmentTest {
+/*
     private static final Username USERNAME = Username.of("user@domain.tld");
 
     private MailboxManager mailboxManager;
@@ -198,5 +199,7 @@ public abstract class AbstractMailboxManagerAttachmentTest {
         List<MessageAttachment> attachments = messages.next().getAttachments();
         assertThat(attachments).hasSize(0);
     }
+
+ */
 }
 
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsMultipartMixedTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsMultipartMixedTest.java
index ff26f19..126ff8a 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsMultipartMixedTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsMultipartMixedTest.java
@@ -38,7 +38,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 class SearchUtilsMultipartMixedTest {
-
+/*
     static final String SAMPLE_INNER_MAIL_BODY_ONE = "far a modern quill doth come too";
 
     static final String SAMPLE_PART_ONE = "The better angel is a man right fair,\r\n";
@@ -229,4 +229,6 @@ class SearchUtilsMultipartMixedTest {
         assertThat(messageSearches.isMatch(SearchQuery
                 .mailContains(SAMPLE_PART_TWO_FIELD), row, recent)).isTrue();
     }
+
+ */
 }
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsRFC822Test.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsRFC822Test.java
index 62b8921..c02ff3b 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsRFC822Test.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsRFC822Test.java
@@ -38,7 +38,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 class SearchUtilsRFC822Test {
-
+/*
     static final String FROM_ADDRESS = "Harry <harry@example.org";
 
     static final String SUBJECT_PART = "Mixed";
@@ -127,4 +127,6 @@ class SearchUtilsRFC822Test {
         assertThat(messageSearches.isMatch(SearchQuery.mailContains(SUBJECT_PART),
                 row, recent)).isTrue();
     }
+
+ */
 }
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java
index d263af7..579201d 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java
@@ -44,7 +44,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 class SearchUtilsTest {
-
+/*
     static final String RHUBARD = "Rhubard";
 
     static final String CUSTARD = "Custard";
@@ -810,4 +810,6 @@ class SearchUtilsTest {
         assertThat(messageSearches.isMatch(SearchQuery.address(AddressType.From, "user-from@domain.org"), row, recent)).isFalse();
     }
 
+
+ */
 }
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
index a7cecc19..80b4f6a 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
@@ -42,6 +42,7 @@ import org.junit.jupiter.api.Test;
 
 class MessageParserTest {
 
+    /*
     MessageParser testee;
 
     @BeforeEach
@@ -317,4 +318,6 @@ class MessageParserTest {
         assertThat(result).hasSize(1)
             .allMatch(attachment -> attachment.getAttachment().getType().equals(MDN.DISPOSITION_CONTENT_TYPE));
     }
+
+     */
 }
diff --git a/server/protocols/jmap-draft-integration-testing/cassandra-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMessagesMethodTest.java b/server/protocols/jmap-draft-integration-testing/cassandra-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMessagesMethodTest.java
index de89e9f..17f4360 100644
--- a/server/protocols/jmap-draft-integration-testing/cassandra-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMessagesMethodTest.java
+++ b/server/protocols/jmap-draft-integration-testing/cassandra-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMessagesMethodTest.java
@@ -32,7 +32,7 @@ import org.junit.Rule;
 import org.junit.Test;
 
 public class CassandraSetMessagesMethodTest extends SetMessagesMethodTest {
-
+/*
     @Rule
     public DockerCassandraRule cassandra = new DockerCassandraRule();
 
@@ -60,4 +60,6 @@ public class CassandraSetMessagesMethodTest extends SetMessagesMethodTest {
     public void setMessagesWithABigBodyShouldReturnCreatedMessageWhenSendingMessage() {
 
     }
+
+ */
 }
diff --git a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
index c83fdca..d11172e 100644
--- a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
+++ b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
@@ -140,7 +140,7 @@ import io.restassured.http.ContentType;
 import io.restassured.parsing.Parser;
 
 public abstract class SetMessagesMethodTest {
-    private static final String FORWARDED = "$Forwarded";
+/*    private static final String FORWARDED = "$Forwarded";
     private static final int _1MB = 1024 * 1024;
     private static final Username USERNAME = Username.of("username@" + DOMAIN);
     private static final String ALIAS_OF_USERNAME_MAIL = "alias@" + DOMAIN;
@@ -6147,4 +6147,6 @@ public abstract class SetMessagesMethodTest {
         assertThat(receivedMimeMessageId).isEqualTo(creationMimeMessageId);
     }
 
+
+ */
 }
diff --git a/server/protocols/jmap-draft-integration-testing/memory-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/memory/MemorySetMessagesMethodTest.java b/server/protocols/jmap-draft-integration-testing/memory-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/memory/MemorySetMessagesMethodTest.java
index 2d3e693..443e044 100644
--- a/server/protocols/jmap-draft-integration-testing/memory-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/memory/MemorySetMessagesMethodTest.java
+++ b/server/protocols/jmap-draft-integration-testing/memory-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/memory/MemorySetMessagesMethodTest.java
@@ -30,7 +30,7 @@ import org.apache.james.mailbox.model.MessageId;
 import org.junit.Rule;
 
 public class MemorySetMessagesMethodTest extends SetMessagesMethodTest {
-
+/*
     @Rule
     public MemoryJmapTestRule memoryJmap = new MemoryJmapTestRule();
 
@@ -47,5 +47,5 @@ public class MemorySetMessagesMethodTest extends SetMessagesMethodTest {
     protected MessageId randomMessageId() {
         return new InMemoryMessageId.Factory().fromString(String.valueOf(ThreadLocalRandom.current().nextInt(100000) + 100));
     }
-
+*/
 }
diff --git a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SetMessagesMethodTest.java b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SetMessagesMethodTest.java
index 0e6170c..97d76a7 100644
--- a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SetMessagesMethodTest.java
+++ b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SetMessagesMethodTest.java
@@ -32,7 +32,7 @@ import org.junit.Rule;
 import org.junit.Test;
 
 public class RabbitMQAwsS3SetMessagesMethodTest extends SetMessagesMethodTest {
-
+/*
     @Rule
     public DockerCassandraRule cassandra = new DockerCassandraRule();
 
@@ -61,5 +61,7 @@ public class RabbitMQAwsS3SetMessagesMethodTest extends SetMessagesMethodTest {
     public void setMessagesWithABigBodyShouldReturnCreatedMessageWhenSendingMessage() {
 
     }
+    
+ */
 }
 


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


[james-project] 34/37: JAMES-2997 ReactorUtils::toChunk should be done on an elastic scheduler

Posted by bt...@apache.org.
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 4bc79a94da9fa2f997d0d1c4088d671fbdc381d4
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed Apr 1 22:00:09 2020 +0700

    JAMES-2997 ReactorUtils::toChunk should be done on an elastic scheduler
---
 .../src/main/java/org/apache/james/jmap/http/DownloadRoutes.java       | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/DownloadRoutes.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/DownloadRoutes.java
index 160bdde..ddabcf7 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/DownloadRoutes.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/http/DownloadRoutes.java
@@ -228,7 +228,8 @@ public class DownloadRoutes implements JMAPRoutes {
             .header(CONTENT_TYPE, blobContentType)
             .status(OK)
             .send(ReactorUtils.toChunks(stream, BUFFER_SIZE)
-                .map(Unpooled::wrappedBuffer))
+                .map(Unpooled::wrappedBuffer)
+                .subscribeOn(Schedulers.elastic()))
             .then();
     }
 


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


[james-project] 23/37: JAMES-2997 Renable MessageParserTest

Posted by bt...@apache.org.
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 18530dbe80dfda0ad0104dd7cf475e6855496f8d
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 20 19:11:24 2020 +0700

    JAMES-2997 Renable MessageParserTest
---
 .../store/mail/model/impl/MessageParserTest.java   | 99 ++++++++++------------
 1 file changed, 43 insertions(+), 56 deletions(-)

diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
index 80b4f6a..32eb1eb 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
@@ -25,9 +25,8 @@ import java.io.ByteArrayInputStream;
 import java.util.List;
 import java.util.Optional;
 
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.Cid;
-import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mdn.MDN;
 import org.apache.james.mdn.MDNReport;
 import org.apache.james.mdn.action.mode.DispositionActionMode;
@@ -41,8 +40,6 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 class MessageParserTest {
-
-    /*
     MessageParser testee;
 
     @BeforeEach
@@ -52,21 +49,21 @@ class MessageParserTest {
 
     @Test
     void getAttachmentsShouldBeEmptyWhenNoAttachment() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/noAttachment.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/noAttachment.eml"));
 
         assertThat(attachments).isEmpty();
     }
 
     @Test
     void getAttachmentsShouldRetrieveAttachmentsWhenOneAttachment() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeTextInlined.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeTextInlined.eml"));
 
         assertThat(attachments).hasSize(1);
     }
 
     @Test
     void getAttachmentsShouldRetrieveAttachmentNameWhenOne() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeTextInlined.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeTextInlined.eml"));
 
         assertThat(attachments).hasSize(1);
         Optional<String> expectedName = Optional.of("exploits_of_a_mom.png");
@@ -75,14 +72,14 @@ class MessageParserTest {
 
     @Test
     void getAttachmentsShouldRetrieveAttachmentNameWhenOneContainingNonASCIICharacters() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/messageWithNonASCIIFilenameAttachment.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/messageWithNonASCIIFilenameAttachment.eml"));
         assertThat(attachments).hasSize(1);
         assertThat(attachments.get(0).getName()).contains("ديناصور.odt");
     }
 
     @Test
     void getAttachmentsShouldRetrieveEmptyNameWhenNone() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentWithoutName.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentWithoutName.eml"));
 
         assertThat(attachments).hasSize(1);
         assertThat(attachments.get(0).getName()).isEqualTo(Optional.empty());
@@ -90,79 +87,71 @@ class MessageParserTest {
 
     @Test
     void getAttachmentsShouldNotFailWhenContentTypeIsNotHere() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentWithoutContentType.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentWithoutContentType.eml"));
 
         assertThat(attachments).hasSize(1);
-        assertThat(attachments.get(0).getAttachment().getType()).isEqualTo("application/octet-stream");
+        assertThat(attachments.get(0).getContentType()).isEqualTo("application/octet-stream");
     }
 
     @Test
     void getAttachmentsShouldNotFailWhenContentTypeIsEmpty() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentWithEmptyContentType.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentWithEmptyContentType.eml"));
 
         assertThat(attachments).hasSize(1);
-        assertThat(attachments.get(0).getAttachment().getType()).isEqualTo("application/octet-stream");
+        assertThat(attachments.get(0).getContentType()).isEqualTo("application/octet-stream");
     }
 
     @Test
     void getAttachmentsShouldRetrieveTheAttachmentContentTypeWhenOneAttachment() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeTextInlined.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeTextInlined.eml"));
 
         assertThat(attachments).hasSize(1);
-        assertThat(attachments.get(0).getAttachment().getType()).isEqualTo("application/octet-stream");
+        assertThat(attachments.get(0).getContentType()).isEqualTo("application/octet-stream");
     }
 
     @Test
     void retrieveAttachmentsShouldNotFailOnMessagesWithManyHeaders() throws Exception {
-        List<MessageAttachment> messageAttachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/mailWithManyHeaders.eml"));
+        List<ParsedAttachment> messageAttachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/mailWithManyHeaders.eml"));
 
         assertThat(messageAttachments).hasSize(1);
     }
 
     @Test
     void retrieveAttachmentsShouldNotFailOnMessagesWithLongHeaders() throws Exception {
-        List<MessageAttachment> messageAttachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/mailWithLongHeaders.eml"));
+        List<ParsedAttachment> messageAttachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/mailWithLongHeaders.eml"));
 
         assertThat(messageAttachments).hasSize(1);
     }
 
     @Test
     void getAttachmentsShouldRetrieveTheAttachmentContentTypeWhenOneAttachmentWithSimpleContentType() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentWithSimpleContentType.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentWithSimpleContentType.eml"));
 
         assertThat(attachments).hasSize(1);
-        assertThat(attachments.get(0).getAttachment().getType()).isEqualTo("application/octet-stream");
-    }
-
-    @Test
-    void getAttachmentsShouldRetrieveTheAttachmentSizeWhenOneAttachment() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeTextInlined.eml"));
-
-        assertThat(attachments).hasSize(1);
-        assertThat(attachments.get(0).getAttachment().getSize()).isEqualTo(3071);
+        assertThat(attachments.get(0).getContentType()).isEqualTo("application/octet-stream");
     }
 
     @Test
     void getAttachmentsShouldReturnTheExpectedAttachment() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeTextInlined.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeTextInlined.eml"));
 
-        Attachment attachment = attachments.get(0).getAttachment();
-        assertThat(attachment.getStream()).hasSameContentAs(ClassLoader.getSystemResourceAsStream("eml/gimp.png"));
+        ParsedAttachment attachment = attachments.get(0);
+        assertThat(attachment.getContent()).hasSameContentAs(ClassLoader.getSystemResourceAsStream("eml/gimp.png"));
     }
 
     @Test
     void getAttachmentsShouldRetrieveAttachmentsWhenTwo() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/twoAttachments.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/twoAttachments.eml"));
 
         assertThat(attachments).hasSize(2);
     }
 
     @Test
     void retrieveAttachmentShouldUseFilenameAsNameWhenNoName() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/filenameOnly.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/filenameOnly.eml"));
 
         assertThat(attachments).hasSize(1)
-            .extracting(MessageAttachment::getName)
+            .extracting(ParsedAttachment::getName)
             .allMatch(Optional::isPresent)
             .extracting(Optional::get)
             .containsExactly("inventory.csv");
@@ -170,10 +159,10 @@ class MessageParserTest {
 
     @Test
     void retrieveAttachmentShouldUseNameWhenBothNameAndFilename() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/filenameAndName.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/filenameAndName.eml"));
 
         assertThat(attachments).hasSize(1)
-            .extracting(MessageAttachment::getName)
+            .extracting(ParsedAttachment::getName)
             .allMatch(Optional::isPresent)
             .extracting(Optional::get)
             .containsExactly("good.csv");
@@ -181,21 +170,21 @@ class MessageParserTest {
 
     @Test
     void getAttachmentsShouldRetrieveEmbeddedAttachmentsWhenSome() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/embeddedAttachmentWithInline.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/embeddedAttachmentWithInline.eml"));
 
         assertThat(attachments).hasSize(1);
     }
 
     @Test
     void getAttachmentsShouldRetrieveInlineAttachmentsWhenSome() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/embeddedAttachmentWithAttachment.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/embeddedAttachmentWithAttachment.eml"));
 
         assertThat(attachments).hasSize(1);
     }
 
     @Test
     void getAttachmentsShouldRetrieveTheAttachmentCIDWhenOne() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneInlinedAttachment.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneInlinedAttachment.eml"));
 
         assertThat(attachments).hasSize(1);
         assertThat(attachments.get(0).getCid()).isEqualTo(Optional.of(Cid.from("part1.37A15C92.A7C3488D@linagora.com")));
@@ -203,7 +192,7 @@ class MessageParserTest {
 
     @Test
     void getAttachmentsShouldSetInlineWhenOneInlinedAttachment() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneInlinedAttachment.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneInlinedAttachment.eml"));
 
         assertThat(attachments).hasSize(1);
         assertThat(attachments.get(0).isInline()).isTrue();
@@ -211,63 +200,63 @@ class MessageParserTest {
 
     @Test
     void getAttachementsShouldRetrieveHtmlAttachementsWhenSome() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneHtmlAttachmentAndSomeTextInlined.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneHtmlAttachmentAndSomeTextInlined.eml"));
 
         assertThat(attachments).hasSize(1);
     }
 
     @Test
     void getAttachementsShouldRetrieveAttachmentsWhenSomeAreInTheMultipartAlternative() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/invitationEmailFromOP.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/invitationEmailFromOP.eml"));
         
         assertThat(attachments).hasSize(7);
     }
 
     @Test
     void getAttachmentsShouldNotConsiderUnknownContentDispositionAsAttachments() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/unknownDisposition.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/unknownDisposition.eml"));
 
         assertThat(attachments).hasSize(0);
     }
 
     @Test
     void getAttachmentsShouldConsiderNoContentDispositionAsAttachmentsWhenCID() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/noContentDispositionWithCID.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/noContentDispositionWithCID.eml"));
 
         assertThat(attachments).hasSize(1);
     }
 
     @Test
     void getAttachmentsShouldRetrieveAttachmentsWhenNoCidForInlined() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneInlinedAttachmentWithNoCid.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneInlinedAttachmentWithNoCid.eml"));
 
         assertThat(attachments).hasSize(1);
     }
 
     @Test
     void getAttachmentsShouldRetrieveAttachmentsWhenEmptyCidForInlined() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneInlinedAttachmentWithEmptyCid.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneInlinedAttachmentWithEmptyCid.eml"));
 
         assertThat(attachments).hasSize(1);
     }
 
     @Test
     void getAttachmentsShouldRetrieveAttachmentsWhenBlankCidForInlined() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneInlinedAttachmentWithBlankCid.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneInlinedAttachmentWithBlankCid.eml"));
 
         assertThat(attachments).hasSize(1);
     }
 
     @Test
     void getAttachmentsShouldRetrieveAttachmentsWhenOneFailOnWrongContentDisposition() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/multiAttachmentsWithOneWrongContentDisposition.eml"));
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/multiAttachmentsWithOneWrongContentDisposition.eml"));
 
         assertThat(attachments).hasSize(2);
     }
 
     @Test
     void getAttachmentsShouldRetrieveOneAttachmentWhenMessageWithAttachmentContentDisposition() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(
             ClassLoader.getSystemResourceAsStream("eml/emailWithOnlyAttachment.eml"));
 
         assertThat(attachments).hasSize(1);
@@ -275,21 +264,21 @@ class MessageParserTest {
 
     @Test
     void getAttachmentsShouldConsiderICSAsAttachments() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(
             ClassLoader.getSystemResourceAsStream("eml/calendar.eml"));
 
         assertThat(attachments)
             .hasSize(1)
-            .allMatch(messageAttachment -> messageAttachment.getAttachment().getType().equals("text/calendar"));
+            .allMatch(messageAttachment -> messageAttachment.getContentType().equals("text/calendar"));
     }
 
     @Test
     void gpgSignatureShouldBeConsideredAsAnAttachment() throws Exception {
-        List<MessageAttachment> attachments = testee.retrieveAttachments(
+        List<ParsedAttachment> attachments = testee.retrieveAttachments(
             ClassLoader.getSystemResourceAsStream("eml/signedMessage.eml"));
 
         assertThat(attachments).hasSize(2)
-            .extracting(MessageAttachment::getName)
+            .extracting(ParsedAttachment::getName)
             .allMatch(Optional::isPresent)
             .extracting(Optional::get)
             .containsOnly("message suivi", "signature.asc");
@@ -314,10 +303,8 @@ class MessageParserTest {
             .asMime4JMessageBuilder()
             .build();
 
-        List<MessageAttachment> result = testee.retrieveAttachments(new ByteArrayInputStream(DefaultMessageWriter.asBytes(message)));
+        List<ParsedAttachment> result = testee.retrieveAttachments(new ByteArrayInputStream(DefaultMessageWriter.asBytes(message)));
         assertThat(result).hasSize(1)
-            .allMatch(attachment -> attachment.getAttachment().getType().equals(MDN.DISPOSITION_CONTENT_TYPE));
+            .allMatch(attachment -> attachment.getContentType().equals(MDN.DISPOSITION_CONTENT_TYPE));
     }
-
-     */
 }


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


[james-project] 01/37: JAMES-2997 Move james-server-utils InputStream in a dedicated io package

Posted by bt...@apache.org.
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 284451226fab86ff1948184991e9609bfc6018b7
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Jan 17 09:47:57 2020 +0700

    JAMES-2997 Move james-server-utils InputStream in a dedicated io package
---
 .../main/java/org/apache/james/mailbox/store/StoreMessageManager.java | 2 +-
 .../java/org/apache/james/blob/cassandra/CassandraBlobStoreTest.java  | 2 +-
 .../src/main/java/org/apache/james/blob/mail/MimeMessageStore.java    | 2 +-
 .../apache/james/server/core/MimeMessageInputStreamSourceTest.java    | 2 +-
 .../java/org/apache/james/util/{ => io}/BodyOffsetInputStream.java    | 2 +-
 .../org/apache/james/util/{ => io}/CountDownConsumeInputStream.java   | 2 +-
 .../main/java/org/apache/james/util/{ => io}/InputStreamUtils.java    | 2 +-
 .../main/java/org/apache/james/util/{ => io}/ZeroedInputStream.java   | 2 +-
 .../test/java/org/apache/james/util/BodyOffsetInputStreamTest.java    | 1 +
 .../src/test/java/org/apache/james/util/InputStreamUtilsTest.java     | 1 +
 .../james/jmap/draft/methods/integration/SetMessagesMethodTest.java   | 3 ++-
 .../jmap/draft/methods/integration/cucumber/DownloadStepdefs.java     | 2 +-
 .../james/jmap/draft/methods/integration/cucumber/UploadStepdefs.java | 4 ++--
 13 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
index bb139fc..f5e18c7 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
@@ -95,8 +95,8 @@ import org.apache.james.mime4j.stream.EntityState;
 import org.apache.james.mime4j.stream.MimeConfig;
 import org.apache.james.mime4j.stream.MimeTokenStream;
 import org.apache.james.mime4j.stream.RecursionMode;
-import org.apache.james.util.BodyOffsetInputStream;
 import org.apache.james.util.IteratorWrapper;
+import org.apache.james.util.io.BodyOffsetInputStream;
 import org.apache.james.util.streams.Iterators;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreTest.java b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreTest.java
index e073231..cba4df7 100644
--- a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreTest.java
+++ b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/CassandraBlobStoreTest.java
@@ -40,7 +40,7 @@ import org.apache.james.blob.api.HashBlobId;
 import org.apache.james.blob.api.MetricableBlobStore;
 import org.apache.james.blob.api.MetricableBlobStoreContract;
 import org.apache.james.blob.api.ObjectStoreException;
-import org.apache.james.util.ZeroedInputStream;
+import org.apache.james.util.io.ZeroedInputStream;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
diff --git a/server/blob/mail-store/src/main/java/org/apache/james/blob/mail/MimeMessageStore.java b/server/blob/mail-store/src/main/java/org/apache/james/blob/mail/MimeMessageStore.java
index 47194a7..7614928 100644
--- a/server/blob/mail-store/src/main/java/org/apache/james/blob/mail/MimeMessageStore.java
+++ b/server/blob/mail-store/src/main/java/org/apache/james/blob/mail/MimeMessageStore.java
@@ -45,7 +45,7 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.james.blob.api.BlobStore;
 import org.apache.james.blob.api.BlobType;
 import org.apache.james.blob.api.Store;
-import org.apache.james.util.BodyOffsetInputStream;
+import org.apache.james.util.io.BodyOffsetInputStream;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
diff --git a/server/container/core/src/test/java/org/apache/james/server/core/MimeMessageInputStreamSourceTest.java b/server/container/core/src/test/java/org/apache/james/server/core/MimeMessageInputStreamSourceTest.java
index 6a005a0..e98f597 100644
--- a/server/container/core/src/test/java/org/apache/james/server/core/MimeMessageInputStreamSourceTest.java
+++ b/server/container/core/src/test/java/org/apache/james/server/core/MimeMessageInputStreamSourceTest.java
@@ -24,7 +24,7 @@ import java.io.IOException;
 
 import javax.mail.MessagingException;
 
-import org.apache.james.util.ZeroedInputStream;
+import org.apache.james.util.io.ZeroedInputStream;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
 
diff --git a/server/container/util/src/main/java/org/apache/james/util/BodyOffsetInputStream.java b/server/container/util/src/main/java/org/apache/james/util/io/BodyOffsetInputStream.java
similarity index 99%
rename from server/container/util/src/main/java/org/apache/james/util/BodyOffsetInputStream.java
rename to server/container/util/src/main/java/org/apache/james/util/io/BodyOffsetInputStream.java
index e0bb63a..0efec22 100644
--- a/server/container/util/src/main/java/org/apache/james/util/BodyOffsetInputStream.java
+++ b/server/container/util/src/main/java/org/apache/james/util/io/BodyOffsetInputStream.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations      *
  * under the License.                                           *
  ****************************************************************/
-package org.apache.james.util;
+package org.apache.james.util.io;
 
 import java.io.IOException;
 import java.io.InputStream;
diff --git a/server/container/util/src/main/java/org/apache/james/util/CountDownConsumeInputStream.java b/server/container/util/src/main/java/org/apache/james/util/io/CountDownConsumeInputStream.java
similarity index 98%
rename from server/container/util/src/main/java/org/apache/james/util/CountDownConsumeInputStream.java
rename to server/container/util/src/main/java/org/apache/james/util/io/CountDownConsumeInputStream.java
index dbf952d..3d4e9f2 100644
--- a/server/container/util/src/main/java/org/apache/james/util/CountDownConsumeInputStream.java
+++ b/server/container/util/src/main/java/org/apache/james/util/io/CountDownConsumeInputStream.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.util;
+package org.apache.james.util.io;
 
 import java.io.IOException;
 import java.io.InputStream;
diff --git a/server/container/util/src/main/java/org/apache/james/util/InputStreamUtils.java b/server/container/util/src/main/java/org/apache/james/util/io/InputStreamUtils.java
similarity index 97%
rename from server/container/util/src/main/java/org/apache/james/util/InputStreamUtils.java
rename to server/container/util/src/main/java/org/apache/james/util/io/InputStreamUtils.java
index 0d96591..b500142 100644
--- a/server/container/util/src/main/java/org/apache/james/util/InputStreamUtils.java
+++ b/server/container/util/src/main/java/org/apache/james/util/io/InputStreamUtils.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.util;
+package org.apache.james.util.io;
 
 import java.io.InputStream;
 import java.io.SequenceInputStream;
diff --git a/server/container/util/src/main/java/org/apache/james/util/ZeroedInputStream.java b/server/container/util/src/main/java/org/apache/james/util/io/ZeroedInputStream.java
similarity index 97%
rename from server/container/util/src/main/java/org/apache/james/util/ZeroedInputStream.java
rename to server/container/util/src/main/java/org/apache/james/util/io/ZeroedInputStream.java
index f1583c7..65549b3 100644
--- a/server/container/util/src/main/java/org/apache/james/util/ZeroedInputStream.java
+++ b/server/container/util/src/main/java/org/apache/james/util/io/ZeroedInputStream.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations      *
  * under the License.                                           *
  ****************************************************************/
-package org.apache.james.util;
+package org.apache.james.util.io;
 
 import java.io.InputStream;
 
diff --git a/server/container/util/src/test/java/org/apache/james/util/BodyOffsetInputStreamTest.java b/server/container/util/src/test/java/org/apache/james/util/BodyOffsetInputStreamTest.java
index de5ca13..a2c1c03 100644
--- a/server/container/util/src/test/java/org/apache/james/util/BodyOffsetInputStreamTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/BodyOffsetInputStreamTest.java
@@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 
+import org.apache.james.util.io.BodyOffsetInputStream;
 import org.junit.jupiter.api.Test;
 
 class BodyOffsetInputStreamTest {
diff --git a/server/container/util/src/test/java/org/apache/james/util/InputStreamUtilsTest.java b/server/container/util/src/test/java/org/apache/james/util/InputStreamUtilsTest.java
index 7ed1f97..8890feb 100644
--- a/server/container/util/src/test/java/org/apache/james/util/InputStreamUtilsTest.java
+++ b/server/container/util/src/test/java/org/apache/james/util/InputStreamUtilsTest.java
@@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import java.io.ByteArrayInputStream;
 import java.nio.charset.StandardCharsets;
 
+import org.apache.james.util.io.InputStreamUtils;
 import org.junit.jupiter.api.Test;
 
 import com.google.common.primitives.Bytes;
diff --git a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
index c2e8ff3..c83fdca 100644
--- a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
+++ b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
@@ -114,7 +114,7 @@ import org.apache.james.probe.DataProbe;
 import org.apache.james.util.ClassLoaderUtils;
 import org.apache.james.util.MimeMessageUtil;
 import org.apache.james.util.Port;
-import org.apache.james.util.ZeroedInputStream;
+import org.apache.james.util.io.ZeroedInputStream;
 import org.apache.james.utils.DataProbeImpl;
 import org.apache.james.utils.IMAPMessageReader;
 import org.apache.james.utils.SMTPMessageSender;
@@ -132,6 +132,7 @@ import org.junit.experimental.categories.Category;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
 import com.google.common.io.ByteStreams;
+
 import io.restassured.RestAssured;
 import io.restassured.builder.RequestSpecBuilder;
 import io.restassured.filter.log.LogDetail;
diff --git a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/cucumber/DownloadStepdefs.java b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/cucumber/DownloadStepdefs.java
index 41a8fe1..b5998c5 100644
--- a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/cucumber/DownloadStepdefs.java
+++ b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/cucumber/DownloadStepdefs.java
@@ -51,7 +51,7 @@ import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mime4j.codec.DecoderUtil;
-import org.apache.james.util.InputStreamUtils;
+import org.apache.james.util.io.InputStreamUtils;
 
 import com.google.common.base.CharMatcher;
 import com.google.common.base.MoreObjects;
diff --git a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/cucumber/UploadStepdefs.java b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/cucumber/UploadStepdefs.java
index 9fe7661..5266fc7 100644
--- a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/cucumber/UploadStepdefs.java
+++ b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/cucumber/UploadStepdefs.java
@@ -41,8 +41,8 @@ import org.apache.http.concurrent.FutureCallback;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.james.jmap.AccessToken;
-import org.apache.james.util.CountDownConsumeInputStream;
-import org.apache.james.util.ZeroedInputStream;
+import org.apache.james.util.io.CountDownConsumeInputStream;
+import org.apache.james.util.io.ZeroedInputStream;
 
 import com.google.common.base.CharMatcher;
 import com.jayway.jsonpath.DocumentContext;


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


[james-project] 27/37: [REFACTORING] Favor composition over inheritance in order to parse and store attachments

Posted by bt...@apache.org.
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 f407fba4e6a638610dc4fd99844df45146421cb2
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 20 11:44:58 2020 +0700

    [REFACTORING] Favor composition over inheritance in order to parse and store attachments
    
    This enables the parse-then-store behaviour factorisation
---
 .../org/apache/james/mailbox/AttachmentStorer.java | 44 +++++++++++++++
 .../mailbox/cassandra/CassandraMessageManager.java | 24 +-------
 .../mailbox/jpa/openjpa/OpenJPAMailboxManager.java |  1 -
 .../mailbox/jpa/openjpa/OpenJPAMessageManager.java |  8 +--
 .../mailbox/inmemory/InMemoryMessageManager.java   | 21 +------
 .../james/mailbox/store/StoreAttachmentStorer.java | 65 ++++++++++++++++++++++
 .../james/mailbox/store/StoreMailboxManager.java   |  6 +-
 .../james/mailbox/store/StoreMessageManager.java   | 30 ++--------
 8 files changed, 129 insertions(+), 70 deletions(-)

diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentStorer.java b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentStorer.java
new file mode 100644
index 0000000..2a3e22b
--- /dev/null
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/AttachmentStorer.java
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox;
+
+import java.util.List;
+
+import javax.mail.internet.SharedInputStream;
+
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageId;
+
+import com.google.common.collect.ImmutableList;
+
+public interface AttachmentStorer {
+    /**
+     * If applicable, this method will parse the messageContent to retrieve associated attachments and will store them.
+     */
+    List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream messageContent, MailboxSession session) throws MailboxException;
+
+    class NoopAttachmentStorer implements AttachmentStorer {
+        @Override
+        public List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream messageContent, MailboxSession session) {
+            return ImmutableList.of();
+        }
+    }
+}
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
index 50159cd..c22aba9 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
@@ -19,24 +19,19 @@
 
 package org.apache.james.mailbox.cassandra;
 
-import java.util.List;
-
 import javax.mail.Flags;
-import javax.mail.internet.SharedInputStream;
 
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.events.EventBus;
-import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
-import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
 import org.apache.james.mailbox.store.BatchSizes;
 import org.apache.james.mailbox.store.MessageFactory;
 import org.apache.james.mailbox.store.PreDeletionHooks;
+import org.apache.james.mailbox.store.StoreAttachmentStorer;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.StoreRightManager;
 import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
@@ -44,12 +39,9 @@ import org.apache.james.mailbox.store.search.MessageSearchIndex;
 
 /**
  * Cassandra implementation of {@link StoreMessageManager}
- * 
  */
 public class CassandraMessageManager extends StoreMessageManager {
 
-    private CassandraMailboxSessionMapperFactory mapperFactory;
-
     CassandraMessageManager(CassandraMailboxSessionMapperFactory mapperFactory, MessageSearchIndex index,
                             EventBus eventBus, MailboxPathLocker locker, Mailbox mailbox, QuotaManager quotaManager,
                             QuotaRootResolver quotaRootResolver, MessageParser messageParser, MessageId.Factory messageIdFactory,
@@ -57,10 +49,8 @@ public class CassandraMessageManager extends StoreMessageManager {
                             StoreRightManager storeRightManager,
                             PreDeletionHooks preDeletionHooks) {
         super(CassandraMailboxManager.MESSAGE_CAPABILITIES, mapperFactory, index, eventBus, locker, mailbox,
-            quotaManager, quotaRootResolver, messageParser, messageIdFactory, batchSizes, storeRightManager,
-            preDeletionHooks, new MessageFactory.StoreMessageFactory());
-
-        this.mapperFactory = mapperFactory;
+            quotaManager, quotaRootResolver, messageIdFactory, batchSizes, storeRightManager,
+            preDeletionHooks, new MessageFactory.StoreMessageFactory(), new StoreAttachmentStorer(mapperFactory, messageParser));
     }
 
     /**
@@ -72,12 +62,4 @@ public class CassandraMessageManager extends StoreMessageManager {
         flags.add(Flags.Flag.USER);
         return flags;
     }
-
-    @Override
-    protected List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream content, MailboxSession session) throws MailboxException {
-        List<ParsedAttachment> attachments = extractAttachments(content);
-        return mapperFactory.getAttachmentMapper(session)
-            .storeAttachmentsForMessage(attachments, messageId);
-    }
-
 }
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java
index 3fec6d5..764868d 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java
@@ -75,7 +75,6 @@ public class OpenJPAMailboxManager extends StoreMailboxManager {
             mailboxRow,
             getQuotaComponents().getQuotaManager(),
             getQuotaComponents().getQuotaRootResolver(),
-            getMessageParser(),
             getMessageIdFactory(),
             configuration.getBatchSizes(),
             getStoreRightManager());
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
index 6db978a..d982497 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
@@ -21,6 +21,7 @@ package org.apache.james.mailbox.jpa.openjpa;
 
 import javax.mail.Flags;
 
+import org.apache.james.mailbox.AttachmentStorer;
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.events.EventBus;
@@ -34,7 +35,6 @@ import org.apache.james.mailbox.store.PreDeletionHooks;
 import org.apache.james.mailbox.store.StoreMailboxManager;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.StoreRightManager;
-import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
 import org.apache.james.mailbox.store.search.MessageSearchIndex;
 
 /**
@@ -45,12 +45,12 @@ public class OpenJPAMessageManager extends StoreMessageManager {
     public OpenJPAMessageManager(MailboxSessionMapperFactory mapperFactory,
                                  MessageSearchIndex index, EventBus eventBus,
                                  MailboxPathLocker locker, Mailbox mailbox,
-                                 QuotaManager quotaManager, QuotaRootResolver quotaRootResolver, MessageParser messageParser,
+                                 QuotaManager quotaManager, QuotaRootResolver quotaRootResolver,
                                  MessageId.Factory messageIdFactory, BatchSizes batchSizes,
                                  StoreRightManager storeRightManager) {
         super(StoreMailboxManager.DEFAULT_NO_MESSAGE_CAPABILITIES, mapperFactory, index, eventBus, locker, mailbox,
-            quotaManager, quotaRootResolver, messageParser, messageIdFactory, batchSizes, storeRightManager, PreDeletionHooks.NO_PRE_DELETION_HOOK,
-            new OpenJPAMessageFactory(OpenJPAMessageFactory.AdvancedFeature.None));
+            quotaManager, quotaRootResolver, messageIdFactory, batchSizes, storeRightManager, PreDeletionHooks.NO_PRE_DELETION_HOOK,
+            new OpenJPAMessageFactory(OpenJPAMessageFactory.AdvancedFeature.None), new AttachmentStorer.NoopAttachmentStorer());
     }
 
     /**
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
index d8d1a96..5d51bb7 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
@@ -1,33 +1,25 @@
 package org.apache.james.mailbox.inmemory;
 
-import java.util.List;
-
 import javax.mail.Flags;
-import javax.mail.internet.SharedInputStream;
 
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.events.EventBus;
-import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
-import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
-import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
 import org.apache.james.mailbox.store.BatchSizes;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.MessageFactory;
 import org.apache.james.mailbox.store.PreDeletionHooks;
+import org.apache.james.mailbox.store.StoreAttachmentStorer;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.StoreRightManager;
 import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
 import org.apache.james.mailbox.store.search.MessageSearchIndex;
 
 public class InMemoryMessageManager extends StoreMessageManager {
-
-    private InMemoryMailboxSessionMapperFactory mapperFactory;
-
     public InMemoryMessageManager(MailboxSessionMapperFactory mapperFactory,
                                   MessageSearchIndex index,
                                   EventBus eventBus,
@@ -42,8 +34,8 @@ public class InMemoryMessageManager extends StoreMessageManager {
                                   PreDeletionHooks preDeletionHooks) {
 
         super(InMemoryMailboxManager.MESSAGE_CAPABILITIES, mapperFactory, index, eventBus, locker, mailbox, quotaManager, quotaRootResolver,
-            messageParser, messageIdFactory, batchSizes, storeRightManager, preDeletionHooks, new MessageFactory.StoreMessageFactory());
-        this.mapperFactory = (InMemoryMailboxSessionMapperFactory) mapperFactory;
+            messageIdFactory, batchSizes, storeRightManager, preDeletionHooks, new MessageFactory.StoreMessageFactory(),
+            new StoreAttachmentStorer((InMemoryMailboxSessionMapperFactory) mapperFactory, messageParser));
     }
 
     @Override
@@ -52,11 +44,4 @@ public class InMemoryMessageManager extends StoreMessageManager {
         permanentFlags.add(Flags.Flag.USER);
         return permanentFlags;
     }
-
-    @Override
-    protected List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream content, MailboxSession session) throws MailboxException {
-        List<ParsedAttachment> attachments = extractAttachments(content);
-        return mapperFactory.getAttachmentMapper(session)
-            .storeAttachmentsForMessage(attachments, messageId);
-    }
 }
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentStorer.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentStorer.java
new file mode 100644
index 0000000..5ff314b
--- /dev/null
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreAttachmentStorer.java
@@ -0,0 +1,65 @@
+/****************************************************************
+ * 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.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.store;
+
+import java.util.List;
+
+import javax.mail.internet.SharedInputStream;
+
+import org.apache.james.mailbox.AttachmentStorer;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.ParsedAttachment;
+import org.apache.james.mailbox.store.mail.AttachmentMapperFactory;
+import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+
+public class StoreAttachmentStorer implements AttachmentStorer {
+    private static final Logger LOGGER = LoggerFactory.getLogger(StoreAttachmentStorer.class);
+
+    private final AttachmentMapperFactory mapperFactory;
+    private final MessageParser messageParser;
+
+    public StoreAttachmentStorer(AttachmentMapperFactory mapperFactory, MessageParser messageParser) {
+        this.mapperFactory = mapperFactory;
+        this.messageParser = messageParser;
+    }
+
+    @Override
+    public List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream messageContent, MailboxSession session) throws MailboxException {
+        List<ParsedAttachment> attachments = extractAttachments(messageContent);
+        return mapperFactory.getAttachmentMapper(session)
+            .storeAttachmentsForMessage(attachments, messageId);
+    }
+
+    private List<ParsedAttachment> extractAttachments(SharedInputStream contentIn) {
+        try {
+            return messageParser.retrieveAttachments(contentIn.newStream(0, -1));
+        } catch (Exception e) {
+            LOGGER.warn("Error while parsing mail's attachments: {}", e.getMessage(), e);
+            return ImmutableList.of();
+        }
+    }
+}
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 aad8189..96cc2a5 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
@@ -33,6 +33,7 @@ import javax.inject.Inject;
 import org.apache.james.core.Username;
 import org.apache.james.core.quota.QuotaCountUsage;
 import org.apache.james.core.quota.QuotaSizeUsage;
+import org.apache.james.mailbox.AttachmentStorer.NoopAttachmentStorer;
 import org.apache.james.mailbox.MailboxAnnotationManager;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxPathLocker;
@@ -248,8 +249,9 @@ 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,
-            getQuotaComponents().getQuotaRootResolver(), getMessageParser(), getMessageIdFactory(), configuration.getBatchSizes(),
-            getStoreRightManager(), preDeletionHooks, new MessageFactory.StoreMessageFactory());
+            getQuotaComponents().getQuotaRootResolver(), getMessageIdFactory(), configuration.getBatchSizes(),
+            getStoreRightManager(), preDeletionHooks, new MessageFactory.StoreMessageFactory(),
+            new NoopAttachmentStorer());
     }
 
     @Override
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
index f37279a..0006c6f 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
@@ -45,6 +45,7 @@ import javax.mail.util.SharedFileInputStream;
 
 import org.apache.commons.io.input.TeeInputStream;
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.james.mailbox.AttachmentStorer;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxManager.MessageCapabilities;
 import org.apache.james.mailbox.MailboxPathLocker;
@@ -73,7 +74,6 @@ import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.MessageMoves;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.MessageResultIterator;
-import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.model.UidValidity;
 import org.apache.james.mailbox.model.UpdatedFlags;
@@ -83,7 +83,6 @@ import org.apache.james.mailbox.store.event.EventFactory;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper.FetchType;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
-import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
 import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
 import org.apache.james.mailbox.store.quota.QuotaChecker;
 import org.apache.james.mailbox.store.search.MessageSearchIndex;
@@ -100,8 +99,6 @@ import org.apache.james.util.IteratorWrapper;
 import org.apache.james.util.io.BodyOffsetInputStream;
 import org.apache.james.util.io.InputStreamConsummer;
 import org.apache.james.util.streams.Iterators;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableList;
@@ -148,8 +145,6 @@ public class StoreMessageManager implements MessageManager {
         MINIMAL_PERMANET_FLAGS.add(Flags.Flag.SEEN);
     }
 
-    private static final Logger LOG = LoggerFactory.getLogger(StoreMessageManager.class);
-
     private final EnumSet<MailboxManager.MessageCapabilities> messageCapabilities;
     private final EventBus eventBus;
     private final Mailbox mailbox;
@@ -159,17 +154,17 @@ public class StoreMessageManager implements MessageManager {
     private final QuotaManager quotaManager;
     private final QuotaRootResolver quotaRootResolver;
     private final MailboxPathLocker locker;
-    private final MessageParser messageParser;
     private final Factory messageIdFactory;
     private final BatchSizes batchSizes;
     private final PreDeletionHooks preDeletionHooks;
     private final MessageFactory messageFactory;
+    private final AttachmentStorer attachmentStorer;
 
     public StoreMessageManager(EnumSet<MessageCapabilities> messageCapabilities, MailboxSessionMapperFactory mapperFactory,
                                MessageSearchIndex index, EventBus eventBus,
                                MailboxPathLocker locker, Mailbox mailbox,
-                               QuotaManager quotaManager, QuotaRootResolver quotaRootResolver, MessageParser messageParser, Factory messageIdFactory, BatchSizes batchSizes,
-                               StoreRightManager storeRightManager, PreDeletionHooks preDeletionHooks, MessageFactory messageFactory) {
+                               QuotaManager quotaManager, QuotaRootResolver quotaRootResolver, Factory messageIdFactory, BatchSizes batchSizes,
+                               StoreRightManager storeRightManager, PreDeletionHooks preDeletionHooks, MessageFactory messageFactory, AttachmentStorer attachmentStorer) {
         this.messageCapabilities = messageCapabilities;
         this.eventBus = eventBus;
         this.mailbox = mailbox;
@@ -178,12 +173,12 @@ public class StoreMessageManager implements MessageManager {
         this.locker = locker;
         this.quotaManager = quotaManager;
         this.quotaRootResolver = quotaRootResolver;
-        this.messageParser = messageParser;
         this.messageIdFactory = messageIdFactory;
         this.batchSizes = batchSizes;
         this.storeRightManager = storeRightManager;
         this.preDeletionHooks = preDeletionHooks;
         this.messageFactory = messageFactory;
+        this.attachmentStorer = attachmentStorer;
     }
 
     /**
@@ -492,15 +487,6 @@ public class StoreMessageManager implements MessageManager {
         return propertyBuilder;
     }
 
-    protected List<ParsedAttachment> extractAttachments(SharedInputStream contentIn) {
-        try {
-            return messageParser.retrieveAttachments(contentIn.newStream(0, -1));
-        } catch (Exception e) {
-            LOG.warn("Error while parsing mail's attachments: {}", e.getMessage(), e);
-            return ImmutableList.of();
-        }
-    }
-
     @Override
     public boolean isWriteable(MailboxSession session) throws MailboxException {
         return storeRightManager.isReadWrite(session, mailbox, getSharedPermanentFlags(session));
@@ -662,17 +648,13 @@ public class StoreMessageManager implements MessageManager {
         MessageId messageId = messageIdFactory.generate();
 
         return mapperFactory.getMessageMapper(session).execute(() -> {
-            List<MessageAttachment> attachments = storeAttachments(messageId, content, session);
+            List<MessageAttachment> attachments = attachmentStorer.storeAttachments(messageId, content, session);
             MailboxMessage message = messageFactory.createMessage(messageId, getMailboxEntity(), internalDate, size, bodyStartOctet, content, flags, propertyBuilder, attachments);
             MessageMetaData metadata = messageMapper.add(getMailboxEntity(), message);
             return Pair.of(metadata, attachments);
         });
     }
 
-    protected List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream content, MailboxSession session) throws MailboxException {
-        return ImmutableList.of();
-    }
-
     @Override
     public long getMessageCount(MailboxSession mailboxSession) throws MailboxException {
         return mapperFactory.getMessageMapper(mailboxSession).countMessagesInMailbox(getMailboxEntity());


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


[james-project] 32/37: JAMES-2997 Fix checkstyle in AttachmentMapper

Posted by bt...@apache.org.
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 ee9c1b50c8726d9803314f10e9716b233a2cc034
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Mar 27 13:37:12 2020 +0700

    JAMES-2997 Fix checkstyle in AttachmentMapper
---
 .../main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java  | 1 -
 1 file changed, 1 deletion(-)

diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
index 196eb91..a25714a 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
@@ -20,7 +20,6 @@ package org.apache.james.mailbox.store.mail;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.UncheckedIOException;
 import java.util.Collection;
 import java.util.List;
 


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


[james-project] 16/37: JAMES-2997 Renable StoreBlobManagerTest

Posted by bt...@apache.org.
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 3d465902f5c4cb4ace88a08fc40805b70013d33e
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 20 14:32:24 2020 +0700

    JAMES-2997 Renable StoreBlobManagerTest
---
 .../james/mailbox/store/StoreBlobManagerTest.java  | 59 +++++++++++++---------
 1 file changed, 35 insertions(+), 24 deletions(-)

diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
index 8c86114..5b5dece 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreBlobManagerTest.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.mailbox.store;
 
+import static org.apache.james.mailbox.store.StoreBlobManager.MESSAGE_RFC822_CONTENT_TYPE;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.ArgumentMatchers.any;
@@ -45,9 +46,12 @@ import org.apache.james.mailbox.model.Content;
 import org.apache.james.mailbox.model.FetchGroup;
 import org.apache.james.mailbox.model.MessageResult;
 import org.apache.james.mailbox.model.TestMessageId;
+import org.apache.james.mailbox.store.streaming.ByteContent;
+import org.assertj.core.api.SoftAssertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
+import com.github.fge.lambdas.Throwing;
 import com.google.common.collect.ImmutableList;
 
 class StoreBlobManagerTest {
@@ -72,26 +76,29 @@ class StoreBlobManagerTest {
 
         blobManager = new StoreBlobManager(attachmentManager, messageIdManager, new TestMessageId.Factory());
     }
-/*
+
     @Test
     void retrieveShouldReturnBlobWhenAttachment() throws Exception {
         when(attachmentManager.getAttachment(ATTACHMENT_ID, session))
             .thenReturn(Attachment.builder()
                 .attachmentId(ATTACHMENT_ID)
-                .bytes(BYTES)
+                .size(BYTES.length)
                 .type(CONTENT_TYPE)
                 .build());
-
-        assertThat(blobManager.retrieve(BLOB_ID_ATTACHMENT, session))
-            .isEqualTo(Blob.builder()
-                .id(BlobId.fromString("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"))
-                .contentType(CONTENT_TYPE)
-                .payload(BYTES)
-                .build());
+        when(attachmentManager.loadAttachmentContent(ATTACHMENT_ID, session))
+            .thenReturn(new ByteArrayInputStream(BYTES));
+
+        Blob blob = blobManager.retrieve(BLOB_ID_ATTACHMENT, session);
+
+        SoftAssertions.assertSoftly(Throwing.consumer(
+            softly -> {
+                assertThat(blob.getBlobId()).isEqualTo(BlobId.fromString(ATTACHMENT_ID.getId()));
+                assertThat(blob.getContentType()).isEqualTo(CONTENT_TYPE);
+                assertThat(blob.getSize()).isEqualTo(BYTES.length);
+                assertThat(blob.getStream()).hasSameContentAs(new ByteArrayInputStream(BYTES));
+            }));
     }
 
- */
-
     @Test
     void retrieveShouldThrowWhenNotFound() throws Exception {
         when(attachmentManager.getAttachment(ATTACHMENT_ID, session))
@@ -102,27 +109,29 @@ class StoreBlobManagerTest {
         assertThatThrownBy(() -> blobManager.retrieve(BLOB_ID_ATTACHMENT, session))
             .isInstanceOf(BlobNotFoundException.class);
     }
-/*
+
     @Test
     void retrieveShouldReturnBlobWhenMessage() throws Exception {
         when(attachmentManager.getAttachment(any(), any()))
             .thenThrow(new AttachmentNotFoundException(ID));
 
         MessageResult messageResult = mock(MessageResult.class);
-        Content content = mock(Content.class);
-        when(content.getInputStream()).thenReturn(new ByteArrayInputStream(BYTES));
+        Content content = new ByteContent(BYTES);
         when(messageResult.getFullContent()).thenReturn(content);
         when(messageIdManager.getMessage(MESSAGE_ID, FetchGroup.FULL_CONTENT, session))
             .thenReturn(ImmutableList.of(messageResult));
 
-        assertThat(blobManager.retrieve(BLOB_ID_MESSAGE, session))
-            .isEqualTo(Blob.builder()
-                .id(BLOB_ID_MESSAGE)
-                .contentType(StoreBlobManager.MESSAGE_RFC822_CONTENT_TYPE)
-                .payload(BYTES)
-                .build());
+        Blob blob = blobManager.retrieve(BLOB_ID_MESSAGE, session);
+
+        SoftAssertions.assertSoftly(Throwing.consumer(
+            softly -> {
+                assertThat(blob.getBlobId()).isEqualTo(BLOB_ID_MESSAGE);
+                assertThat(blob.getContentType()).isEqualTo(MESSAGE_RFC822_CONTENT_TYPE);
+                assertThat(blob.getSize()).isEqualTo(BYTES.length);
+                assertThat(blob.getStream()).hasSameContentAs(new ByteArrayInputStream(BYTES));
+            }));
     }
-*/
+
     @Test
     void retrieveShouldThrowOnMailboxExceptionWhenRetrievingAttachment() throws Exception {
         when(attachmentManager.getAttachment(any(), any()))
@@ -205,8 +214,9 @@ class StoreBlobManagerTest {
         when(messageIdManager.getMessage(MESSAGE_ID, FetchGroup.FULL_CONTENT, session))
             .thenReturn(ImmutableList.of(messageResult));
 
-        assertThatThrownBy(() -> blobManager.retrieve(BLOB_ID_MESSAGE, session))
-            .isInstanceOf(RuntimeException.class);
+        Blob blob = blobManager.retrieve(BLOB_ID_MESSAGE, session);
+        assertThatThrownBy(blob::getStream)
+            .isInstanceOf(IOException.class);
     }
 
     @Test
@@ -221,7 +231,8 @@ class StoreBlobManagerTest {
         when(messageIdManager.getMessage(MESSAGE_ID, FetchGroup.FULL_CONTENT, session))
             .thenReturn(ImmutableList.of(messageResult));
 
-        assertThatThrownBy(() -> blobManager.retrieve(BLOB_ID_MESSAGE, session))
+        Blob blob = blobManager.retrieve(BLOB_ID_MESSAGE, session);
+        assertThatThrownBy(blob::getStream)
             .isInstanceOf(RuntimeException.class);
     }
 


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


[james-project] 13/37: JAMES-2997 step #11 Remove bytes from attachment

Posted by bt...@apache.org.
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 06d3b79ec3fc9ccc2009923d03bf53278e88de06
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Jan 17 16:05:14 2020 +0700

    JAMES-2997 step #11 Remove bytes from attachment
---
 .../org/apache/james/mailbox/model/Attachment.java | 42 ++++++---------------
 .../james/mailbox/model/ParsedAttachment.java      | 44 ++++++++++++++--------
 .../james/mailbox/model/MessageAttachmentTest.java | 24 ++++++------
 .../cassandra/mail/CassandraAttachmentDAOV2.java   |  4 +-
 .../cassandra/mail/CassandraAttachmentMapper.java  | 10 ++---
 .../cassandra/mail/AttachmentLoaderTest.java       | 10 ++---
 .../mail/CassandraAttachmentDAOV2Test.java         |  3 +-
 ...asticSearchListeningMessageSearchIndexTest.java |  2 +-
 .../model/openjpa/AbstractJPAMailboxMessage.java   |  6 ++-
 .../mailbox/maildir/mail/model/MaildirMessage.java |  6 ++-
 .../inmemory/mail/InMemoryAttachmentMapper.java    | 28 +++++++-------
 .../james/vault/DeletedMessageConverterTest.java   |  3 +-
 .../james/mailbox/store/StoreMessageManager.java   | 14 ++-----
 .../mailbox/store/StoreAttachmentManagerTest.java  |  6 +--
 .../mail/model/impl/SimpleMailboxMessageTest.java  |  2 +-
 .../apache/james/util/io/InputStreamConsummer.java | 32 ++++++++++++++++
 .../message/view/MessageFullViewFactoryTest.java   |  2 +-
 17 files changed, 127 insertions(+), 111 deletions(-)

diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
index eb017c9..934d044 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
@@ -19,15 +19,12 @@
 
 package org.apache.james.mailbox.model;
 
-import java.util.Arrays;
-
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 
 public class Attachment {
-
     public static Builder builder() {
         return new Builder();
     }
@@ -35,7 +32,7 @@ public class Attachment {
     public static class Builder {
 
         private AttachmentId attachmentId;
-        private byte[] bytes;
+        private Long size;
         private String type;
 
         public Builder attachmentId(AttachmentId attachmentId) {
@@ -44,24 +41,24 @@ public class Attachment {
             return this;
         }
 
-        public Builder bytes(byte[] bytes) {
-            Preconditions.checkArgument(bytes != null);
-            this.bytes = bytes;
-            return this;
-        }
-
         public Builder type(String type) {
             Preconditions.checkArgument(!Strings.isNullOrEmpty(type));
             this.type = type;
             return this;
         }
 
+        public Builder size(long size) {
+            Preconditions.checkArgument(size >= 0, "'size' must be positive");
+            this.size = size;
+            return this;
+        }
+
         public Attachment build() {
-            Preconditions.checkState(bytes != null, "'bytes' is mandatory");
             Preconditions.checkState(type != null, "'type' is mandatory");
+            Preconditions.checkState(size != null, "'size' is mandatory");
             AttachmentId builtAttachmentId = attachmentId();
             Preconditions.checkState(builtAttachmentId != null, "'attachmentId' is mandatory");
-            return new Attachment(bytes, builtAttachmentId, type, size());
+            return new Attachment(builtAttachmentId, type, size);
         }
 
         private AttachmentId attachmentId() {
@@ -70,19 +67,13 @@ public class Attachment {
             }
             return AttachmentId.random();
         }
-
-        private long size() {
-            return bytes.length;
-        }
     }
 
-    private final byte[] bytes;
     private final AttachmentId attachmentId;
     private final String type;
     private final long size;
 
-    private Attachment(byte[] bytes, AttachmentId attachmentId, String type, long size) {
-        this.bytes = bytes;
+    private Attachment(AttachmentId attachmentId, String type, long size) {
         this.attachmentId = attachmentId;
         this.type = type;
         this.size = size;
@@ -100,22 +91,12 @@ public class Attachment {
         return size;
     }
 
-    /**
-     * Be careful the returned array is not a copy of the attachment byte array.
-     * Mutating it will mutate the attachment!
-     * @return the attachment content
-     */
-    public byte[] getBytes() {
-        return bytes;
-    }
-
 
     @Override
     public boolean equals(Object obj) {
         if (obj instanceof Attachment) {
             Attachment other = (Attachment) obj;
             return Objects.equal(attachmentId, other.attachmentId)
-                && Arrays.equals(bytes, other.bytes)
                 && Objects.equal(type, other.type)
                 && Objects.equal(size, other.size);
         }
@@ -124,7 +105,7 @@ public class Attachment {
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(attachmentId, bytes, type, size);
+        return Objects.hashCode(attachmentId, type, size);
     }
 
     @Override
@@ -132,7 +113,6 @@ public class Attachment {
         return MoreObjects
                 .toStringHelper(this)
                 .add("attachmentId", attachmentId)
-                .add("bytes", bytes)
                 .add("type", type)
                 .add("size", size)
                 .toString();
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java
index 649b034..96dd66d 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java
@@ -23,7 +23,8 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.Optional;
 
-import org.apache.commons.io.IOUtils;
+import org.apache.james.util.io.InputStreamConsummer;
+import org.apache.james.util.io.SizeInputStream;
 
 public class ParsedAttachment {
     interface Builder {
@@ -111,20 +112,31 @@ public class ParsedAttachment {
         return isInline;
     }
 
-    public MessageAttachment asMessageAttachment(AttachmentId attachmentId) {
-        try {
-            return MessageAttachment.builder()
-                .attachment(Attachment.builder()
-                        .attachmentId(attachmentId)
-                        .type(contentType)
-                        .bytes(IOUtils.toByteArray(content))
-                        .build())
-                    .name(name)
-                    .cid(cid)
-                    .isInline(isInline)
-                    .build();
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
+    public MessageAttachment asMessageAttachment(AttachmentId attachmentId, long size) {
+        return MessageAttachment.builder()
+            .attachment(Attachment.builder()
+                .attachmentId(attachmentId)
+                .type(contentType)
+                .size(size)
+                .build())
+            .name(name)
+            .cid(cid)
+            .isInline(isInline)
+            .build();
+    }
+
+    public MessageAttachment asMessageAttachment(AttachmentId attachmentId) throws IOException {
+        SizeInputStream sizeInputStream = new SizeInputStream(content);
+        InputStreamConsummer.consume(sizeInputStream);
+        return MessageAttachment.builder()
+            .attachment(Attachment.builder()
+                .attachmentId(attachmentId)
+                .type(contentType)
+                .size(sizeInputStream.getSize())
+                .build())
+            .name(name)
+            .cid(cid)
+            .isInline(isInline)
+            .build();
     }
 }
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageAttachmentTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageAttachmentTest.java
index edbc673..d501c30 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageAttachmentTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageAttachmentTest.java
@@ -45,9 +45,9 @@ class MessageAttachmentTest {
     @Test
     void buildShouldWorkWhenMandatoryAttributesAreGiven() {
         Attachment attachment = Attachment.builder()
-                .bytes("content".getBytes())
-                .type("type")
-                .build();
+            .size(36)
+            .type("type")
+            .build();
         MessageAttachment expectedMessageAttachment = new MessageAttachment(attachment, Optional.empty(), Optional.empty(), false);
 
         MessageAttachment messageAttachment = MessageAttachment.builder()
@@ -60,9 +60,9 @@ class MessageAttachmentTest {
     @Test
     void buildShouldAcceptIsInlineAndNoCid() {
         Attachment attachment = Attachment.builder()
-                .bytes("content".getBytes())
-                .type("type")
-                .build();
+            .size(36)
+            .type("type")
+            .build();
 
         MessageAttachment messageAttachment = MessageAttachment.builder()
             .attachment(attachment)
@@ -75,9 +75,9 @@ class MessageAttachmentTest {
     @Test
     void buildShouldSetAttributesWhenAllAreGiven() {
         Attachment attachment = Attachment.builder()
-                .bytes("content".getBytes())
-                .type("type")
-                .build();
+            .size(36)
+            .type("type")
+            .build();
         MessageAttachment expectedMessageAttachment = new MessageAttachment(attachment, Optional.of("name"), Optional.of(Cid.from("cid")), true);
 
         MessageAttachment messageAttachment = MessageAttachment.builder()
@@ -93,7 +93,7 @@ class MessageAttachmentTest {
     @Test
     void isInlinedWithCidShouldReturnTrueWhenIsInlineAndHasCid() throws Exception {
         Attachment attachment = Attachment.builder()
-            .bytes("content".getBytes())
+            .size(36)
             .type("type")
             .build();
 
@@ -110,7 +110,7 @@ class MessageAttachmentTest {
     @Test
     void isInlinedWithCidShouldReturnFalseWhenIsNotInline() throws Exception {
         Attachment attachment = Attachment.builder()
-            .bytes("content".getBytes())
+            .size(36)
             .type("type")
             .build();
 
@@ -127,7 +127,7 @@ class MessageAttachmentTest {
     @Test
     void isInlinedWithCidShouldReturnFalseWhenIsInlineButNoCid() throws Exception {
         Attachment attachment = Attachment.builder()
-            .bytes("content".getBytes())
+            .size(36)
             .type("type")
             .build();
 
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
index d846f91..226b40a 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2.java
@@ -78,11 +78,11 @@ public class CassandraAttachmentDAOV2 {
             return size;
         }
 
-        public Attachment toAttachment(byte[] data) {
+        public Attachment toAttachment() {
             return Attachment.builder()
                 .attachmentId(attachmentId)
                 .type(type)
-                .bytes(data)
+                .size(size)
                 .build();
         }
 
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
index dced0a0..7cd1484 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
@@ -83,11 +83,6 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
             .orElseThrow(() -> new AttachmentNotFoundException(attachmentId.getId()));
     }
 
-    private Mono<Attachment> retrievePayload(DAOAttachment daoAttachment) {
-        return Mono.from(blobStore.readBytes(blobStore.getDefaultBucketName(), daoAttachment.getBlobId()))
-            .map(daoAttachment::toAttachment);
-    }
-
     @Override
     public List<Attachment> getAttachments(Collection<AttachmentId> attachmentIds) {
         Preconditions.checkArgument(attachmentIds != null);
@@ -112,7 +107,7 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
 
     private Mono<Attachment> getAttachmentInternal(AttachmentId id) {
         return attachmentDAOV2.getAttachment(id)
-            .flatMap(this::retrievePayload);
+            .map(DAOAttachment::toAttachment);
     }
 
     @Override
@@ -127,6 +122,7 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
             .map(any -> Attachment.builder()
                 .attachmentId(attachmentId)
                 .type(contentType)
+                .size(sizeInputStream.getSize())
                 .build());
     }
 
@@ -156,7 +152,7 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
         return Mono.from(blobStore.save(blobStore.getDefaultBucketName(), content, LOW_COST))
             .map(blobId -> new DAOAttachment(attachmentId, blobId, parsedAttachment.getContentType(), content.getSize()))
             .flatMap(daoAttachment -> storeAttachmentWithIndex(daoAttachment, ownerMessageId))
-            .then(Mono.just(parsedAttachment.asMessageAttachment(attachmentId)));
+            .then(Mono.defer(() -> Mono.just(parsedAttachment.asMessageAttachment(attachmentId, content.getSize()))));
     }
 
     private Mono<Void> storeAttachmentWithIndex(DAOAttachment daoAttachment, MessageId ownerMessageId) {
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoaderTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoaderTest.java
index c536650..cc23204 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoaderTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/AttachmentLoaderTest.java
@@ -53,7 +53,7 @@ class AttachmentLoaderTest {
 
         Attachment attachment = Attachment.builder()
             .attachmentId(attachmentId)
-            .bytes("attachment".getBytes())
+            .size(11)
             .type("type")
             .build();
 
@@ -79,7 +79,7 @@ class AttachmentLoaderTest {
 
         Attachment attachment = Attachment.builder()
             .attachmentId(attachmentId)
-            .bytes("attachment".getBytes())
+            .size(11)
             .type("type")
             .build();
 
@@ -108,12 +108,12 @@ class AttachmentLoaderTest {
 
         Attachment attachment1 = Attachment.builder()
             .attachmentId(attachmentId1)
-            .bytes("attachment1".getBytes())
+            .size(12)
             .type("type")
             .build();
         Attachment attachment2 = Attachment.builder()
             .attachmentId(attachmentId2)
-            .bytes("attachment2".getBytes())
+            .size(13)
             .type("type")
             .build();
 
@@ -143,7 +143,7 @@ class AttachmentLoaderTest {
 
         Attachment attachment = Attachment.builder()
             .attachmentId(attachmentId)
-            .bytes("attachment".getBytes())
+            .size(11)
             .type("type")
             .build();
 
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2Test.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2Test.java
index 2bf90c7..e9cbec6 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2Test.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentDAOV2Test.java
@@ -21,7 +21,6 @@ package org.apache.james.mailbox.cassandra.mail;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import java.nio.charset.StandardCharsets;
 import java.util.Optional;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
@@ -62,7 +61,7 @@ class CassandraAttachmentDAOV2Test {
         Attachment attachment = Attachment.builder()
             .attachmentId(ATTACHMENT_ID)
             .type("application/json")
-            .bytes("{\"property\":`\"value\"}".getBytes(StandardCharsets.UTF_8))
+            .size(4)
             .build();
         BlobId blobId = BLOB_ID_FACTORY.from("blobId");
         DAOAttachment daoAttachment = CassandraAttachmentDAOV2.from(attachment, blobId);
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
index 95b67f8..73a6b0c 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
@@ -114,8 +114,8 @@ class ElasticSearchListeningMessageSearchIndexTest {
 
     static final MessageAttachment MESSAGE_ATTACHMENT = MessageAttachment.builder()
         .attachment(Attachment.builder()
-            .bytes("".getBytes(StandardCharsets.UTF_8))
             .type("type")
+            .size(523)
             .build())
         .name("name")
         .isInline(false)
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
index f174fe6..68afe5d 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
@@ -53,6 +53,7 @@ import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
 import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.store.mail.model.DefaultMessageId;
 import org.apache.james.mailbox.store.mail.model.DelegatingMailboxMessage;
 import org.apache.james.mailbox.store.mail.model.FlagsFactory;
@@ -64,6 +65,7 @@ import org.apache.openjpa.persistence.jdbc.ElementJoinColumn;
 import org.apache.openjpa.persistence.jdbc.ElementJoinColumns;
 import org.apache.openjpa.persistence.jdbc.Index;
 
+import com.github.fge.lambdas.Throwing;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Objects;
 
@@ -507,7 +509,9 @@ public abstract class AbstractJPAMailboxMessage implements MailboxMessage {
         try {
             return new MessageParser().retrieveAttachments(getFullContent())
                 .stream()
-                .map(attachmentMetadata -> attachmentMetadata.asMessageAttachment(AttachmentId.random()))
+                .map(Throwing.<ParsedAttachment, MessageAttachment>function(
+                    attachmentMetadata -> attachmentMetadata.asMessageAttachment(AttachmentId.random()))
+                    .sneakyThrow())
                 .collect(Guavate.toImmutableList());
         } catch (IOException e) {
             throw new RuntimeException(e);
diff --git a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
index c2a0b01..b2b4725 100644
--- a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
+++ b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
@@ -33,6 +33,7 @@ import org.apache.james.mailbox.maildir.MaildirMessageName;
 import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.store.mail.model.DefaultMessageId;
 import org.apache.james.mailbox.store.mail.model.Message;
 import org.apache.james.mailbox.store.mail.model.Property;
@@ -47,6 +48,7 @@ import org.apache.james.mime4j.stream.MimeConfig;
 import org.apache.james.mime4j.stream.MimeTokenStream;
 import org.apache.james.mime4j.stream.RecursionMode;
 
+import com.github.fge.lambdas.Throwing;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.io.ByteStreams;
 
@@ -275,7 +277,9 @@ public class MaildirMessage implements Message {
         try {
             return new MessageParser().retrieveAttachments(getFullContent())
                 .stream()
-                .map(attachmentMetadata -> attachmentMetadata.asMessageAttachment(AttachmentId.random()))
+                .map(Throwing.<ParsedAttachment, MessageAttachment>function(
+                    attachmentMetadata -> attachmentMetadata.asMessageAttachment(AttachmentId.random()))
+                    .sneakyThrow())
                 .collect(Guavate.toImmutableList());
         } catch (IOException e) {
             throw new RuntimeException(e);
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
index 331c60f..ac192f8 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
@@ -87,18 +87,18 @@ public class InMemoryAttachmentMapper implements AttachmentMapper {
 
     @Override
     public Mono<Attachment> storeAttachmentForOwner(String contentType, InputStream inputStream, Username owner) {
-            return Mono.fromCallable(() -> {
-                byte[] bytes = toByteArray(inputStream);
-                Attachment attachment = Attachment.builder()
-                    .bytes(bytes)
-                    .type(contentType)
-                    .attachmentId(AttachmentId.random())
-                    .build();
-                attachmentsById.put(attachment.getAttachmentId(), attachment);
-                attachmentsRawContentById.put(attachment.getAttachmentId(), bytes);
-                ownersByAttachmentId.put(attachment.getAttachmentId(), owner);
-                return attachment;
-            });
+        return Mono.fromCallable(() -> {
+            byte[] bytes = toByteArray(inputStream);
+            Attachment attachment = Attachment.builder()
+                .type(contentType)
+                .attachmentId(AttachmentId.random())
+                .size(bytes.length)
+                .build();
+            attachmentsById.put(attachment.getAttachmentId(), attachment);
+            attachmentsRawContentById.put(attachment.getAttachmentId(), bytes);
+            ownersByAttachmentId.put(attachment.getAttachmentId(), owner);
+            return attachment;
+        });
     }
 
     private byte[] toByteArray(InputStream inputStream) {
@@ -136,11 +136,11 @@ public class InMemoryAttachmentMapper implements AttachmentMapper {
             attachmentsById.put(attachmentId, Attachment.builder()
                 .attachmentId(attachmentId)
                 .type(parsedAttachment.getContentType())
-                .bytes(bytes)
+                .size(bytes.length)
                 .build());
             attachmentsRawContentById.put(attachmentId, bytes);
             messageIdsByAttachmentId.put(attachmentId, ownerMessageId);
-            return parsedAttachment.asMessageAttachment(attachmentId);
+            return parsedAttachment.asMessageAttachment(attachmentId, bytes.length);
         } catch (IOException e) {
             throw new MailboxException(String.format("Failed to persist attachment %s of message %s", attachmentId, ownerMessageId.serialize()), e);
         }
diff --git a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageConverterTest.java b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageConverterTest.java
index e22c8e8..eeb6a1c 100644
--- a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageConverterTest.java
+++ b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageConverterTest.java
@@ -35,7 +35,6 @@ import static org.apache.mailet.base.MailAddressFixture.SENDER;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
-import java.nio.charset.StandardCharsets;
 import java.util.Collection;
 import java.util.Date;
 import java.util.List;
@@ -73,8 +72,8 @@ class DeletedMessageConverterTest {
     private static final Collection<MessageAttachment> NO_ATTACHMENT = ImmutableList.of();
     private static final Collection<MessageAttachment> ATTACHMENTS = ImmutableList.of(MessageAttachment.builder()
         .attachment(Attachment.builder()
-            .bytes("content".getBytes(StandardCharsets.UTF_8))
             .type("type")
+            .size(48)
             .build())
         .build());
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
index 1cb207e..19d2106 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
@@ -99,6 +99,7 @@ import org.apache.james.mime4j.stream.MimeTokenStream;
 import org.apache.james.mime4j.stream.RecursionMode;
 import org.apache.james.util.IteratorWrapper;
 import org.apache.james.util.io.BodyOffsetInputStream;
+import org.apache.james.util.io.InputStreamConsummer;
 import org.apache.james.util.streams.Iterators;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -342,7 +343,8 @@ public class StoreMessageManager implements MessageManager {
                 if (internalDate == null) {
                     internalDate = new Date();
                 }
-                consumeStream(bufferedOut, tmpMsgIn);
+                InputStreamConsummer.consume(tmpMsgIn);
+                bufferedOut.flush();
                 int bodyStartOctet = getBodyStartOctet(bIn);
                 return createAndDispatchMessage(internalDate, mailboxSession, file, propertyBuilder, flags, bodyStartOctet);
             }
@@ -426,16 +428,6 @@ public class StoreMessageManager implements MessageManager {
         }
     }
 
-    private void consumeStream(BufferedOutputStream bufferedOut, BufferedInputStream tmpMsgIn) throws IOException {
-        byte[] discard = new byte[4096];
-        while (tmpMsgIn.read(discard) != -1) {
-            // consume the rest of the stream so everything get copied to
-            // the file now
-            // via the TeeInputStream
-        }
-        bufferedOut.flush();
-    }
-
     private int getBodyStartOctet(BodyOffsetInputStream bIn) {
         int bodyStartOctet = (int) bIn.getBodyStartOffset();
         if (bodyStartOctet == -1) {
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreAttachmentManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreAttachmentManagerTest.java
index 9e129a1..66131d0 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreAttachmentManagerTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreAttachmentManagerTest.java
@@ -24,8 +24,6 @@ import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import java.nio.charset.StandardCharsets;
-
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
@@ -47,8 +45,8 @@ class StoreAttachmentManagerTest {
     static final AttachmentId ATTACHMENT_ID = AttachmentId.from("1");
     static final Attachment ATTACHMENT = Attachment.builder()
         .attachmentId(ATTACHMENT_ID)
+        .size(48)
         .type("type")
-        .bytes("Any".getBytes(StandardCharsets.UTF_8))
         .build();
 
     StoreAttachmentManager testee;
@@ -56,7 +54,7 @@ class StoreAttachmentManagerTest {
     MessageIdManager messageIdManager;
 
     @BeforeEach
-    void setup() throws Exception {
+    void setup() {
         attachmentMapper = mock(AttachmentMapper.class);
         AttachmentMapperFactory attachmentMapperFactory = mock(AttachmentMapperFactory.class);
         when(attachmentMapperFactory.getAttachmentMapper(any(MailboxSession.class)))
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessageTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessageTest.java
index 4d1ff30..0e13f97 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessageTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessageTest.java
@@ -177,8 +177,8 @@ class SimpleMailboxMessageTest {
         MessageUid uid = MessageUid.of(45);
         MessageAttachment messageAttachment = MessageAttachment.builder()
             .attachment(Attachment.builder()
-                .bytes("".getBytes(StandardCharsets.UTF_8))
                 .type("type")
+                .size(485)
                 .build())
             .name("name")
             .isInline(false)
diff --git a/server/container/util/src/main/java/org/apache/james/util/io/InputStreamConsummer.java b/server/container/util/src/main/java/org/apache/james/util/io/InputStreamConsummer.java
new file mode 100644
index 0000000..77a7365
--- /dev/null
+++ b/server/container/util/src/main/java/org/apache/james/util/io/InputStreamConsummer.java
@@ -0,0 +1,32 @@
+/****************************************************************
+ * 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.                                           *
+ ****************************************************************/
+
+package org.apache.james.util.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class InputStreamConsummer {
+    public static void consume(InputStream inputStream) throws IOException {
+        byte[] discard = new byte[4096];
+        while (inputStream.read(discard) != -1) {
+            // consume the rest of the stream
+        }
+    }
+}
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java
index 14f7221..4805f1e 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java
@@ -496,7 +496,7 @@ class MessageFullViewFactoryTest {
                 .attachments(ImmutableList.of(MessageAttachment.builder()
                         .attachment(org.apache.james.mailbox.model.Attachment.builder()
                                 .attachmentId(AttachmentId.from(blodId.getRawValue()))
-                                .bytes(payload.getBytes())
+                                .size(payload.length())
                                 .type(type)
                                 .build())
                         .cid(Cid.from("cid"))


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


[james-project] 25/37: JAMES-2997 Renable SetMessagesMethodTest

Posted by bt...@apache.org.
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 f6d9341ec81658674516bcda2bd4af1c6cdcd0dd
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Wed Jan 22 10:31:31 2020 +0700

    JAMES-2997 Renable SetMessagesMethodTest
---
 .../pom.xml                                        |   5 +
 .../cassandra/CassandraSetMessagesMethodTest.java  |   3 -
 .../jmap-draft-integration-testing-common/pom.xml  |   5 +
 .../methods/integration/SetMessagesMethodTest.java | 399 ++++++++++-----------
 .../memory-jmap-draft-integration-testing/pom.xml  |   5 +
 .../jmap/memory/MemorySetMessagesMethodTest.java   |   2 -
 .../pom.xml                                        |   5 +
 .../RabbitMQAwsS3SetMessagesMethodTest.java        |   3 -
 8 files changed, 201 insertions(+), 226 deletions(-)

diff --git a/server/protocols/jmap-draft-integration-testing/cassandra-jmap-draft-integration-testing/pom.xml b/server/protocols/jmap-draft-integration-testing/cassandra-jmap-draft-integration-testing/pom.xml
index c8338cc..0767503 100644
--- a/server/protocols/jmap-draft-integration-testing/cassandra-jmap-draft-integration-testing/pom.xml
+++ b/server/protocols/jmap-draft-integration-testing/cassandra-jmap-draft-integration-testing/pom.xml
@@ -199,6 +199,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>net.javacrumbs.json-unit</groupId>
+            <artifactId>json-unit-assertj</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.pdfbox</groupId>
             <artifactId>pdfbox</artifactId>
             <scope>test</scope>
diff --git a/server/protocols/jmap-draft-integration-testing/cassandra-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMessagesMethodTest.java b/server/protocols/jmap-draft-integration-testing/cassandra-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMessagesMethodTest.java
index 17f4360..1f28849 100644
--- a/server/protocols/jmap-draft-integration-testing/cassandra-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMessagesMethodTest.java
+++ b/server/protocols/jmap-draft-integration-testing/cassandra-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraSetMessagesMethodTest.java
@@ -32,7 +32,6 @@ import org.junit.Rule;
 import org.junit.Test;
 
 public class CassandraSetMessagesMethodTest extends SetMessagesMethodTest {
-/*
     @Rule
     public DockerCassandraRule cassandra = new DockerCassandraRule();
 
@@ -60,6 +59,4 @@ public class CassandraSetMessagesMethodTest extends SetMessagesMethodTest {
     public void setMessagesWithABigBodyShouldReturnCreatedMessageWhenSendingMessage() {
 
     }
-
- */
 }
diff --git a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/pom.xml b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/pom.xml
index b9585b4..d776d7f 100644
--- a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/pom.xml
+++ b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/pom.xml
@@ -146,6 +146,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>net.javacrumbs.json-unit</groupId>
+            <artifactId>json-unit-assertj</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-text</artifactId>
         </dependency>
diff --git a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
index d11172e..c448ee5 100644
--- a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
+++ b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/SetMessagesMethodTest.java
@@ -23,6 +23,7 @@ import static io.restassured.RestAssured.given;
 import static io.restassured.RestAssured.with;
 import static io.restassured.config.EncoderConfig.encoderConfig;
 import static io.restassured.config.RestAssuredConfig.newConfig;
+import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
 import static org.apache.james.jmap.JMAPTestingConstants.ALICE;
 import static org.apache.james.jmap.JMAPTestingConstants.ALICE_PASSWORD;
 import static org.apache.james.jmap.JMAPTestingConstants.ARGUMENTS;
@@ -55,7 +56,6 @@ import static org.hamcrest.Matchers.hasKey;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.isEmptyOrNullString;
 import static org.hamcrest.Matchers.not;
-import static org.hamcrest.Matchers.nullValue;
 import static org.hamcrest.collection.IsMapWithSize.aMapWithSize;
 import static org.hamcrest.collection.IsMapWithSize.anEmptyMap;
 
@@ -74,7 +74,6 @@ import javax.mail.Flags;
 import javax.mail.Flags.Flag;
 import javax.mail.internet.MimeMessage;
 
-import org.apache.commons.io.IOUtils;
 import org.apache.james.GuiceJamesServer;
 import org.apache.james.core.Domain;
 import org.apache.james.core.Username;
@@ -93,6 +92,7 @@ import org.apache.james.mailbox.events.Event;
 import org.apache.james.mailbox.events.MailboxListener;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Attachment;
+import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxConstants;
@@ -138,9 +138,12 @@ import io.restassured.builder.RequestSpecBuilder;
 import io.restassured.filter.log.LogDetail;
 import io.restassured.http.ContentType;
 import io.restassured.parsing.Parser;
+import io.restassured.path.json.JsonPath;
+import net.javacrumbs.jsonunit.core.Option;
+import net.javacrumbs.jsonunit.core.internal.Options;
 
 public abstract class SetMessagesMethodTest {
-/*    private static final String FORWARDED = "$Forwarded";
+    private static final String FORWARDED = "$Forwarded";
     private static final int _1MB = 1024 * 1024;
     private static final Username USERNAME = Username.of("username@" + DOMAIN);
     private static final String ALIAS_OF_USERNAME_MAIL = "alias@" + DOMAIN;
@@ -150,6 +153,7 @@ public abstract class SetMessagesMethodTest {
     private static final MailboxPath USER_MAILBOX = MailboxPath.forUser(USERNAME, "mailbox");
     private static final String NOT_UPDATED = ARGUMENTS + ".notUpdated";
     private static final int BIG_MESSAGE_SIZE = 20 * 1024 * 1024;
+    public static final String OCTET_CONTENT_TYPE = "application/octet-stream";
 
     private AccessToken bobAccessToken;
 
@@ -2092,11 +2096,8 @@ public abstract class SetMessagesMethodTest {
     public void setMessagesShouldAcceptAttachmentsWhenDraft() throws Exception {
         String messageCreationId = "creationId1337";
         String fromAddress = USERNAME.asString();
-        Attachment attachment = Attachment.builder()
-            .bytes("attachment".getBytes(StandardCharsets.UTF_8))
-            .type("application/octet-stream")
-            .build();
-        String uploadedBlobId = uploadAttachment(attachment);
+        String bytes = "attachment";
+        Attachment uploadedAttachment = uploadAttachment(OCTET_CONTENT_TYPE, bytes.getBytes(StandardCharsets.UTF_8));
         String requestBody = "[" +
             "  [" +
             "    \"setMessages\"," +
@@ -2107,9 +2108,9 @@ public abstract class SetMessagesMethodTest {
             "        \"subject\": \"subject\"," +
             "        \"keywords\": {\"$Draft\": true}," +
             "        \"attachments\": [" +
-            "                {\"blobId\" : \"" + uploadedBlobId + "\", " +
-            "                 \"type\" : \"" + attachment.getType() + "\"," +
-            "                 \"size\" : " + attachment.getSize() + "}" +
+            "                {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
+            "                 \"type\" : \"" + uploadedAttachment.getType() + "\"," +
+            "                 \"size\" : " + uploadedAttachment.getSize() + "}" +
             "             ]," +
             "        \"mailboxIds\": [\"" + getDraftId(accessToken) + "\"]" +
             "      }}" +
@@ -3961,16 +3962,10 @@ public abstract class SetMessagesMethodTest {
 
     @Test
     public void setMessagesShouldReturnAttachmentsWhenMessageHasAttachment() throws Exception {
-        Attachment attachment = Attachment.builder()
-            .bytes("attachment".getBytes(StandardCharsets.UTF_8))
-            .type("application/octet-stream")
-            .build();
-        String uploadedAttachment1 = uploadAttachment(attachment);
-        Attachment attachment2 = Attachment.builder()
-            .bytes("attachment2".getBytes(StandardCharsets.UTF_8))
-            .type("application/octet-stream")
-            .build();
-        String uploadedAttachment2 = uploadAttachment(attachment2);
+        String bytes1 = "attachment";
+        String bytes2 = "attachment2";
+        Attachment uploadedAttachment1 = uploadAttachment(OCTET_CONTENT_TYPE, bytes1.getBytes(StandardCharsets.UTF_8));
+        Attachment uploadedAttachment2 = uploadAttachment(OCTET_CONTENT_TYPE, bytes2.getBytes(StandardCharsets.UTF_8));
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -3986,12 +3981,12 @@ public abstract class SetMessagesMethodTest {
             "        \"textBody\": \"Test body\"," +
             "        \"mailboxIds\": [\"" + outboxId + "\"], " +
             "        \"attachments\": [" +
-            "               {\"blobId\" : \"" + uploadedAttachment1 + "\", " +
-            "               \"type\" : \"" + attachment.getType() + "\", " +
-            "               \"size\" : " + attachment.getSize() + "}," +
-            "               {\"blobId\" : \"" + uploadedAttachment2 + "\", " +
-            "               \"type\" : \"" + attachment2.getType() + "\", " +
-            "               \"size\" : " + attachment2.getSize() + ", " +
+            "               {\"blobId\" : \"" + uploadedAttachment1.getAttachmentId().getId() + "\", " +
+            "               \"type\" : \"" + uploadedAttachment1.getType() + "\", " +
+            "               \"size\" : " + uploadedAttachment1.getSize() + "}," +
+            "               {\"blobId\" : \"" + uploadedAttachment2.getAttachmentId().getId() + "\", " +
+            "               \"type\" : \"" + uploadedAttachment2.getType() + "\", " +
+            "               \"size\" : " + uploadedAttachment2.getSize() + ", " +
             "               \"cid\" : \"123456789\", " +
             "               \"isInline\" : true }" +
             "           ]" +
@@ -4002,10 +3997,8 @@ public abstract class SetMessagesMethodTest {
             "]";
 
         String createdPath = ARGUMENTS + ".created[\"" + messageCreationId + "\"]";
-        String firstAttachment = createdPath + ".attachments[0]";
-        String secondAttachment = createdPath + ".attachments[1]";
 
-        given()
+        String json = given()
             .header("Authorization", accessToken.asString())
             .body(requestBody)
         .when()
@@ -4016,35 +4009,34 @@ public abstract class SetMessagesMethodTest {
             .body(ARGUMENTS + ".notCreated", aMapWithSize(0))
             .body(ARGUMENTS + ".created", aMapWithSize(1))
             .body(createdPath + ".attachments", hasSize(2))
-            .body(firstAttachment + ".blobId", equalTo(uploadedAttachment1))
-            .body(firstAttachment + ".type", equalTo("application/octet-stream; charset=UTF-8"))
-            .body(firstAttachment + ".size", equalTo((int) attachment.getSize()))
-            .body(firstAttachment + ".cid", nullValue())
-            .body(firstAttachment + ".isInline", equalTo(false))
-            .body(secondAttachment + ".blobId", equalTo(uploadedAttachment2))
-            .body(secondAttachment + ".type", equalTo("application/octet-stream; charset=UTF-8"))
-            .body(secondAttachment + ".size", equalTo((int) attachment2.getSize()))
-            .body(secondAttachment + ".cid", equalTo("123456789"))
-            .body(secondAttachment + ".isInline", equalTo(true));
+            .extract().asString();
+
+        assertThatJson(json)
+            .withOptions(new Options(Option.TREATING_NULL_AS_ABSENT, Option.IGNORING_ARRAY_ORDER, Option.IGNORING_EXTRA_FIELDS))
+            .whenIgnoringPaths(createdPath + ".attachments[0].blobId", createdPath + ".attachments[1].blobId",
+                createdPath + ".attachments[0].inlinedWithCid", createdPath + ".attachments[1].inlinedWithCid")
+            .inPath(createdPath + ".attachments")
+            .isEqualTo("[{" +
+                "  \"type\":\"application/octet-stream\"," +
+                "  \"size\":" + bytes1.length() + "," +
+                "  \"cid\":null," +
+                "  \"isInline\":false" +
+                "}, {" +
+                "  \"type\":\"application/octet-stream\"," +
+                "  \"size\":" + bytes2.length() + "," +
+                "  \"cid\":\"123456789\"," +
+                "  \"isInline\":true" +
+                "}]");
     }
 
     @Test
     public void setMessagesShouldReturnAttachmentsWithNonASCIINames() throws Exception {
-        Attachment attachment = Attachment.builder()
-            .bytes("attachment".getBytes(StandardCharsets.UTF_8))
-            .type("application/octet-stream")
-            .build();
-        String uploadedAttachment1 = uploadAttachment(attachment);
-        Attachment attachment2 = Attachment.builder()
-            .bytes("attachment2".getBytes(StandardCharsets.UTF_8))
-            .type("application/octet-stream")
-            .build();
-        String uploadedAttachment2 = uploadAttachment(attachment2);
-        Attachment attachment3 = Attachment.builder()
-            .bytes("attachment3".getBytes(StandardCharsets.UTF_8))
-            .type("application/octet-stream")
-            .build();
-        String uploadedAttachment3 = uploadAttachment(attachment3);
+        String bytes1 = "attachment";
+        String bytes2 = "attachment2";
+        String bytes3 = "attachment3";
+        Attachment uploadedAttachment1 = uploadAttachment(OCTET_CONTENT_TYPE, bytes1.getBytes(StandardCharsets.UTF_8));
+        Attachment uploadedAttachment2 = uploadAttachment(OCTET_CONTENT_TYPE, bytes2.getBytes(StandardCharsets.UTF_8));
+        Attachment uploadedAttachment3 = uploadAttachment(OCTET_CONTENT_TYPE, bytes3.getBytes(StandardCharsets.UTF_8));
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -4065,23 +4057,23 @@ public abstract class SetMessagesMethodTest {
             "          \"attachments\":" +
             "          [" +
             "            {" +
-            "              \"blobId\" : \"" + uploadedAttachment1 + "\", " +
-            "              \"type\" : \"" + attachment.getType() + "\", " +
-            "              \"size\" : " + attachment.getSize() + "," +
+            "              \"blobId\" : \"" + uploadedAttachment1.getAttachmentId().getId() + "\", " +
+            "              \"type\" : \"" + uploadedAttachment1.getType() + "\", " +
+            "              \"size\" : " + uploadedAttachment1.getSize() + "," +
             "              \"name\" : \"ديناصور.png\", " +
             "              \"isInline\" : false" +
             "            }," +
             "            {" +
-            "              \"blobId\" : \"" + uploadedAttachment2 + "\", " +
-            "              \"type\" : \"" + attachment2.getType() + "\", " +
-            "              \"size\" : " + attachment2.getSize() + "," +
+            "              \"blobId\" : \"" + uploadedAttachment2.getAttachmentId().getId() + "\", " +
+            "              \"type\" : \"" + uploadedAttachment2.getType() + "\", " +
+            "              \"size\" : " + uploadedAttachment2.getSize() + "," +
             "              \"name\" : \"эволюционировать.png\", " +
             "              \"isInline\" : false" +
             "            }," +
             "            {" +
-            "              \"blobId\" : \"" + uploadedAttachment3 + "\", " +
-            "              \"type\" : \"" + attachment3.getType() + "\", " +
-            "              \"size\" : " + attachment3.getSize() + "," +
+            "              \"blobId\" : \"" + uploadedAttachment3.getAttachmentId().getId() + "\", " +
+            "              \"type\" : \"" + uploadedAttachment3.getType() + "\", " +
+            "              \"size\" : " + uploadedAttachment3.getSize() + "," +
             "              \"name\" : \"进化还是不.png\"," +
             "              \"isInline\" : false" +
             "            }" +
@@ -4116,23 +4108,12 @@ public abstract class SetMessagesMethodTest {
 
     @Test
     public void filenamesAttachmentsWithNonASCIICharactersShouldBeRetrievedWhenChainingSetMessagesAndGetMessages() throws Exception {
-        Attachment attachment = Attachment.builder()
-            .bytes("attachment".getBytes(StandardCharsets.UTF_8))
-            .type("application/octet-stream")
-            .build();
-        String uploadedAttachment1 = uploadAttachment(attachment);
-
-        Attachment attachment2 = Attachment.builder()
-            .bytes("attachment2".getBytes(StandardCharsets.UTF_8))
-            .type("application/octet-stream")
-            .build();
-        String uploadedAttachment2 = uploadAttachment(attachment2);
-
-        Attachment attachment3 = Attachment.builder()
-            .bytes("attachment3".getBytes(StandardCharsets.UTF_8))
-            .type("application/octet-stream")
-            .build();
-        String uploadedAttachment3 = uploadAttachment(attachment3);
+        String bytes1 = "attachment";
+        String bytes2 = "attachment2";
+        String bytes3 = "attachment3";
+        Attachment uploadedAttachment1 = uploadAttachment(OCTET_CONTENT_TYPE, bytes1.getBytes(StandardCharsets.UTF_8));
+        Attachment uploadedAttachment2 = uploadAttachment(OCTET_CONTENT_TYPE, bytes2.getBytes(StandardCharsets.UTF_8));
+        Attachment uploadedAttachment3 = uploadAttachment(OCTET_CONTENT_TYPE, bytes3.getBytes(StandardCharsets.UTF_8));
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -4153,23 +4134,23 @@ public abstract class SetMessagesMethodTest {
             "          \"attachments\":" +
             "          [" +
             "            {" +
-            "              \"blobId\" : \"" + uploadedAttachment1 + "\", " +
-            "              \"type\" : \"" + attachment.getType() + "\", " +
-            "              \"size\" : " + attachment.getSize() + "," +
+            "              \"blobId\" : \"" + uploadedAttachment1.getAttachmentId().getId() + "\", " +
+            "              \"type\" : \"" + uploadedAttachment1.getType() + "\", " +
+            "              \"size\" : " + uploadedAttachment1.getSize() + "," +
             "              \"name\" : \"ديناصور.png\", " +
             "              \"isInline\" : false" +
             "            }," +
             "            {" +
-            "              \"blobId\" : \"" + uploadedAttachment2 + "\", " +
-            "              \"type\" : \"" + attachment2.getType() + "\", " +
-            "              \"size\" : " + attachment2.getSize() + "," +
+            "              \"blobId\" : \"" + uploadedAttachment2.getAttachmentId().getId() + "\", " +
+            "              \"type\" : \"" + uploadedAttachment2.getType() + "\", " +
+            "              \"size\" : " + uploadedAttachment2.getSize() + "," +
             "              \"name\" : \"эволюционировать.png\", " +
             "              \"isInline\" : false" +
             "            }," +
             "            {" +
-            "              \"blobId\" : \"" + uploadedAttachment3 + "\", " +
-            "              \"type\" : \"" + attachment3.getType() + "\", " +
-            "              \"size\" : " + attachment3.getSize() + "," +
+            "              \"blobId\" : \"" + uploadedAttachment3.getAttachmentId().getId() + "\", " +
+            "              \"type\" : \"" + uploadedAttachment3.getType() + "\", " +
+            "              \"size\" : " + uploadedAttachment3.getSize() + "," +
             "              \"name\" : \"进化还是不.png\"," +
             "              \"isInline\" : false" +
             "            }" +
@@ -4220,30 +4201,40 @@ public abstract class SetMessagesMethodTest {
             .body(thirdAttachment + ".name", equalTo("进化还是不.png"));
     }
 
-    private String uploadAttachment(Attachment attachment) throws IOException {
-        return with()
+    private Attachment uploadAttachment(String contentType, byte[] content) {
+        JsonPath json = with()
             .header("Authorization", accessToken.asString())
-            .contentType(attachment.getType())
-            .body(attachment.getStream())
+            .contentType(contentType)
+            .body(new ByteArrayInputStream(content))
             .post("/upload")
         .then()
             .extract()
             .body()
-            .jsonPath()
-            .getString("blobId");
+            .jsonPath();
+
+        return Attachment.builder()
+            .attachmentId(AttachmentId.from(json.getString("blobId")))
+            .size(json.getLong("size"))
+            .type(json.getString("type"))
+            .build();
     }
 
-    private String uploadTextAttachment(Attachment attachment) throws IOException {
-        return with()
+    private Attachment uploadTextAttachment(String contentType, String content) {
+        JsonPath json = with()
             .header("Authorization", accessToken.asString())
-            .contentType(attachment.getType())
-            .body(new String(IOUtils.toByteArray(attachment.getStream()), StandardCharsets.UTF_8))
+            .contentType(contentType)
+            .body(content)
             .post("/upload")
         .then()
             .extract()
             .body()
-            .jsonPath()
-            .getString("blobId");
+            .jsonPath();
+
+        return Attachment.builder()
+            .attachmentId(AttachmentId.from(json.getString("blobId")))
+            .size(json.getLong("size"))
+            .type(json.getString("type"))
+            .build();
     }
 
     @Test
@@ -4255,11 +4246,7 @@ public abstract class SetMessagesMethodTest {
             50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,
             100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127};
 
-        Attachment attachment = Attachment.builder()
-            .bytes(rawBytes)
-            .type("application/octet-stream")
-            .build();
-        String uploadedAttachment = uploadAttachment(attachment);
+        Attachment uploadedAttachment = uploadAttachment(OCTET_CONTENT_TYPE, rawBytes);
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -4275,9 +4262,9 @@ public abstract class SetMessagesMethodTest {
             "        \"textBody\": \"Test body\"," +
             "        \"mailboxIds\": [\"" + outboxId + "\"], " +
             "        \"attachments\": [" +
-            "               {\"blobId\" : \"" + uploadedAttachment + "\", " +
-            "               \"type\" : \"" + attachment.getType() + "\", " +
-            "               \"size\" : " + attachment.getSize() + ", " +
+            "               {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
+            "               \"type\" : \"" + uploadedAttachment.getType() + "\", " +
+            "               \"size\" : " + uploadedAttachment.getSize() + ", " +
             "               \"cid\" : \"123456789\", " +
             "               \"isInline\" : true }" +
             "           ]" +
@@ -4316,8 +4303,8 @@ public abstract class SetMessagesMethodTest {
             .body(NAME, equalTo("messages"))
             .body(ARGUMENTS + ".list", hasSize(1))
             .body(firstMessage + ".attachments", hasSize(1))
-            .body(firstAttachment + ".type", equalTo("application/octet-stream"))
-            .body(firstAttachment + ".size", equalTo((int) attachment.getSize()))
+            .body(firstAttachment + ".type", equalTo(OCTET_CONTENT_TYPE))
+            .body(firstAttachment + ".size", equalTo(rawBytes.length))
             .body(firstAttachment + ".cid", equalTo("123456789"))
             .body(firstAttachment + ".isInline", equalTo(true))
             .extract()
@@ -4331,11 +4318,7 @@ public abstract class SetMessagesMethodTest {
     @Test
     public void attachmentsShouldBeRetrievedWhenChainingSetMessagesAndGetMessagesTextAttachment() throws Exception {
         byte[] rawBytes = ByteStreams.toByteArray(new ZeroedInputStream(_1MB));
-        Attachment attachment = Attachment.builder()
-            .bytes(rawBytes)
-            .type("application/octet-stream")
-            .build();
-        String uploadedAttachment = uploadAttachment(attachment);
+        Attachment uploadedAttachment = uploadAttachment(OCTET_CONTENT_TYPE, rawBytes);
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -4351,9 +4334,9 @@ public abstract class SetMessagesMethodTest {
             "        \"textBody\": \"Test body\"," +
             "        \"mailboxIds\": [\"" + outboxId + "\"], " +
             "        \"attachments\": [" +
-            "               {\"blobId\" : \"" + uploadedAttachment + "\", " +
-            "               \"type\" : \"" + attachment.getType() + "\", " +
-            "               \"size\" : " + attachment.getSize() + ", " +
+            "               {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
+            "               \"type\" : \"" + uploadedAttachment.getType() + "\", " +
+            "               \"size\" : " + uploadedAttachment.getSize() + ", " +
             "               \"cid\" : \"123456789\", " +
             "               \"isInline\" : true }" +
             "           ]" +
@@ -4393,8 +4376,8 @@ public abstract class SetMessagesMethodTest {
             .body(NAME, equalTo("messages"))
             .body(ARGUMENTS + ".list", hasSize(1))
             .body(firstMessage + ".attachments", hasSize(1))
-            .body(firstAttachment + ".type", equalTo("application/octet-stream"))
-            .body(firstAttachment + ".size", equalTo((int) attachment.getSize()))
+            .body(firstAttachment + ".type", equalTo(OCTET_CONTENT_TYPE))
+            .body(firstAttachment + ".size", equalTo(rawBytes.length))
             .body(firstAttachment + ".cid", equalTo("123456789"))
             .body(firstAttachment + ".isInline", equalTo(true))
             .extract()
@@ -4425,14 +4408,11 @@ public abstract class SetMessagesMethodTest {
 
     @Test
     public void attachmentsAndBodysShouldBeRetrievedWhenChainingSetMessagesAndGetMessagesWithMixedTextAndHtmlBodyAndHtmlAttachment() throws Exception {
-        byte[] rawBytes = ("<html>\n" +
+        String text = "<html>\n" +
             "  <body>attachment</body>\n" + // needed indentation, else restassured is adding some
-            "</html>").getBytes(StandardCharsets.UTF_8);
-        Attachment attachment = Attachment.builder()
-            .bytes(rawBytes)
-            .type("text/html; charset=UTF-8")
-            .build();
-        String uploadedBlobId = uploadTextAttachment(attachment);
+            "</html>";
+        String contentType = "text/html; charset=UTF-8";
+        Attachment uploadedAttachment = uploadTextAttachment(contentType, text);
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -4449,9 +4429,9 @@ public abstract class SetMessagesMethodTest {
             "        \"htmlBody\": \"Test <b>body</b>, HTML version\"," +
             "        \"mailboxIds\": [\"" + outboxId + "\"], " +
             "        \"attachments\": [" +
-            "               {\"blobId\" : \"" + uploadedBlobId + "\", " +
-            "               \"type\" : \"" + attachment.getType() + "\", " +
-            "               \"size\" : " + attachment.getSize() + ", " +
+            "               {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
+            "               \"type\" : \"" + uploadedAttachment.getType() + "\", " +
+            "               \"size\" : " + uploadedAttachment.getSize() + ", " +
             "               \"isInline\" : false }" +
             "           ]" +
             "      }}" +
@@ -4494,24 +4474,21 @@ public abstract class SetMessagesMethodTest {
             .body(firstMessage + ".htmlBody", equalTo("Test <b>body</b>, HTML version"))
             .body(firstMessage + ".attachments", hasSize(1))
             .body(firstAttachment + ".type", equalTo("text/html"))
-            .body(firstAttachment + ".size", equalTo((int) attachment.getSize()))
+            .body(firstAttachment + ".size", equalTo(text.length()))
             .extract()
             .jsonPath()
             .getString(firstAttachment + ".blobId");
 
-        checkBlobContent(blobId, rawBytes);
+        checkBlobContent(blobId, text.getBytes(StandardCharsets.UTF_8));
     }
 
     @Test
     public void attachmentsAndBodyShouldBeRetrievedWhenChainingSetMessagesAndGetMessagesWithTextBodyAndHtmlAttachment() throws Exception {
-        byte[] rawBytes = ("<html>\n" +
+        String text = "<html>\n" +
             "  <body>attachment</body>\n" + // needed indentation, else restassured is adding some
-            "</html>").getBytes(StandardCharsets.UTF_8);
-        Attachment attachment = Attachment.builder()
-            .bytes(rawBytes)
-            .type("text/html; charset=UTF-8")
-            .build();
-        String uploadedBlobId = uploadTextAttachment(attachment);
+            "</html>";
+        String contentType = "text/html; charset=UTF-8";
+        Attachment uploadedAttachment = uploadTextAttachment(contentType, text);
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -4527,9 +4504,9 @@ public abstract class SetMessagesMethodTest {
             "        \"textBody\": \"Test body, plain text version\"," +
             "        \"mailboxIds\": [\"" + outboxId + "\"], " +
             "        \"attachments\": [" +
-            "               {\"blobId\" : \"" + uploadedBlobId + "\", " +
-            "               \"type\" : \"" + attachment.getType() + "\", " +
-            "               \"size\" : " + attachment.getSize() + ", " +
+            "               {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
+            "               \"type\" : \"" + uploadedAttachment.getType() + "\", " +
+            "               \"size\" : " + uploadedAttachment.getSize() + ", " +
             "               \"isInline\" : false }" +
             "           ]" +
             "      }}" +
@@ -4572,15 +4549,15 @@ public abstract class SetMessagesMethodTest {
             .body(firstMessage + ".htmlBody", isEmptyOrNullString())
             .body(firstMessage + ".attachments", hasSize(1))
             .body(firstAttachment + ".type", equalTo("text/html"))
-            .body(firstAttachment + ".size", equalTo((int) attachment.getSize()))
+            .body(firstAttachment + ".size", equalTo((int) uploadedAttachment.getSize()))
             .extract()
             .jsonPath()
             .getString(firstAttachment + ".blobId");
 
-        checkBlobContent(blobId, rawBytes);
+        checkBlobContent(blobId, text.getBytes(StandardCharsets.UTF_8));
     }
 
-    public void checkBlobContent(String blobId, byte[] rawBytes) {
+    private void checkBlobContent(String blobId, byte[] rawBytes) {
         byte[] attachmentBytes = with()
             .header("Authorization", accessToken.asString())
             .get("/download/" + blobId)
@@ -4589,17 +4566,15 @@ public abstract class SetMessagesMethodTest {
             .body()
             .asByteArray();
 
-        assertThat(attachmentBytes).containsExactly(rawBytes);
+        assertThat(new ByteArrayInputStream(attachmentBytes))
+            .hasSameContentAs(new ByteArrayInputStream(rawBytes));
     }
 
     @Test
     public void attachmentAndEmptyBodyShouldBeRetrievedWhenChainingSetMessagesAndGetMessagesWithTextAttachmentWithoutMailBody() throws Exception {
-        byte[] rawBytes = ("some text").getBytes(StandardCharsets.UTF_8);
-        Attachment attachment = Attachment.builder()
-            .bytes(rawBytes)
-            .type("text/plain; charset=UTF-8")
-            .build();
-        String uploadedBlobId = uploadTextAttachment(attachment);
+        String text = "some text";
+        String contentType = "text/plain; charset=UTF-8";
+        Attachment uploadedAttachment = uploadTextAttachment(contentType, text);
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -4614,9 +4589,9 @@ public abstract class SetMessagesMethodTest {
             "        \"subject\": \"Message with an attachment\"," +
             "        \"mailboxIds\": [\"" + outboxId + "\"], " +
             "        \"attachments\": [" +
-            "               {\"blobId\" : \"" + uploadedBlobId + "\", " +
-            "               \"type\" : \"" + attachment.getType() + "\", " +
-            "               \"size\" : " + attachment.getSize() + ", " +
+            "               {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
+            "               \"type\" : \"" + uploadedAttachment.getType() + "\", " +
+            "               \"size\" : " + uploadedAttachment.getSize() + ", " +
             "               \"isInline\" : false }" +
             "           ]" +
             "      }}" +
@@ -4659,12 +4634,12 @@ public abstract class SetMessagesMethodTest {
             .body(firstMessage + ".htmlBody", isEmptyOrNullString())
             .body(firstMessage + ".attachments", hasSize(1))
             .body(firstAttachment + ".type", equalTo("text/plain"))
-            .body(firstAttachment + ".size", equalTo((int) attachment.getSize()))
+            .body(firstAttachment + ".size", equalTo((int) uploadedAttachment.getSize()))
             .extract()
             .jsonPath()
             .getString(firstAttachment + ".blobId");
 
-        checkBlobContent(blobId, rawBytes);
+        checkBlobContent(blobId, text.getBytes(StandardCharsets.UTF_8));
     }
 
     @Test
@@ -5357,11 +5332,9 @@ public abstract class SetMessagesMethodTest {
 
     @Test
     public void setMessagesShouldCreateMessageWhenSendingMessageWithNonIndexableAttachment() throws Exception {
-        Attachment nonIndexableAttachment = Attachment.builder()
-                .bytes(ClassLoaderUtils.getSystemResourceAsByteArray("attachment/nonIndexableAttachment.html"))
-                .type("text/html")
-                .build();
-        String uploadedBlobId = uploadTextAttachment(nonIndexableAttachment);
+        byte[] bytes = ClassLoaderUtils.getSystemResourceAsByteArray("attachment/nonIndexableAttachment.html");
+        String contentType = "text/html";
+        Attachment uploadedAttachment = uploadAttachment(contentType, bytes);
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -5377,10 +5350,10 @@ public abstract class SetMessagesMethodTest {
                 "        \"textBody\": \"Test body\"," +
                 "        \"mailboxIds\": [\"" + outboxId + "\"], " +
                 "        \"attachments\": [" +
-                "               {\"blobId\" : \"" + uploadedBlobId + "\", " +
-                "               \"type\" : \"" + nonIndexableAttachment.getType() + "\", " +
+                "               {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
+                "               \"type\" : \"" + uploadedAttachment.getType() + "\", " +
                 "               \"name\" : \"nonIndexableAttachment.html\", " +
-                "               \"size\" : " + nonIndexableAttachment.getSize() + "}" +
+                "               \"size\" : " + uploadedAttachment.getSize() + "}" +
                 "           ]" +
                 "      }}" +
                 "    }," +
@@ -5402,18 +5375,15 @@ public abstract class SetMessagesMethodTest {
             .body(ARGUMENTS + ".notCreated", aMapWithSize(0))
             .body(ARGUMENTS + ".created", aMapWithSize(1))
             .body(createdPath + ".attachments", hasSize(1))
-            .body(singleAttachment + ".blobId", equalTo(uploadedBlobId))
-            .body(singleAttachment + ".type", equalTo("text/html; charset=UTF-8"))
-            .body(singleAttachment + ".size", equalTo((int) nonIndexableAttachment.getSize()));
+            .body(singleAttachment + ".type", equalTo("text/html"))
+            .body(singleAttachment + ".size", equalTo((int) uploadedAttachment.getSize()));
     }
 
     @Test
     public void messageWithNonIndexableAttachmentShouldBeRetrievedWhenChainingSetMessagesAndGetMessages() throws Exception {
-        Attachment nonIndexableAttachment = Attachment.builder()
-                .bytes(ClassLoaderUtils.getSystemResourceAsByteArray("attachment/nonIndexableAttachment.html"))
-                .type("text/html")
-                .build();
-        String uploadedBlobId = uploadTextAttachment(nonIndexableAttachment);
+        byte[] bytes = ClassLoaderUtils.getSystemResourceAsByteArray("attachment/nonIndexableAttachment.html");
+        String contentType = "text/html";
+        Attachment uploadedAttachment = uploadAttachment(contentType, bytes);
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -5429,10 +5399,10 @@ public abstract class SetMessagesMethodTest {
                 "        \"textBody\": \"Test body\"," +
                 "        \"mailboxIds\": [\"" + outboxId + "\"], " +
                 "        \"attachments\": [" +
-                "               {\"blobId\" : \"" + uploadedBlobId + "\", " +
-                "               \"type\" : \"" + nonIndexableAttachment.getType() + "\", " +
+                "               {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
+                "               \"type\" : \"" + uploadedAttachment.getType() + "\", " +
                 "               \"name\" : \"nonIndexableAttachment.html\", " +
-                "               \"size\" : " + nonIndexableAttachment.getSize() + "}" +
+                "               \"size\" : " + uploadedAttachment.getSize() + "}" +
                 "           ]" +
                 "      }}" +
                 "    }," +
@@ -5469,11 +5439,9 @@ public abstract class SetMessagesMethodTest {
 
     @Test
     public void messageWithNonIndexableAttachmentShouldHaveItsEmailBodyIndexed() throws Exception {
-        Attachment nonIndexableAttachment = Attachment.builder()
-                .bytes(ClassLoaderUtils.getSystemResourceAsByteArray("attachment/nonIndexableAttachment.html"))
-                .type("text/html")
-                .build();
-        String uploadedBlobId = uploadTextAttachment(nonIndexableAttachment);
+        byte[] bytes = ClassLoaderUtils.getSystemResourceAsByteArray("attachment/nonIndexableAttachment.html");
+        String contentType = "text/html";
+        Attachment uploadedAttachment = uploadAttachment(contentType, bytes);
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -5490,10 +5458,10 @@ public abstract class SetMessagesMethodTest {
                 "        \"textBody\": \"Test body\"," +
                 "        \"mailboxIds\": [\"" + outboxId + "\"], " +
                 "        \"attachments\": [" +
-                "               {\"blobId\" : \"" + uploadedBlobId + "\", " +
-                "               \"type\" : \"" + nonIndexableAttachment.getType() + "\", " +
+                "               {\"blobId\" : \"" + uploadedAttachment.getAttachmentId().getId() + "\", " +
+                "               \"type\" : \"" + uploadedAttachment.getType() + "\", " +
                 "               \"name\" : \"nonIndexableAttachment.html\", " +
-                "               \"size\" : " + nonIndexableAttachment.getSize() + "}" +
+                "               \"size\" : " + uploadedAttachment.getSize() + "}" +
                 "           ]" +
                 "      }}" +
                 "    }," +
@@ -5525,16 +5493,10 @@ public abstract class SetMessagesMethodTest {
 
     @Test
     public void setMessagesShouldReturnAttachmentsWhenMessageHasInlinedAttachmentButNoCid() throws Exception {
-        Attachment attachment = Attachment.builder()
-            .bytes("attachment".getBytes(StandardCharsets.UTF_8))
-            .type("application/octet-stream")
-            .build();
-        String uploadedAttachment1 = uploadAttachment(attachment);
-        Attachment attachment2 = Attachment.builder()
-            .bytes("attachment2".getBytes(StandardCharsets.UTF_8))
-            .type("application/octet-stream")
-            .build();
-        String uploadedAttachment2 = uploadAttachment(attachment2);
+        String bytes = "attachment";
+        Attachment uploadedAttachment1 = uploadAttachment(OCTET_CONTENT_TYPE, bytes.getBytes(StandardCharsets.UTF_8));
+        String bytes2 = "attachment2";
+        Attachment uploadedAttachment2 = uploadAttachment(OCTET_CONTENT_TYPE, bytes2.getBytes(StandardCharsets.UTF_8));
 
         String messageCreationId = "creationId";
         String fromAddress = USERNAME.asString();
@@ -5550,12 +5512,12 @@ public abstract class SetMessagesMethodTest {
             "        \"textBody\": \"Test body\"," +
             "        \"mailboxIds\": [\"" + outboxId + "\"], " +
             "        \"attachments\": [" +
-            "               {\"blobId\" : \"" + uploadedAttachment1 + "\", " +
-            "               \"type\" : \"" + attachment.getType() + "\", " +
-            "               \"size\" : " + attachment.getSize() + "}," +
-            "               {\"blobId\" : \"" + uploadedAttachment2 + "\", " +
-            "               \"type\" : \"" + attachment2.getType() + "\", " +
-            "               \"size\" : " + attachment2.getSize() + ", " +
+            "               {\"blobId\" : \"" + uploadedAttachment1.getAttachmentId().getId() + "\", " +
+            "               \"type\" : \"" + uploadedAttachment1.getType() + "\", " +
+            "               \"size\" : " + uploadedAttachment1.getSize() + "}," +
+            "               {\"blobId\" : \"" + uploadedAttachment2.getAttachmentId().getId() + "\", " +
+            "               \"type\" : \"" + uploadedAttachment2.getType() + "\", " +
+            "               \"size\" : " + uploadedAttachment2.getSize() + ", " +
             "               \"isInline\" : true }" +
             "           ]" +
             "      }}" +
@@ -5565,10 +5527,8 @@ public abstract class SetMessagesMethodTest {
             "]";
 
         String createdPath = ARGUMENTS + ".created[\"" + messageCreationId + "\"]";
-        String firstAttachment = createdPath + ".attachments[0]";
-        String secondAttachment = createdPath + ".attachments[1]";
 
-        given()
+        String json = given()
             .header("Authorization", accessToken.asString())
             .body(requestBody)
         .when()
@@ -5579,16 +5539,22 @@ public abstract class SetMessagesMethodTest {
             .body(ARGUMENTS + ".notCreated", aMapWithSize(0))
             .body(ARGUMENTS + ".created", aMapWithSize(1))
             .body(createdPath + ".attachments", hasSize(2))
-            .body(firstAttachment + ".blobId", equalTo(uploadedAttachment1))
-            .body(firstAttachment + ".type", equalTo("application/octet-stream; charset=UTF-8"))
-            .body(firstAttachment + ".size", equalTo((int) attachment.getSize()))
-            .body(firstAttachment + ".cid", nullValue())
-            .body(firstAttachment + ".isInline", equalTo(false))
-            .body(secondAttachment + ".blobId", equalTo(uploadedAttachment2))
-            .body(secondAttachment + ".type", equalTo("application/octet-stream; charset=UTF-8"))
-            .body(secondAttachment + ".size", equalTo((int) attachment2.getSize()))
-            .body(secondAttachment + ".cid", nullValue())
-            .body(secondAttachment + ".isInline", equalTo(true));
+            .extract()
+            .asString();
+
+        assertThatJson(json)
+            .withOptions(new Options(Option.TREATING_NULL_AS_ABSENT, Option.IGNORING_ARRAY_ORDER, Option.IGNORING_EXTRA_FIELDS))
+            .inPath(createdPath + ".attachments")
+            .isEqualTo("[{" +
+                "  \"type\":\"application/octet-stream\"," +
+                "  \"size\":" + bytes2.length() + "," +
+                "  \"isInline\":false" +
+                "}, {" +
+                "  \"type\":\"application/octet-stream\"," +
+                "  \"size\":" + bytes.length() + "," +
+                "  \"isInline\":false" + // See JAMES-2258 inline should be false in case of no Content-ID for inlined attachment
+                // Stored attachment will not be considered as having an inlined attachment.
+                "}]");
     }
 
     @Test
@@ -6146,7 +6112,4 @@ public abstract class SetMessagesMethodTest {
 
         assertThat(receivedMimeMessageId).isEqualTo(creationMimeMessageId);
     }
-
-
- */
 }
diff --git a/server/protocols/jmap-draft-integration-testing/memory-jmap-draft-integration-testing/pom.xml b/server/protocols/jmap-draft-integration-testing/memory-jmap-draft-integration-testing/pom.xml
index 4a35f4a..ef9d639 100644
--- a/server/protocols/jmap-draft-integration-testing/memory-jmap-draft-integration-testing/pom.xml
+++ b/server/protocols/jmap-draft-integration-testing/memory-jmap-draft-integration-testing/pom.xml
@@ -144,6 +144,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>net.javacrumbs.json-unit</groupId>
+            <artifactId>json-unit-assertj</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.pdfbox</groupId>
             <artifactId>pdfbox</artifactId>
             <scope>test</scope>
diff --git a/server/protocols/jmap-draft-integration-testing/memory-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/memory/MemorySetMessagesMethodTest.java b/server/protocols/jmap-draft-integration-testing/memory-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/memory/MemorySetMessagesMethodTest.java
index 443e044..bbf001a 100644
--- a/server/protocols/jmap-draft-integration-testing/memory-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/memory/MemorySetMessagesMethodTest.java
+++ b/server/protocols/jmap-draft-integration-testing/memory-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/memory/MemorySetMessagesMethodTest.java
@@ -30,7 +30,6 @@ import org.apache.james.mailbox.model.MessageId;
 import org.junit.Rule;
 
 public class MemorySetMessagesMethodTest extends SetMessagesMethodTest {
-/*
     @Rule
     public MemoryJmapTestRule memoryJmap = new MemoryJmapTestRule();
 
@@ -47,5 +46,4 @@ public class MemorySetMessagesMethodTest extends SetMessagesMethodTest {
     protected MessageId randomMessageId() {
         return new InMemoryMessageId.Factory().fromString(String.valueOf(ThreadLocalRandom.current().nextInt(100000) + 100));
     }
-*/
 }
diff --git a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/pom.xml b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/pom.xml
index b6716c0..e05b983 100644
--- a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/pom.xml
+++ b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/pom.xml
@@ -148,6 +148,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>net.javacrumbs.json-unit</groupId>
+            <artifactId>json-unit-assertj</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.pdfbox</groupId>
             <artifactId>pdfbox</artifactId>
             <scope>test</scope>
diff --git a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SetMessagesMethodTest.java b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SetMessagesMethodTest.java
index 67b4e94..c92c966 100644
--- a/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SetMessagesMethodTest.java
+++ b/server/protocols/jmap-draft-integration-testing/rabbitmq-jmap-draft-integration-testing/src/test/java/org/apache/james/jmap/rabbitmq/RabbitMQAwsS3SetMessagesMethodTest.java
@@ -32,7 +32,6 @@ import org.junit.Rule;
 import org.junit.Test;
 
 public class RabbitMQAwsS3SetMessagesMethodTest extends SetMessagesMethodTest {
-/*
     @Rule
     public DockerCassandraRule cassandra = new DockerCassandraRule();
 
@@ -61,7 +60,5 @@ public class RabbitMQAwsS3SetMessagesMethodTest extends SetMessagesMethodTest {
     public void setMessagesWithABigBodyShouldReturnCreatedMessageWhenSendingMessage() {
 
     }
-
- */
 }
 


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


[james-project] 10/37: JAMES-2997 step #8 Stop relying on Attachment byte array in AttachmentMapper::storeAttachmentsForMessage

Posted by bt...@apache.org.
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 431a8e128bf972f4f78792ae93f59f5c1ac30b86
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Jan 17 13:41:34 2020 +0700

    JAMES-2997 step #8 Stop relying on Attachment byte array in AttachmentMapper::storeAttachmentsForMessage
    
    This forced me to review attachment write path:
     - AttachmentId needs to be allocated by the attachment mapper
     - Thus we can not return MessageAttachment (requiring an attachmentId) within
     Message parser
     - Attachments needs to be persisted first, then the message is persisted.
    
    Along the way improvements:
     - Rely on casting to avoid byte reallocation upon reading content in MessageParser
     - Avoid parsing attachment for backends not storing them
---
 mailbox/api/pom.xml                                |   1 -
 .../james/mailbox/model/MessageAttachment.java     |   5 +
 .../james/mailbox/model/ParsedAttachment.java      | 130 +++++++++++++++++++++
 .../mailbox/cassandra/CassandraMessageManager.java |  16 +--
 .../cassandra/mail/CassandraAttachmentMapper.java  |  19 +--
 .../model/openjpa/AbstractJPAMailboxMessage.java   |   9 +-
 .../mailbox/maildir/mail/model/MaildirMessage.java |   9 +-
 .../mailbox/inmemory/InMemoryMessageManager.java   |  16 +--
 .../inmemory/mail/InMemoryAttachmentMapper.java    |  32 ++++-
 .../james/mailbox/store/StoreMessageManager.java   |  26 ++---
 .../james/mailbox/store/mail/AttachmentMapper.java |   4 +-
 .../store/mail/model/impl/MessageParser.java       |  37 +++---
 .../model/MessageWithAttachmentMapperTest.java     |  66 +++++------
 13 files changed, 264 insertions(+), 106 deletions(-)

diff --git a/mailbox/api/pom.xml b/mailbox/api/pom.xml
index 4706a0e..7ce79e2 100644
--- a/mailbox/api/pom.xml
+++ b/mailbox/api/pom.xml
@@ -82,7 +82,6 @@
         <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
-            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>javax.inject</groupId>
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageAttachment.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageAttachment.java
index fc37b03..8e6b407 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageAttachment.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageAttachment.java
@@ -55,6 +55,11 @@ public class MessageAttachment {
             return this;
         }
 
+        public Builder name(Optional<String> name) {
+            this.name = name;
+            return this;
+        }
+
         public Builder cid(Optional<Cid> cid) {
             Preconditions.checkNotNull(cid);
             this.cid = cid;
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java
new file mode 100644
index 0000000..649b034
--- /dev/null
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/ParsedAttachment.java
@@ -0,0 +1,130 @@
+/****************************************************************
+ * 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.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.model;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Optional;
+
+import org.apache.commons.io.IOUtils;
+
+public class ParsedAttachment {
+    interface Builder {
+        @FunctionalInterface
+        interface RequireContentType {
+            RequireContent contentType(String contentType);
+        }
+
+        @FunctionalInterface
+        interface RequireContent {
+            RequireName content(InputStream stream);
+        }
+
+        @FunctionalInterface
+        interface RequireName {
+            RequireCid name(Optional<String> name);
+
+            default RequireCid name(String name) {
+                return name(Optional.of(name));
+            }
+
+            default RequireCid noName() {
+                return name(Optional.empty());
+            }
+        }
+
+        @FunctionalInterface
+        interface RequireCid {
+            RequireIsInline cid(Optional<Cid> cid);
+
+            default RequireIsInline cid(Cid cid) {
+                return cid(Optional.of(cid));
+            }
+
+            default RequireIsInline noCid() {
+                return cid(Optional.empty());
+            }
+        }
+
+        @FunctionalInterface
+        interface RequireIsInline {
+            ParsedAttachment inline(boolean isInline);
+
+            default ParsedAttachment inline() {
+                return inline(true);
+            }
+        }
+    }
+
+    public static Builder.RequireContentType builder() {
+        return contentType -> content -> name -> cid -> isInline -> new ParsedAttachment(contentType, content, name, cid, isInline);
+    }
+
+    private final String contentType;
+    private final InputStream content;
+    private final Optional<String> name;
+    private final Optional<Cid> cid;
+    private final boolean isInline;
+
+    private ParsedAttachment(String contentType, InputStream content, Optional<String> name, Optional<Cid> cid, boolean isInline) {
+        this.contentType = contentType;
+        this.content = content;
+        this.name = name;
+        this.cid = cid;
+        this.isInline = isInline;
+    }
+
+    public String getContentType() {
+        return contentType;
+    }
+
+    public InputStream getContent() {
+        return content;
+    }
+
+    public Optional<String> getName() {
+        return name;
+    }
+
+    public Optional<Cid> getCid() {
+        return cid;
+    }
+
+    public boolean isInline() {
+        return isInline;
+    }
+
+    public MessageAttachment asMessageAttachment(AttachmentId attachmentId) {
+        try {
+            return MessageAttachment.builder()
+                .attachment(Attachment.builder()
+                        .attachmentId(attachmentId)
+                        .type(contentType)
+                        .bytes(IOUtils.toByteArray(content))
+                        .build())
+                    .name(name)
+                    .cid(cid)
+                    .isInline(isInline)
+                    .build();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
index d699e7d..d3cbdde 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
@@ -22,6 +22,7 @@ package org.apache.james.mailbox.cassandra;
 import java.util.List;
 
 import javax.mail.Flags;
+import javax.mail.internet.SharedInputStream;
 
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
@@ -30,18 +31,16 @@ import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
 import org.apache.james.mailbox.store.BatchSizes;
 import org.apache.james.mailbox.store.PreDeletionHooks;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.StoreRightManager;
-import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
 import org.apache.james.mailbox.store.search.MessageSearchIndex;
 
-import com.github.steveash.guavate.Guavate;
-
 /**
  * Cassandra implementation of {@link StoreMessageManager}
  * 
@@ -74,13 +73,10 @@ public class CassandraMessageManager extends StoreMessageManager {
     }
 
     @Override
-    protected void storeAttachment(MailboxMessage message, List<MessageAttachment> messageAttachments, MailboxSession session) throws MailboxException {
-        mapperFactory.getAttachmentMapper(session)
-            .storeAttachmentsForMessage(
-                messageAttachments.stream()
-                    .map(MessageAttachment::getAttachment)
-                    .collect(Guavate.toImmutableList()),
-                message.getMessageId());
+    protected List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream content, MailboxSession session) throws MailboxException {
+        List<ParsedAttachment> attachments = extractAttachments(content);
+        return mapperFactory.getAttachmentMapper(session)
+            .storeAttachmentsForMessage(attachments, messageId);
     }
 
 }
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
index 534e3f1..74fe75c 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
@@ -36,7 +36,9 @@ import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.util.ReactorUtils;
 import org.apache.james.util.io.SizeInputStream;
@@ -130,10 +132,10 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
     }
 
     @Override
-    public void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId) throws MailboxException {
-        Flux.fromIterable(attachments)
+    public List<MessageAttachment> storeAttachmentsForMessage(Collection<ParsedAttachment> parsedAttachments, MessageId ownerMessageId) throws MailboxException {
+        return Flux.fromIterable(parsedAttachments)
             .flatMap(attachment -> storeAttachmentAsync(attachment, ownerMessageId))
-            .then()
+            .collectList()
             .block();
     }
 
@@ -149,10 +151,13 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
         return ownerDAO.retrieveOwners(attachmentId).collect(Guavate.toImmutableList()).block();
     }
 
-    public Mono<Void> storeAttachmentAsync(Attachment attachment, MessageId ownerMessageId) {
-        return Mono.from(blobStore.save(blobStore.getDefaultBucketName(), attachment.getBytes(), LOW_COST))
-            .map(blobId -> CassandraAttachmentDAOV2.from(attachment, blobId))
-            .flatMap(daoAttachment -> storeAttachmentWithIndex(daoAttachment, ownerMessageId));
+    private Mono<MessageAttachment> storeAttachmentAsync(ParsedAttachment parsedAttachment, MessageId ownerMessageId) {
+        AttachmentId attachmentId = AttachmentId.random();
+        SizeInputStream content = new SizeInputStream(parsedAttachment.getContent());
+        return Mono.from(blobStore.save(blobStore.getDefaultBucketName(), content, LOW_COST))
+            .map(blobId -> new DAOAttachment(attachmentId, blobId, parsedAttachment.getContentType(), content.getSize()))
+            .flatMap(daoAttachment -> storeAttachmentWithIndex(daoAttachment, ownerMessageId))
+            .then(Mono.just(parsedAttachment.asMessageAttachment(attachmentId)));
     }
 
     private Mono<Void> storeAttachmentWithIndex(DAOAttachment daoAttachment, MessageId ownerMessageId) {
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
index cfebd40..f174fe6 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
@@ -48,6 +48,7 @@ import org.apache.james.mailbox.jpa.JPAId;
 import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
 import org.apache.james.mailbox.jpa.mail.model.JPAProperty;
 import org.apache.james.mailbox.jpa.mail.model.JPAUserFlag;
+import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.ComposedMessageId;
 import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
 import org.apache.james.mailbox.model.MessageAttachment;
@@ -59,7 +60,6 @@ import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.Property;
 import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
 import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
-import org.apache.james.mime4j.MimeException;
 import org.apache.openjpa.persistence.jdbc.ElementJoinColumn;
 import org.apache.openjpa.persistence.jdbc.ElementJoinColumns;
 import org.apache.openjpa.persistence.jdbc.Index;
@@ -505,8 +505,11 @@ public abstract class AbstractJPAMailboxMessage implements MailboxMessage {
     @Override
     public List<MessageAttachment> getAttachments() {
         try {
-            return new MessageParser().retrieveAttachments(getFullContent());
-        } catch (MimeException | IOException e) {
+            return new MessageParser().retrieveAttachments(getFullContent())
+                .stream()
+                .map(attachmentMetadata -> attachmentMetadata.asMessageAttachment(AttachmentId.random()))
+                .collect(Guavate.toImmutableList());
+        } catch (IOException e) {
             throw new RuntimeException(e);
         }
     }
diff --git a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
index c92a2d9..c2a0b01 100644
--- a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
+++ b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
@@ -30,6 +30,7 @@ import javax.mail.util.SharedFileInputStream;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.james.mailbox.maildir.MaildirMessageName;
+import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.mail.model.DefaultMessageId;
@@ -46,6 +47,7 @@ import org.apache.james.mime4j.stream.MimeConfig;
 import org.apache.james.mime4j.stream.MimeTokenStream;
 import org.apache.james.mime4j.stream.RecursionMode;
 
+import com.github.steveash.guavate.Guavate;
 import com.google.common.io.ByteStreams;
 
 public class MaildirMessage implements Message {
@@ -271,8 +273,11 @@ public class MaildirMessage implements Message {
     @Override
     public List<MessageAttachment> getAttachments() {
         try {
-            return new MessageParser().retrieveAttachments(getFullContent());
-        } catch (MimeException | IOException e) {
+            return new MessageParser().retrieveAttachments(getFullContent())
+                .stream()
+                .map(attachmentMetadata -> attachmentMetadata.asMessageAttachment(AttachmentId.random()))
+                .collect(Guavate.toImmutableList());
+        } catch (IOException e) {
             throw new RuntimeException(e);
         }
     }
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
index fed0e7b..ef84c37 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/InMemoryMessageManager.java
@@ -3,6 +3,7 @@ package org.apache.james.mailbox.inmemory;
 import java.util.List;
 
 import javax.mail.Flags;
+import javax.mail.internet.SharedInputStream;
 
 import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxSession;
@@ -11,6 +12,7 @@ import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
 import org.apache.james.mailbox.store.BatchSizes;
@@ -18,12 +20,9 @@ import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.PreDeletionHooks;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.StoreRightManager;
-import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
 import org.apache.james.mailbox.store.search.MessageSearchIndex;
 
-import com.github.steveash.guavate.Guavate;
-
 public class InMemoryMessageManager extends StoreMessageManager {
 
     private InMemoryMailboxSessionMapperFactory mapperFactory;
@@ -54,12 +53,9 @@ public class InMemoryMessageManager extends StoreMessageManager {
     }
 
     @Override
-    protected void storeAttachment(final MailboxMessage message, final List<MessageAttachment> messageAttachments, final MailboxSession session) throws MailboxException {
-        mapperFactory.getAttachmentMapper(session)
-            .storeAttachmentsForMessage(
-                messageAttachments.stream()
-                    .map(MessageAttachment::getAttachment)
-                    .collect(Guavate.toImmutableList()),
-                message.getMessageId());
+    protected List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream content, MailboxSession session) throws MailboxException {
+        List<ParsedAttachment> attachments = extractAttachments(content);
+        return mapperFactory.getAttachmentMapper(session)
+            .storeAttachmentsForMessage(attachments, messageId);
     }
 }
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
index 9112ece..331c60f 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
@@ -33,9 +33,13 @@ import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
 
+import com.github.fge.lambdas.Throwing;
+import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.ImmutableList;
@@ -116,11 +120,29 @@ public class InMemoryAttachmentMapper implements AttachmentMapper {
     }
 
     @Override
-    public void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId) throws MailboxException {
-        for (Attachment attachment: attachments) {
-            attachmentsById.put(attachment.getAttachmentId(), attachment);
-            attachmentsRawContentById.put(attachment.getAttachmentId(), attachment.getBytes());
-            messageIdsByAttachmentId.put(attachment.getAttachmentId(), ownerMessageId);
+    public List<MessageAttachment> storeAttachmentsForMessage(Collection<ParsedAttachment> parsedAttachments, MessageId ownerMessageId) throws MailboxException {
+        return parsedAttachments.stream()
+            .map(Throwing.<ParsedAttachment, MessageAttachment>function(
+                typedContent -> storeAttachmentForMessage(ownerMessageId, typedContent))
+                .sneakyThrow())
+            .collect(Guavate.toImmutableList());
+    }
+
+    private MessageAttachment storeAttachmentForMessage(MessageId ownerMessageId, ParsedAttachment parsedAttachment) throws MailboxException {
+        AttachmentId attachmentId = AttachmentId.random();
+        try {
+            byte[] bytes = IOUtils.toByteArray(parsedAttachment.getContent());
+
+            attachmentsById.put(attachmentId, Attachment.builder()
+                .attachmentId(attachmentId)
+                .type(parsedAttachment.getContentType())
+                .bytes(bytes)
+                .build());
+            attachmentsRawContentById.put(attachmentId, bytes);
+            messageIdsByAttachmentId.put(attachmentId, ownerMessageId);
+            return parsedAttachment.asMessageAttachment(attachmentId);
+        } catch (IOException e) {
+            throw new MailboxException(String.format("Failed to persist attachment %s of message %s", attachmentId, ownerMessageId.serialize()), e);
         }
     }
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
index 1eb89a7..9f2557b 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
@@ -72,6 +72,7 @@ import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.MessageMoves;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.MessageResultIterator;
+import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.model.UidValidity;
 import org.apache.james.mailbox.model.UpdatedFlags;
@@ -445,15 +446,10 @@ public class StoreMessageManager implements MessageManager {
     private ComposedMessageId createAndDispatchMessage(Date internalDate, MailboxSession mailboxSession, File file, PropertyBuilder propertyBuilder, Flags flags, int bodyStartOctet) throws IOException, MailboxException {
         try (SharedFileInputStream contentIn = new SharedFileInputStream(file)) {
             final int size = (int) file.length();
-
-            final List<MessageAttachment> attachments = extractAttachments(contentIn);
-
-            final MailboxMessage message = createMessage(internalDate, size, bodyStartOctet, contentIn, flags, propertyBuilder, attachments);
-
             new QuotaChecker(quotaManager, quotaRootResolver, mailbox).tryAddition(1, size);
 
             return locker.executeWithLock(getMailboxPath(), () -> {
-                MessageMetaData data = appendMessageToStore(message, attachments, mailboxSession);
+                MessageMetaData data = appendMessageToStore(internalDate, size, bodyStartOctet, contentIn, flags, propertyBuilder, mailboxSession);
 
                 Mailbox mailbox = getMailboxEntity();
 
@@ -461,7 +457,7 @@ public class StoreMessageManager implements MessageManager {
                     .randomEventId()
                     .mailboxSession(mailboxSession)
                     .mailbox(mailbox)
-                    .addMetaData(message.metaData())
+                    .addMetaData(data)
                     .build(),
                     new MailboxIdRegistrationKey(mailbox.getMailboxId()))
                     .subscribeOn(Schedulers.elastic())
@@ -500,9 +496,9 @@ public class StoreMessageManager implements MessageManager {
         return propertyBuilder;
     }
 
-    private List<MessageAttachment> extractAttachments(SharedFileInputStream contentIn) {
+    protected List<ParsedAttachment> extractAttachments(SharedInputStream contentIn) {
         try {
-            return messageParser.retrieveAttachments(contentIn);
+            return messageParser.retrieveAttachments(contentIn.newStream(0, -1));
         } catch (Exception e) {
             LOG.warn("Error while parsing mail's attachments: {}", e.getMessage(), e);
             return ImmutableList.of();
@@ -672,17 +668,19 @@ public class StoreMessageManager implements MessageManager {
         }, MailboxPathLocker.LockType.Write);
     }
 
-    protected MessageMetaData appendMessageToStore(final MailboxMessage message, final List<MessageAttachment> messageAttachments, MailboxSession session) throws MailboxException {
-        final MessageMapper messageMapper = mapperFactory.getMessageMapper(session);
+    private MessageMetaData appendMessageToStore(Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, MailboxSession session) throws MailboxException {
+        MessageMapper messageMapper = mapperFactory.getMessageMapper(session);
+        MessageId messageId = messageIdFactory.generate();
 
         return mapperFactory.getMessageMapper(session).execute(() -> {
-            storeAttachment(message, messageAttachments, session);
+            List<MessageAttachment> attachments = storeAttachments(messageId, content, session);
+            MailboxMessage message = createMessage(internalDate, size, bodyStartOctet, content, flags, propertyBuilder, attachments);
             return messageMapper.add(getMailboxEntity(), message);
         });
     }
 
-    protected void storeAttachment(final MailboxMessage message, final List<MessageAttachment> messageAttachments, final MailboxSession session) throws MailboxException {
-
+    protected List<MessageAttachment> storeAttachments(MessageId messageId, SharedInputStream content, MailboxSession session) throws MailboxException {
+        return ImmutableList.of();
     }
 
     @Override
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
index 6b5493b..196eb91 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/AttachmentMapper.java
@@ -29,7 +29,9 @@ import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.store.transaction.Mapper;
 import org.reactivestreams.Publisher;
 
@@ -43,7 +45,7 @@ public interface AttachmentMapper extends Mapper {
 
     Publisher<Attachment> storeAttachmentForOwner(String contentType, InputStream attachmentContent, Username owner);
 
-    void storeAttachmentsForMessage(Collection<Attachment> attachments, MessageId ownerMessageId) throws MailboxException;
+    List<MessageAttachment> storeAttachmentsForMessage(Collection<ParsedAttachment> attachments, MessageId ownerMessageId) throws MailboxException;
 
     Collection<MessageId> getRelatedMessageIds(AttachmentId attachmentId) throws MailboxException;
 
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
index 50b849d..39a3c75 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.mailbox.store.mail.model.impl;
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -27,15 +28,14 @@ import java.util.Locale;
 import java.util.Optional;
 import java.util.stream.Stream;
 
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.Cid;
-import org.apache.james.mailbox.model.MessageAttachment;
-import org.apache.james.mime4j.MimeException;
+import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mime4j.codec.DecodeMonitor;
 import org.apache.james.mime4j.dom.Body;
 import org.apache.james.mime4j.dom.Entity;
 import org.apache.james.mime4j.dom.Message;
 import org.apache.james.mime4j.dom.Multipart;
+import org.apache.james.mime4j.dom.SingleBody;
 import org.apache.james.mime4j.dom.field.ContentDispositionField;
 import org.apache.james.mime4j.dom.field.ContentIdField;
 import org.apache.james.mime4j.dom.field.ContentTypeField;
@@ -76,7 +76,7 @@ public class MessageParser {
             .unwrap();
     }
 
-    public List<MessageAttachment> retrieveAttachments(InputStream fullContent) throws MimeException, IOException {
+    public List<ParsedAttachment> retrieveAttachments(InputStream fullContent) throws IOException {
         DefaultMessageBuilder defaultMessageBuilder = new DefaultMessageBuilder();
         defaultMessageBuilder.setMimeEntityConfig(MimeConfig.PERMISSIVE);
         defaultMessageBuilder.setDecodeMonitor(DecodeMonitor.SILENT);
@@ -99,13 +99,13 @@ public class MessageParser {
         }
     }
 
-    private Stream<MessageAttachment> listAttachments(Multipart multipart, Context context) {
+    private Stream<ParsedAttachment> listAttachments(Multipart multipart, Context context) {
         return multipart.getBodyParts()
             .stream()
             .flatMap(entity -> listAttachments(entity, context));
     }
 
-    private Stream<MessageAttachment> listAttachments(Entity entity, Context context) {
+    private Stream<ParsedAttachment> listAttachments(Entity entity, Context context) {
         if (isMultipart(entity)) {
             return listAttachments((Multipart) entity.getBody(), Context.fromEntity(entity));
         }
@@ -121,7 +121,7 @@ public class MessageParser {
         return Stream.empty();
     }
 
-    private MessageAttachment retrieveAttachment(Entity entity) throws IOException {
+    private ParsedAttachment retrieveAttachment(Entity entity) throws IOException {
         Optional<ContentTypeField> contentTypeField = getContentTypeField(entity);
         Optional<ContentDispositionField> contentDispositionField = getContentDispositionField(entity);
         Optional<String> contentType = contentType(contentTypeField);
@@ -129,15 +129,12 @@ public class MessageParser {
         Optional<Cid> cid = cid(readHeader(entity, CONTENT_ID, ContentIdField.class));
         boolean isInline = isInline(readHeader(entity, CONTENT_DISPOSITION, ContentDispositionField.class)) && cid.isPresent();
 
-        return MessageAttachment.builder()
-                .attachment(Attachment.builder()
-                    .bytes(getBytes(entity.getBody()))
-                    .type(contentType.orElse(DEFAULT_CONTENT_TYPE))
-                    .build())
-                .name(name.orElse(null))
-                .cid(cid.orElse(null))
-                .isInline(isInline)
-                .build();
+        return ParsedAttachment.builder()
+                .contentType(contentType.orElse(DEFAULT_CONTENT_TYPE))
+                .content(getContent(entity.getBody()))
+                .name(name)
+                .cid(cid)
+                .inline(isInline);
     }
 
     private <T extends ParsedField> Optional<T> readHeader(Entity entity, String headerName, Class<T> clazz) {
@@ -221,11 +218,15 @@ public class MessageParser {
         return readHeader(part, CONTENT_ID, ContentIdField.class).isPresent();
     }
 
-    private byte[] getBytes(Body body) throws IOException {
+    private InputStream getContent(Body body) throws IOException {
+        if (body instanceof SingleBody) {
+            SingleBody singleBody = (SingleBody) body;
+            return singleBody.getInputStream();
+        }
         DefaultMessageWriter messageWriter = new DefaultMessageWriter();
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         messageWriter.writeBody(body, out);
-        return out.toByteArray();
+        return new ByteArrayInputStream(out.toByteArray());
     }
 
     private enum Context {
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageWithAttachmentMapperTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageWithAttachmentMapperTest.java
index f10a0b6..f8d24ba 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageWithAttachmentMapperTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MessageWithAttachmentMapperTest.java
@@ -22,7 +22,9 @@ package org.apache.james.mailbox.store.mail.model;
 import static org.apache.james.mailbox.store.mail.model.MessageAssert.assertThat;
 import static org.assertj.core.api.Assertions.assertThat;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
@@ -32,8 +34,6 @@ import javax.mail.util.SharedByteArrayInputStream;
 
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.Attachment;
-import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.Cid;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxPath;
@@ -41,6 +41,7 @@ import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.UidValidity;
+import org.apache.james.mailbox.model.ParsedAttachment;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
@@ -80,40 +81,35 @@ public abstract class MessageWithAttachmentMapperTest {
         this.attachmentMapper = mapperProvider.createAttachmentMapper();
 
         attachmentsMailbox = createMailbox(MailboxPath.forUser(Username.of("benwa"), "Attachments"));
-
-        Attachment attachment = Attachment.builder()
-                .attachmentId(AttachmentId.from("123"))
-                .bytes("attachment".getBytes())
-                .type("content")
-                .build();
-        Attachment attachment2 = Attachment.builder()
-                .attachmentId(AttachmentId.from("456"))
-                .bytes("attachment2".getBytes())
-                .type("content")
-                .build();
-        messageWith1Attachment = createMessage(attachmentsMailbox, mapperProvider.generateMessageId(), "Subject: Test7 \n\nBody7\n.\n", BODY_START, new PropertyBuilder(), 
-                ImmutableList.of(MessageAttachment.builder()
-                        .attachment(attachment)
-                        .cid(Cid.from("cid"))
-                        .isInline(true)
-                        .build()));
-        messageWith2Attachments = createMessage(attachmentsMailbox, mapperProvider.generateMessageId(), "Subject: Test8 \n\nBody8\n.\n", BODY_START, new PropertyBuilder(),
-                ImmutableList.of(
-                        MessageAttachment.builder()
-                            .attachment(attachment)
-                            .cid(Cid.from("cid"))
-                            .isInline(true)
-                            .build(),
-                        MessageAttachment.builder()
-                            .attachment(attachment2)
-                            .cid(Cid.from("cid2"))
-                            .isInline(false)
-                            .build()));
+        ParsedAttachment attachment1 = ParsedAttachment.builder()
+            .contentType("content")
+            .content(new ByteArrayInputStream("attachment".getBytes(StandardCharsets.UTF_8)))
+            .noName()
+            .cid(Cid.from("cid"))
+            .inline();
+        ParsedAttachment attachment2 = ParsedAttachment.builder()
+            .contentType("content")
+            .content(new ByteArrayInputStream("attachment2".getBytes(StandardCharsets.UTF_8)))
+            .noName()
+            .cid(Cid.from("cid"))
+            .inline();
+        ParsedAttachment attachment3 = ParsedAttachment.builder()
+            .contentType("content")
+            .content(new ByteArrayInputStream("attachment3".getBytes(StandardCharsets.UTF_8)))
+            .noName()
+            .cid(Cid.from("cid"))
+            .inline(false);
+
+        MessageId messageId1 = mapperProvider.generateMessageId();
+        MessageId messageId2 = mapperProvider.generateMessageId();
+        List<MessageAttachment> message1Attachments = attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment1), messageId1);
+        List<MessageAttachment> message2Attachments = attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment2, attachment3), messageId2);
+
+        messageWith1Attachment = createMessage(attachmentsMailbox, messageId1, "Subject: Test7 \n\nBody7\n.\n", BODY_START, new PropertyBuilder(),
+                message1Attachments);
+        messageWith2Attachments = createMessage(attachmentsMailbox, messageId2, "Subject: Test8 \n\nBody8\n.\n", BODY_START, new PropertyBuilder(),
+                message2Attachments);
         messageWithoutAttachment = createMessage(attachmentsMailbox, mapperProvider.generateMessageId(), "Subject: Test1 \n\nBody1\n.\n", BODY_START, new PropertyBuilder());
-
-        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment), messageWith1Attachment.getMessageId());
-        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment), messageWith2Attachments.getMessageId());
-        attachmentMapper.storeAttachmentsForMessage(ImmutableList.of(attachment2), messageWith2Attachments.getMessageId());
     }
 
     @Test


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


[james-project] 22/37: JAMES-2997 Renable MIMEMessageConverterTest

Posted by bt...@apache.org.
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 7f7da1e07cda9792579a5224c4b5998253465c86
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 20 15:07:12 2020 +0700

    JAMES-2997 Renable MIMEMessageConverterTest
---
 .../draft/methods/MIMEMessageConverterTest.java    | 186 ++++++++++++++-------
 1 file changed, 130 insertions(+), 56 deletions(-)

diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/MIMEMessageConverterTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/MIMEMessageConverterTest.java
index 68f235b..8a8f83b 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/MIMEMessageConverterTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/MIMEMessageConverterTest.java
@@ -19,13 +19,61 @@
 
 package org.apache.james.jmap.draft.methods;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+import java.sql.Date;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+import org.apache.james.core.Username;
+import org.apache.james.jmap.draft.methods.ValueWithId.MessageWithId;
+import org.apache.james.jmap.draft.model.CreationMessage;
+import org.apache.james.jmap.draft.model.CreationMessage.DraftEmailer;
+import org.apache.james.jmap.draft.model.CreationMessageId;
+import org.apache.james.mailbox.AttachmentContentLoader;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MailboxSessionUtil;
+import org.apache.james.mailbox.model.AttachmentId;
+import org.apache.james.mailbox.model.Cid;
+import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mime4j.codec.EncoderUtil;
+import org.apache.james.mime4j.codec.EncoderUtil.Usage;
+import org.apache.james.mime4j.dom.Entity;
+import org.apache.james.mime4j.dom.Message;
+import org.apache.james.mime4j.dom.Multipart;
+import org.apache.james.mime4j.dom.TextBody;
+import org.apache.james.mime4j.dom.address.Mailbox;
+import org.apache.james.mime4j.dom.field.ContentTypeField;
+import org.apache.james.mime4j.message.BasicBodyFactory;
+import org.apache.james.mime4j.stream.Field;
+import org.assertj.core.data.Index;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
 class MIMEMessageConverterTest {
+    MailboxSession session;
+    AttachmentContentLoader attachmentContentLoader;
+
+    @BeforeEach
+    void setUp() {
+        session = MailboxSessionUtil.create(Username.of("bob"));
+        attachmentContentLoader = mock(AttachmentContentLoader.class);
+    }
 
-    /*
     @Test
     void convertToMimeShouldAddInReplyToHeaderWhenProvided() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         String matchingMessageId = "unique-message-id";
         CreationMessage messageHavingInReplyTo = CreationMessage.builder()
@@ -47,7 +95,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldGenerateMessageId() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         CreationMessage message = CreationMessage.builder()
                 .mailboxIds(ImmutableList.of("dead-beef-1337"))
@@ -66,7 +114,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldGenerateMessageIdWhenSenderWithoutDomain() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         CreationMessage message = CreationMessage.builder()
                 .from(DraftEmailer.builder().email("sender").build())
@@ -86,7 +134,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldGenerateMessageIdContainingSenderDomain() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         CreationMessage message = CreationMessage.builder()
                 .from(DraftEmailer.builder().email("email@domain.com").build())
@@ -107,7 +155,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldAddHeaderWhenProvided() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         CreationMessage messageHavingInReplyTo = CreationMessage.builder()
                 .from(DraftEmailer.builder().name("sender").build())
@@ -128,7 +176,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldAddHeadersWhenProvided() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         CreationMessage messageHavingInReplyTo = CreationMessage.builder()
                 .from(DraftEmailer.builder().name("sender").build())
@@ -151,7 +199,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldFilterGeneratedHeadersWhenProvided() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         String joesEmail = "joe@example.com";
         CreationMessage messageHavingInReplyTo = CreationMessage.builder()
@@ -177,7 +225,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldFilterGeneratedHeadersRegardlessOfCaseWhenProvided() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         String joesEmail = "joe@example.com";
         CreationMessage messageHavingInReplyTo = CreationMessage.builder()
@@ -203,7 +251,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldAddMultivaluedHeadersWhenProvided() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         CreationMessage messageHavingInReplyTo = CreationMessage.builder()
                 .from(DraftEmailer.builder().name("sender").build())
@@ -224,7 +272,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldFilterEmptyHeaderNames() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         CreationMessage messageHavingInReplyTo = CreationMessage.builder()
                 .from(DraftEmailer.builder().name("joe").build())
@@ -244,7 +292,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldFilterWhiteSpacesOnlyHeaderNames() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         CreationMessage messageHavingInReplyTo = CreationMessage.builder()
                 .from(DraftEmailer.builder().name("joe").build())
@@ -264,7 +312,7 @@ class MIMEMessageConverterTest {
 
     @Test
     void convertToMimeShouldThrowWhenMessageIsNull() {
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         assertThatThrownBy(() -> sut.convertToMime(
                 new ValueWithId.CreationMessageEntry(CreationMessageId.of("any"), null),
@@ -275,7 +323,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldSetBothFromAndSenderHeaders() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         String joesEmail = "joe@example.com";
         CreationMessage testMessage = CreationMessage.builder()
@@ -296,7 +344,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldSetCorrectLocalDate() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         Instant now = Instant.now();
         ZonedDateTime messageDate = ZonedDateTime.ofInstant(now, ZoneId.systemDefault());
@@ -319,7 +367,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldSetQuotedPrintableContentTransferEncodingWhenText() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         CreationMessage testMessage = CreationMessage.builder()
                 .mailboxId("dead-bada55")
@@ -342,7 +390,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldSetTextBodyWhenProvided() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
         TextBody expected = new BasicBodyFactory().textBody("Hello all!", StandardCharsets.UTF_8);
 
         CreationMessage testMessage = CreationMessage.builder()
@@ -363,7 +411,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldSetEmptyBodyWhenNoBodyProvided() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
         TextBody expected = new BasicBodyFactory().textBody("", StandardCharsets.UTF_8);
 
         CreationMessage testMessage = CreationMessage.builder()
@@ -383,7 +431,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldSetHtmlBodyWhenProvided() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
         TextBody expected = new BasicBodyFactory().textBody("Hello <b>all</b>!", StandardCharsets.UTF_8);
 
         CreationMessage testMessage = CreationMessage.builder()
@@ -404,7 +452,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldGenerateMultipartWhenHtmlBodyAndTextBodyProvided() throws Exception {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         CreationMessage testMessage = CreationMessage.builder()
                 .mailboxId("dead-bada55")
@@ -429,7 +477,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertShouldGenerateExpectedMultipartWhenHtmlAndTextBodyProvided() throws Exception {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         CreationMessage testMessage = CreationMessage.builder()
                 .mailboxId("dead-bada55")
@@ -453,7 +501,7 @@ class MIMEMessageConverterTest {
 
         // When
         byte[] convert = sut.convert(new MessageWithId.CreationMessageEntry(
-                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of());
+                CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(), session);
 
         // Then
         String actual = new String(convert, StandardCharsets.UTF_8);
@@ -465,7 +513,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldSetMimeTypeWhenTextBody() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         CreationMessage testMessage = CreationMessage.builder()
                 .mailboxId("dead-bada55")
@@ -485,7 +533,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldSetMimeTypeWhenHtmlBody() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
         CreationMessage testMessage = CreationMessage.builder()
                 .mailboxId("dead-bada55")
@@ -505,7 +553,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldSetEmptyHtmlBodyWhenProvided() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
         TextBody expected = new BasicBodyFactory().textBody("", StandardCharsets.UTF_8);
 
         CreationMessage testMessage = CreationMessage.builder()
@@ -527,7 +575,7 @@ class MIMEMessageConverterTest {
     @Test
     void convertToMimeShouldSetEmptyTextBodyWhenProvided() {
         // Given
-        MIMEMessageConverter sut = new MIMEMessageConverter();
+        MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
         TextBody expected = new BasicBodyFactory().textBody("", StandardCharsets.UTF_8);
 
         CreationMessage testMessage = CreationMessage.builder()
@@ -550,9 +598,9 @@ class MIMEMessageConverterTest {
     class WithAttachments {
 
         @Test
-        void convertToMimeShouldAddAttachment() {
+        void convertToMimeShouldAddAttachment() throws Exception {
             // Given
-            MIMEMessageConverter sut = new MIMEMessageConverter();
+            MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
             CreationMessage testMessage = CreationMessage.builder()
                 .mailboxId("dead-bada55")
@@ -565,15 +613,18 @@ class MIMEMessageConverterTest {
             String expectedMimeType = "image/png";
             String text = "123456";
             TextBody expectedBody = new BasicBodyFactory().textBody(text.getBytes(), StandardCharsets.UTF_8);
+            AttachmentId blodId = AttachmentId.from("blodId");
             MessageAttachment attachment = MessageAttachment.builder()
                 .attachment(org.apache.james.mailbox.model.Attachment.builder()
-                    .attachmentId(AttachmentId.from("blodId"))
-                    .bytes(text.getBytes())
+                    .attachmentId(blodId)
+                    .size(text.getBytes().length)
                     .type(expectedMimeType)
                     .build())
                 .cid(Cid.from(expectedCID))
                 .isInline(true)
                 .build();
+            when(attachmentContentLoader.load(attachment.getAttachment(), session))
+                .thenReturn(new ByteArrayInputStream(text.getBytes()));
 
             // When
             Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
@@ -594,9 +645,9 @@ class MIMEMessageConverterTest {
         }
 
         @Test
-        void convertToMimeShouldAddAttachmentAndMultipartAlternativeWhenOneAttachementAndTextAndHtmlBody() {
+        void convertToMimeShouldAddAttachmentAndMultipartAlternativeWhenOneAttachementAndTextAndHtmlBody() throws Exception {
             // Given
-            MIMEMessageConverter sut = new MIMEMessageConverter();
+            MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
             CreationMessage testMessage = CreationMessage.builder()
                 .mailboxId("dead-bada55")
@@ -615,12 +666,14 @@ class MIMEMessageConverterTest {
             MessageAttachment attachment = MessageAttachment.builder()
                 .attachment(org.apache.james.mailbox.model.Attachment.builder()
                     .attachmentId(AttachmentId.from("blodId"))
-                    .bytes(text.getBytes())
+                    .size(text.getBytes().length)
                     .type(expectedMimeType)
                     .build())
                 .cid(Cid.from(expectedCID))
                 .isInline(true)
                 .build();
+            when(attachmentContentLoader.load(attachment.getAttachment(), session))
+                .thenReturn(new ByteArrayInputStream(text.getBytes()));
 
             // When
             Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
@@ -652,7 +705,7 @@ class MIMEMessageConverterTest {
         @Test
         void convertShouldEncodeWhenNonASCIICharacters() {
             // Given
-            MIMEMessageConverter sut = new MIMEMessageConverter();
+            MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
             CreationMessage testMessage = CreationMessage.builder()
                     .mailboxId("dead-bada55")
@@ -664,7 +717,7 @@ class MIMEMessageConverterTest {
             // When
             ImmutableList<MessageAttachment> attachments = ImmutableList.of();
             byte[] convert = sut.convert(new ValueWithId.CreationMessageEntry(
-                    CreationMessageId.of("user|mailbox|1"), testMessage), attachments);
+                    CreationMessageId.of("user|mailbox|1"), testMessage), attachments, session);
 
             String expectedEncodedContent = "Some non-ASCII characters: =C3=A1=C3=84=C3=8E=C3=9F=C3=BF";
 
@@ -674,9 +727,9 @@ class MIMEMessageConverterTest {
         }
 
         @Test
-        void convertToMimeShouldAddAttachmentAndContainsIndicationAboutTheWayToEncodeFilenamesAttachmentInTheInputStreamWhenSending() {
+        void convertToMimeShouldAddAttachmentAndContainsIndicationAboutTheWayToEncodeFilenamesAttachmentInTheInputStreamWhenSending() throws Exception {
             // Given
-            MIMEMessageConverter sut = new MIMEMessageConverter();
+            MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
             CreationMessage testMessage = CreationMessage.builder()
                 .mailboxIds(ImmutableList.of("dead-bada55"))
@@ -694,12 +747,15 @@ class MIMEMessageConverterTest {
                 .name(name)
                 .attachment(org.apache.james.mailbox.model.Attachment.builder()
                     .attachmentId(AttachmentId.from("blodId"))
-                    .bytes(text.getBytes())
+                    .size(text.getBytes().length)
                     .type(expectedMimeType)
                     .build())
                 .cid(Cid.from(expectedCID))
                 .isInline(true)
                 .build();
+            when(attachmentContentLoader.load(attachment.getAttachment(), session))
+                .thenReturn(new ByteArrayInputStream(text.getBytes()));
+
 
             // When
             Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
@@ -715,8 +771,8 @@ class MIMEMessageConverterTest {
 
 
         @Test
-        void convertToMimeShouldHaveMixedMultipart() {
-            MIMEMessageConverter sut = new MIMEMessageConverter();
+        void convertToMimeShouldHaveMixedMultipart() throws Exception {
+            MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
             CreationMessage testMessage = CreationMessage.builder()
                 .mailboxIds(ImmutableList.of("dead-bada55"))
@@ -725,16 +781,19 @@ class MIMEMessageConverterTest {
                 .htmlBody("Hello <b>all<b>!")
                 .build();
 
+            String text = "123456";
             MessageAttachment attachment = MessageAttachment.builder()
                 .name("ديناصور.png")
                 .attachment(org.apache.james.mailbox.model.Attachment.builder()
                     .attachmentId(AttachmentId.from("blodId"))
-                    .bytes("123456".getBytes())
+                    .size(text.getBytes().length)
                     .type("image/png")
                     .build())
                 .cid(Cid.from("cid"))
                 .isInline(false)
                 .build();
+            when(attachmentContentLoader.load(attachment.getAttachment(), session))
+                .thenReturn(new ByteArrayInputStream(text.getBytes()));
 
             Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
                 CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment), session);
@@ -745,8 +804,8 @@ class MIMEMessageConverterTest {
         }
 
         @Test
-        void convertToMimeShouldNotHaveInnerMultipartWhenNoInline() {
-            MIMEMessageConverter sut = new MIMEMessageConverter();
+        void convertToMimeShouldNotHaveInnerMultipartWhenNoInline() throws Exception {
+            MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
             CreationMessage testMessage = CreationMessage.builder()
                 .mailboxIds(ImmutableList.of("dead-bada55"))
@@ -755,16 +814,19 @@ class MIMEMessageConverterTest {
                 .htmlBody("Hello <b>all<b>!")
                 .build();
 
+            String text = "123456";
             MessageAttachment attachment = MessageAttachment.builder()
                 .name("ديناصور.png")
                 .attachment(org.apache.james.mailbox.model.Attachment.builder()
                     .attachmentId(AttachmentId.from("blodId"))
-                    .bytes("123456".getBytes())
+                    .size(text.getBytes().length)
                     .type("image/png")
                     .build())
                 .cid(Cid.from("cid"))
                 .isInline(false)
                 .build();
+            when(attachmentContentLoader.load(attachment.getAttachment(), session))
+                .thenReturn(new ByteArrayInputStream(text.getBytes()));
 
             Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
                 CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment), session);
@@ -775,8 +837,8 @@ class MIMEMessageConverterTest {
         }
 
         @Test
-        void convertToMimeShouldHaveChildrenAttachmentParts() {
-            MIMEMessageConverter sut = new MIMEMessageConverter();
+        void convertToMimeShouldHaveChildrenAttachmentParts() throws Exception {
+            MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
             CreationMessage testMessage = CreationMessage.builder()
                 .mailboxIds(ImmutableList.of("dead-bada55"))
@@ -785,16 +847,19 @@ class MIMEMessageConverterTest {
                 .htmlBody("Hello <b>all<b>!")
                 .build();
 
+            String text = "123456";
             MessageAttachment attachment = MessageAttachment.builder()
                 .name("ديناصور.png")
                 .attachment(org.apache.james.mailbox.model.Attachment.builder()
                     .attachmentId(AttachmentId.from("blodId"))
-                    .bytes("123456".getBytes())
+                    .size(text.getBytes().length)
                     .type("image/png")
                     .build())
                 .cid(Cid.from("cid"))
                 .isInline(false)
                 .build();
+            when(attachmentContentLoader.load(attachment.getAttachment(), session))
+                .thenReturn(new ByteArrayInputStream(text.getBytes()));
 
             Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
                 CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment), session);
@@ -806,8 +871,8 @@ class MIMEMessageConverterTest {
         }
 
         @Test
-        void convertToMimeShouldHaveChildMultipartWhenOnlyInline() {
-            MIMEMessageConverter sut = new MIMEMessageConverter();
+        void convertToMimeShouldHaveChildMultipartWhenOnlyInline() throws Exception {
+            MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
             CreationMessage testMessage = CreationMessage.builder()
                 .mailboxIds(ImmutableList.of("dead-bada55"))
@@ -817,16 +882,19 @@ class MIMEMessageConverterTest {
                 .build();
 
             String name = "ديناصور.png";
+            String text = "123456";
             MessageAttachment attachment = MessageAttachment.builder()
                 .name(name)
                 .attachment(org.apache.james.mailbox.model.Attachment.builder()
                     .attachmentId(AttachmentId.from("blodId"))
-                    .bytes("123456".getBytes())
+                    .size(text.getBytes().length)
                     .type("image/png")
                     .build())
                 .cid(Cid.from("cid"))
                 .isInline(true)
                 .build();
+            when(attachmentContentLoader.load(attachment.getAttachment(), session))
+                .thenReturn(new ByteArrayInputStream(text.getBytes()));
 
             Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
                     CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment), session);
@@ -841,8 +909,8 @@ class MIMEMessageConverterTest {
         }
 
         @Test
-        void convertToMimeShouldHaveChildMultipartWhenBothInlinesAndAttachments() {
-            MIMEMessageConverter sut = new MIMEMessageConverter();
+        void convertToMimeShouldHaveChildMultipartWhenBothInlinesAndAttachments() throws Exception {
+            MIMEMessageConverter sut = new MIMEMessageConverter(attachmentContentLoader);
 
             CreationMessage testMessage = CreationMessage.builder()
                 .mailboxIds(ImmutableList.of("dead-bada55"))
@@ -851,27 +919,35 @@ class MIMEMessageConverterTest {
                 .htmlBody("Hello <b>all<b>!")
                 .build();
 
+            String text = "inline data";
             MessageAttachment inline = MessageAttachment.builder()
                 .name("ديناصور.png")
                 .attachment(org.apache.james.mailbox.model.Attachment.builder()
                     .attachmentId(AttachmentId.from("blodId"))
-                    .bytes("inline data".getBytes())
+                    .size(text.getBytes().length)
                     .type("image/png")
                     .build())
                 .cid(Cid.from("cid"))
                 .isInline(true)
                 .build();
+            when(attachmentContentLoader.load(inline.getAttachment(), session))
+                .thenReturn(new ByteArrayInputStream(text.getBytes()));
 
+
+            String text2 = "attachment data";
             MessageAttachment attachment = MessageAttachment.builder()
                 .name("att.pdf")
                 .attachment(org.apache.james.mailbox.model.Attachment.builder()
                     .attachmentId(AttachmentId.from("blodId2"))
-                    .bytes("attachment data".getBytes())
+                    .size(text2.getBytes().length)
                     .type("image/png")
                     .build())
                 .cid(Cid.from("cid2"))
                 .isInline(false)
                 .build();
+            when(attachmentContentLoader.load(attachment.getAttachment(), session))
+                .thenReturn(new ByteArrayInputStream(text2.getBytes()));
+
 
             Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry(
                     CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(inline, attachment), session);
@@ -895,6 +971,4 @@ class MIMEMessageConverterTest {
             return ((ContentTypeField) attachmentPart.getHeader().getField("Content-Type")).getParameter("name");
         }
     }
-
-     */
 }


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


[james-project] 37/37: JAMES-3151 HasMimeType matchers fails on empty charset

Posted by bt...@apache.org.
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 8f0c332216a06cee2154d14336333f9c6058996e
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Apr 20 12:41:17 2020 +0700

    JAMES-3151 HasMimeType matchers fails on empty charset
---
 .../james/transport/matchers/HasMimeType.java      | 32 ++++++++++----------
 .../james/transport/matchers/HasMimeTypeTest.java  | 35 ++++++++++++++++++----
 2 files changed, 46 insertions(+), 21 deletions(-)

diff --git a/mailet/standard/src/main/java/org/apache/james/transport/matchers/HasMimeType.java b/mailet/standard/src/main/java/org/apache/james/transport/matchers/HasMimeType.java
index 1dc2ecf..2dcbc7e 100644
--- a/mailet/standard/src/main/java/org/apache/james/transport/matchers/HasMimeType.java
+++ b/mailet/standard/src/main/java/org/apache/james/transport/matchers/HasMimeType.java
@@ -20,16 +20,15 @@
 
 package org.apache.james.transport.matchers;
 
+import static org.apache.mailet.base.RFC2822Headers.CONTENT_TYPE;
+
 import java.util.Collection;
-import java.util.Optional;
 import java.util.Set;
-
-import javax.activation.MimeType;
-import javax.activation.MimeTypeParseException;
-import javax.mail.MessagingException;
-import javax.mail.internet.MimeMessage;
+import java.util.stream.Stream;
 
 import org.apache.james.core.MailAddress;
+import org.apache.james.mime4j.field.Fields;
+import org.apache.james.util.StreamUtils;
 import org.apache.mailet.Mail;
 import org.apache.mailet.base.GenericMatcher;
 import org.slf4j.Logger;
@@ -58,19 +57,20 @@ public class HasMimeType extends GenericMatcher {
 
     @Override
     public Collection<MailAddress> match(Mail mail) throws javax.mail.MessagingException {
-        Optional<String> mimeTypes = getMimeTypeFromMessage(mail.getMessage());
-
-        return mimeTypes.filter(acceptedContentTypes::contains)
-                .map(any -> mail.getRecipients())
-                .orElse(ImmutableList.of());
+        return StreamUtils.ofNullable(mail.getMessage().getHeader(CONTENT_TYPE))
+            .flatMap(this::getMimeType)
+            .filter(acceptedContentTypes::contains)
+            .findAny()
+            .map(any -> mail.getRecipients())
+            .orElse(ImmutableList.of());
     }
 
-    private static Optional<String> getMimeTypeFromMessage(MimeMessage message) throws MessagingException {
+    private Stream<String> getMimeType(String rawValue) {
         try {
-            return Optional.of(new MimeType(message.getContentType()).getBaseType());
-        } catch (MimeTypeParseException e) {
-            LOGGER.warn("Error while parsing message's mimeType {}", message.getContentType(), e);
-            return Optional.empty();
+            return Stream.of(Fields.contentType(rawValue).getMimeType());
+        } catch (Exception e) {
+            LOGGER.warn("Error while parsing message's mimeType {}", rawValue, e);
+            return Stream.empty();
         }
     }
 
diff --git a/mailet/standard/src/test/java/org/apache/james/transport/matchers/HasMimeTypeTest.java b/mailet/standard/src/test/java/org/apache/james/transport/matchers/HasMimeTypeTest.java
index 46399b4..6ff4620 100644
--- a/mailet/standard/src/test/java/org/apache/james/transport/matchers/HasMimeTypeTest.java
+++ b/mailet/standard/src/test/java/org/apache/james/transport/matchers/HasMimeTypeTest.java
@@ -19,7 +19,12 @@
 
 package org.apache.james.transport.matchers;
 
+import static org.apache.mailet.base.RFC2822Headers.CONTENT_TYPE;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import javax.mail.internet.MimeMessage;
 
 import org.apache.james.core.builder.MimeMessageBuilder;
 import org.apache.mailet.Mail;
@@ -28,7 +33,7 @@ import org.apache.mailet.base.test.FakeMatcherConfig;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
-public class HasMimeTypeTest {
+class HasMimeTypeTest {
 
     private static final String RECIPIENT = "test@james.apache.org";
     private static final String FROM = "test@james.apache.org";
@@ -38,12 +43,12 @@ public class HasMimeTypeTest {
     private HasMimeType matcher;
 
     @BeforeEach
-    public void setUp() throws Exception {
+    void setUp() throws Exception {
         matcher = new HasMimeType();
     }
 
     @Test
-    public void hasMimeType() throws Exception {
+    void hasMimeType() throws Exception {
         matcher.init(FakeMatcherConfig.builder()
                 .matcherName("HasMimeType")
                 .condition(MIME_TYPES)
@@ -74,7 +79,7 @@ public class HasMimeTypeTest {
     }
 
     @Test
-    public void doesNotHaveMimeType() throws Exception {
+    void doesNotHaveMimeType() throws Exception {
         matcher.init(FakeMatcherConfig.builder()
                 .matcherName("HasMimeType")
                 .condition(NON_MATCHING_MIME_TYPES)
@@ -105,7 +110,7 @@ public class HasMimeTypeTest {
     }
 
     @Test
-    public void matchShouldReturnRecipientsWhenAtLeastOneMimeTypeMatch() throws Exception {
+    void matchShouldReturnRecipientsWhenAtLeastOneMimeTypeMatch() throws Exception {
         matcher.init(FakeMatcherConfig.builder()
             .matcherName("HasMimeType")
             .condition("text/md, text/html")
@@ -124,4 +129,24 @@ public class HasMimeTypeTest {
 
         assertThat(matcher.match(mail)).containsExactlyElementsOf(mail.getRecipients());
     }
+
+    @Test
+    void matchShouldNotFailOnEmptyCharset() throws Exception {
+        matcher.init(FakeMatcherConfig.builder()
+            .matcherName("HasMimeType")
+            .condition("text/html")
+            .build());
+
+        MimeMessage message = mock(MimeMessage.class);
+        when(message.getHeader(CONTENT_TYPE)).thenReturn(new String[] {"text/html; charset="});
+
+        Mail mail = FakeMail.builder()
+            .name("mail")
+            .mimeMessage(message)
+            .sender(FROM)
+            .recipient(RECIPIENT)
+            .build();
+
+        assertThat(matcher.match(mail)).containsExactlyElementsOf(mail.getRecipients());
+    }
 }


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


[james-project] 12/37: JAMES-2997 step #10 Mailbox backend is responsible of creating messageAttachments

Posted by bt...@apache.org.
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 935e1f5750841148ded392b9057917df5588926c
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Jan 17 15:22:37 2020 +0700

    JAMES-2997 step #10 Mailbox backend is responsible of creating messageAttachments
    
    We should avoid to compute them in parallel in JMAP and rather rely on
    mailboxManager append result, which can be enriched to convey attachments.
---
 .../listeners/SetCustomFlagOnBigMessagesTest.java  | 12 ++---
 .../org/apache/james/mailbox/MessageManager.java   | 40 +++++++++++++-
 .../mailbox/MailboxManagerStressContract.java      |  2 +-
 .../apache/james/mailbox/MailboxManagerTest.java   | 52 ++++++++++--------
 .../mailbox/manager/ManagerTestProvisionner.java   |  4 +-
 .../ElasticSearchIntegrationTest.java              | 16 +++---
 .../search/ElasticSearchSearcherTest.java          |  3 +-
 .../james/vault/DeletedMessageVaultHookTest.java   |  3 +-
 .../james/mailbox/store/StoreMessageManager.java   | 20 ++++---
 .../store/AbstractCombinationManagerTest.java      | 62 +++++++++++-----------
 .../store/AbstractMessageIdManagerStorageTest.java |  1 +
 .../search/AbstractMessageSearchIndexTest.java     | 52 +++++++++---------
 .../tools/indexer/MessageIdReIndexerImplTest.java  |  2 +-
 .../mailbox/tools/indexer/ReIndexerImplTest.java   | 12 ++---
 .../james/imap/processor/AppendProcessor.java      |  3 +-
 .../org/apache/james/modules/MailboxProbeImpl.java |  4 +-
 .../mailets/delivery/MailboxAppender.java          |  8 +--
 .../mailets/delivery/LocalDeliveryTest.java        |  8 ++-
 .../james/jmap/draft/methods/MessageAppender.java  | 38 ++++++-------
 .../james/jmap/draft/methods/SendMDNProcessor.java | 24 +--------
 .../org/apache/james/jmap/draft/model/JmapMDN.java |  3 +-
 .../MessageFastViewProjectionItemFactoryTest.java  |  2 +-
 .../jmap/draft/methods/GetMessagesMethodTest.java  | 52 +++++++++---------
 .../methods/SetMessagesUpdateProcessorTest.java    |  4 +-
 .../message/view/MessageFastViewFactoryTest.java   |  8 +--
 .../message/view/MessageFullViewFactoryTest.java   |  2 +-
 .../message/view/MessageHeaderViewFactoryTest.java |  2 +-
 .../view/MessageMetadataViewFactoryTest.java       |  2 +-
 .../jmap/draft/send/PostDequeueDecoratorTest.java  | 16 +++---
 ...mputeMessageFastViewProjectionListenerTest.java | 12 ++---
 ...llFastViewProjectionItemsRequestToTaskTest.java |  4 +-
 ...erFastViewProjectionItemsRequestToTaskTest.java |  4 +-
 .../webadmin/vault/routes/RestoreService.java      |  2 +-
 .../james/webadmin/routes/MailboxesRoutesTest.java | 16 +++---
 .../james/webadmin/routes/MessageRoutesTest.java   |  4 +-
 .../webadmin/routes/UserMailboxesRoutesTest.java   |  4 +-
 .../james/webadmin/service/ExportServiceTest.java  |  3 +-
 .../service/MailboxesExportRequestToTaskTest.java  |  4 +-
 38 files changed, 273 insertions(+), 237 deletions(-)

diff --git a/examples/custom-listeners/src/test/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessagesTest.java b/examples/custom-listeners/src/test/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessagesTest.java
index e3340d5..d198a94 100644
--- a/examples/custom-listeners/src/test/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessagesTest.java
+++ b/examples/custom-listeners/src/test/java/org/apache/james/examples/custom/listeners/SetCustomFlagOnBigMessagesTest.java
@@ -81,7 +81,7 @@ class SetCustomFlagOnBigMessagesTest {
         ComposedMessageId composedId = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(smallMessage()),
-            mailboxSession);
+            mailboxSession).getIds();
 
         assertThat(getMessageFlags(composedId.getUid()))
             .allSatisfy(flags -> assertThat(flags.contains(BIG_MESSAGE)).isFalse());
@@ -97,7 +97,7 @@ class SetCustomFlagOnBigMessagesTest {
             MessageManager.AppendCommand.builder()
                 .withFlags(appendMessageFlag)
                 .build(smallMessage()),
-            mailboxSession);
+            mailboxSession).getIds();
 
         assertThat(getMessageFlags(composedId.getUid()))
             .allSatisfy(flags -> {
@@ -111,7 +111,7 @@ class SetCustomFlagOnBigMessagesTest {
         ComposedMessageId composedId = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(bigMessage()),
-            mailboxSession);
+            mailboxSession).getIds();
 
         assertThat(getMessageFlags(composedId.getUid()))
             .allSatisfy(flags -> assertThat(flags.contains(BIG_MESSAGE)).isTrue());
@@ -122,7 +122,7 @@ class SetCustomFlagOnBigMessagesTest {
         ComposedMessageId composedIdOfSmallMessage = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(smallMessage()),
-            mailboxSession);
+            mailboxSession).getIds();
 
         MessageResult addedMessage = inboxMessageManager
             .getMessages(MessageRange.one(composedIdOfSmallMessage.getUid()), FetchGroup.MINIMAL, mailboxSession)
@@ -154,7 +154,7 @@ class SetCustomFlagOnBigMessagesTest {
             MessageManager.AppendCommand.builder()
                 .withFlags(appendMessageFlag)
                 .build(bigMessage()),
-            mailboxSession);
+            mailboxSession).getIds();
 
         assertThat(getMessageFlags(composedId.getUid()))
             .allSatisfy(flags -> {
@@ -173,7 +173,7 @@ class SetCustomFlagOnBigMessagesTest {
             MessageManager.AppendCommand.builder()
                 .withFlags(appendMessageFlag)
                 .build(bigMessage()),
-            mailboxSession);
+            mailboxSession).getIds();
 
         assertThat(getMessageFlags(composedId.getUid()))
             .allSatisfy(flags -> assertThat(flags.contains(BIG_MESSAGE)).isTrue());
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java
index 52c0f6e..2c67375 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/MessageManager.java
@@ -28,6 +28,7 @@ import java.util.EnumSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Stream;
 
@@ -44,6 +45,7 @@ import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxCounters;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.MessageResult;
 import org.apache.james.mailbox.model.MessageResultIterator;
@@ -138,6 +140,40 @@ public interface MessageManager {
      */
     Map<MessageUid, Flags> setFlags(Flags flags, FlagsUpdateMode flagsUpdateMode, MessageRange set, MailboxSession mailboxSession) throws MailboxException;
 
+    class AppendResult {
+        private final ComposedMessageId ids;
+        private final List<MessageAttachment> messageAttachments;
+
+        public AppendResult(ComposedMessageId ids, List<MessageAttachment> messageAttachments) {
+            this.ids = ids;
+            this.messageAttachments = messageAttachments;
+        }
+
+        public ComposedMessageId getIds() {
+            return ids;
+        }
+
+        public List<MessageAttachment> getMessageAttachments() {
+            return messageAttachments;
+        }
+
+        @Override
+        public final boolean equals(Object o) {
+            if (o instanceof AppendResult) {
+                AppendResult that = (AppendResult) o;
+
+                return Objects.equals(this.ids, that.ids)
+                    && Objects.equals(this.messageAttachments, that.messageAttachments);
+            }
+            return false;
+        }
+
+        @Override
+        public final int hashCode() {
+            return Objects.hash(ids, messageAttachments);
+        }
+    }
+
     /**
      * Appends a message to this mailbox. This method must return a higher UID
      * as the last call in every case which also needs to be unique for the
@@ -157,7 +193,7 @@ public interface MessageManager {
      * @throws MailboxException
      *             when message cannot be appended
      */
-    ComposedMessageId appendMessage(InputStream msgIn, Date internalDate, MailboxSession mailboxSession, boolean isRecent, Flags flags) throws MailboxException;
+    AppendResult appendMessage(InputStream msgIn, Date internalDate, MailboxSession mailboxSession, boolean isRecent, Flags flags) throws MailboxException;
 
     class AppendCommand {
 
@@ -265,7 +301,7 @@ public interface MessageManager {
         }
     }
 
-    ComposedMessageId appendMessage(AppendCommand appendCommand, MailboxSession session) throws MailboxException;
+    AppendResult appendMessage(AppendCommand appendCommand, MailboxSession session) throws MailboxException;
 
     /**
      * Gets messages in the given range. The messages may get fetched under
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java
index 3bf6d8f..4821757 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerStressContract.java
@@ -93,7 +93,7 @@ public interface MailboxManagerStressContract<T extends MailboxManager> {
                         MessageManager.AppendCommand
                             .from(Message.Builder.of()
                                 .setSubject("test")
-                                .setBody("testmail", StandardCharsets.UTF_8)), mailboxSession);
+                                .setBody("testmail", StandardCharsets.UTF_8)), mailboxSession).getIds();
 
                     System.out.println("Append message with uid=" + messageId.getUid());
                     if (uids.put(messageId.getUid(), new Object()) != null) {
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 f51c124..7382127 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
@@ -824,7 +824,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
 
         @Test
         void deleteMessageShouldFireExpungedEvent() throws Exception {
-            ComposedMessageId messageId = inboxManager.appendMessage(MessageManager.AppendCommand.builder().build(message), session);
+            ComposedMessageId messageId = inboxManager.appendMessage(MessageManager.AppendCommand.builder().build(message), session).getIds();
             inboxManager.setFlags(new Flags(Flags.Flag.DELETED), MessageManager.FlagsUpdateMode.ADD, MessageRange.all(), session);
 
             retrieveEventBus(mailboxManager).register(listener, new MailboxIdRegistrationKey(inboxId));
@@ -913,7 +913,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             assumeTrue(mailboxManager.getSupportedMessageCapabilities().contains(MailboxManager.MessageCapabilities.UniqueID));
 
             Optional<MailboxId> targetMailboxId = mailboxManager.createMailbox(newPath, session);
-            ComposedMessageId messageId = inboxManager.appendMessage(AppendCommand.builder().build(message), session);
+            ComposedMessageId messageId = inboxManager.appendMessage(AppendCommand.builder().build(message), session).getIds();
 
             retrieveEventBus(mailboxManager).register(listener, new MailboxIdRegistrationKey(targetMailboxId.get()));
             mailboxManager.copyMessages(MessageRange.all(), inbox, newPath, session);
@@ -946,7 +946,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             assumeTrue(mailboxManager.getSupportedMessageCapabilities().contains(MailboxManager.MessageCapabilities.UniqueID));
 
             Optional<MailboxId> targetMailboxId = mailboxManager.createMailbox(newPath, session);
-            ComposedMessageId messageId = inboxManager.appendMessage(AppendCommand.builder().build(message), session);
+            ComposedMessageId messageId = inboxManager.appendMessage(AppendCommand.builder().build(message), session).getIds();
 
             retrieveEventBus(mailboxManager).register(listener, new MailboxIdRegistrationKey(targetMailboxId.get()));
             mailboxManager.moveMessages(MessageRange.all(), inbox, newPath, session);
@@ -964,7 +964,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             assumeTrue(mailboxManager.getSupportedMessageCapabilities().contains(MailboxManager.MessageCapabilities.UniqueID));
 
             mailboxManager.createMailbox(newPath, session);
-            ComposedMessageId messageId = inboxManager.appendMessage(AppendCommand.builder().build(message), session);
+            ComposedMessageId messageId = inboxManager.appendMessage(AppendCommand.builder().build(message), session).getIds();
 
             retrieveEventBus(mailboxManager).register(listener, new MailboxIdRegistrationKey(inboxId));
             mailboxManager.moveMessages(MessageRange.all(), inbox, newPath, session);
@@ -1194,7 +1194,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             MessageManager cacahueteMessageManager = mailboxManager.getMailbox(cacahueteMailboxId, session);
             MessageId cacahueteMessageId = cacahueteMessageManager
                 .appendMessage(AppendCommand.from(message), session)
-                .getMessageId();
+                .getIds().getMessageId();
 
             MailboxPath pirouetteFilder = MailboxPath.forUser(USER_1, "PIROUETTE");
             MailboxId pirouetteMailboxId = mailboxManager.createMailbox(pirouetteFilder, session).get();
@@ -1202,7 +1202,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
 
             MessageId pirouetteMessageId = pirouetteMessageManager
                 .appendMessage(AppendCommand.from(message), session)
-                .getMessageId();
+                .getIds().getMessageId();
 
             MultimailboxesSearchQuery multiMailboxesQuery = MultimailboxesSearchQuery
                 .from(new SearchQuery())
@@ -1226,7 +1226,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
 
             MessageId messageId = delegatedMessageManager
                 .appendMessage(AppendCommand.from(message), sessionFromDelegater)
-                .getMessageId();
+                .getIds().getMessageId();
 
             mailboxManager.setRights(delegatedMailboxPath,
                 MailboxACL.EMPTY.apply(MailboxACL.command()
@@ -1376,7 +1376,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
 
             MessageId messageId = searchedMessageManager
                 .appendMessage(AppendCommand.from(message), session)
-                .getMessageId();
+                .getIds().getMessageId();
 
             MultimailboxesSearchQuery multiMailboxesQuery = MultimailboxesSearchQuery
                 .from(new SearchQuery())
@@ -1842,9 +1842,11 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
 
             MessageId messageId1 = inboxMessageManager
                 .appendMessage(AppendCommand.from(message), session)
+                .getIds()
                 .getMessageId();
             MessageId messageId2 = inboxMessageManager
                 .appendMessage(AppendCommand.from(message), session)
+                .getIds()
                 .getMessageId();
 
             mailboxManager.moveMessages(MessageRange.all(), inbox, otherMailbox, session);
@@ -1883,9 +1885,11 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             MessageManager inboxMessageManager = mailboxManager.getMailbox(inbox, session);
 
             ComposedMessageId composedMessageId1 = inboxMessageManager
-                .appendMessage(AppendCommand.from(message), session);
+                .appendMessage(AppendCommand.from(message), session)
+                .getIds();
             MessageId messageId2 = inboxMessageManager
                 .appendMessage(AppendCommand.from(message), session)
+                .getIds()
                 .getMessageId();
 
             mailboxManager.moveMessages(MessageRange.one(composedMessageId1.getUid()), inbox, otherMailbox, session);
@@ -1975,9 +1979,11 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
 
             MessageId messageId1 = inboxMessageManager
                 .appendMessage(AppendCommand.from(message), session)
+                .getIds()
                 .getMessageId();
             MessageId messageId2 = inboxMessageManager
                 .appendMessage(AppendCommand.from(message), session)
+                .getIds()
                 .getMessageId();
 
             mailboxManager.copyMessages(MessageRange.all(), inbox, otherMailbox, session);
@@ -2015,9 +2021,11 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             MessageManager inboxMessageManager = mailboxManager.getMailbox(inbox, session);
 
             ComposedMessageId composedMessageId1 = inboxMessageManager
-                .appendMessage(AppendCommand.from(message), session);
+                .appendMessage(AppendCommand.from(message), session)
+                .getIds();
             MessageId messageId2 = inboxMessageManager
                 .appendMessage(AppendCommand.from(message), session)
+                .getIds()
                 .getMessageId();
 
             MessageId messageId1 = composedMessageId1.getMessageId();
@@ -2205,7 +2213,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             void expungeShouldCallAllPreDeletionHooks() throws Exception {
                 ComposedMessageId composeId = inboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session);
+                    .build(message), session).getIds();
                 inboxManager.expunge(MessageRange.one(composeId.getUid()), session);
 
                 ArgumentCaptor<PreDeletionHook.DeleteOperation> preDeleteCaptor1 = ArgumentCaptor.forClass(PreDeletionHook.DeleteOperation.class);
@@ -2226,7 +2234,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             void deleteMailboxShouldCallAllPreDeletionHooks() throws Exception {
                 ComposedMessageId composeId = inboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session);
+                    .build(message), session).getIds();
                 mailboxManager.deleteMailbox(inbox, session);
 
                 ArgumentCaptor<PreDeletionHook.DeleteOperation> preDeleteCaptor1 = ArgumentCaptor.forClass(PreDeletionHook.DeleteOperation.class);
@@ -2247,7 +2255,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             void deleteMailboxByIdShouldCallAllPreDeletionHooks() throws Exception {
                 ComposedMessageId composeId = inboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session);
+                    .build(message), session).getIds();
                 mailboxManager.deleteMailbox(inboxId, session);
 
                 ArgumentCaptor<PreDeletionHook.DeleteOperation> preDeleteCaptor1 = ArgumentCaptor.forClass(PreDeletionHook.DeleteOperation.class);
@@ -2268,10 +2276,10 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             void expungeShouldCallAllPreDeletionHooksOnEachMessageDeletionCall() throws Exception {
                 ComposedMessageId composeId1 = inboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session);
+                    .build(message), session).getIds();
                 ComposedMessageId composeId2 = inboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session);
+                    .build(message), session).getIds();
 
                 inboxManager.expunge(MessageRange.one(composeId1.getUid()), session);
                 inboxManager.expunge(MessageRange.one(composeId2.getUid()), session);
@@ -2294,7 +2302,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             void expungeShouldCallAllPreDeletionHooksOnlyOnMessagesMarkedAsDeleted() throws Exception {
                 ComposedMessageId composeId1 = inboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session);
+                    .build(message), session).getIds();
                 inboxManager.appendMessage(AppendCommand.builder()
                     .build(message), session);
 
@@ -2329,10 +2337,10 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
             void expungeShouldCallAllPreDeletionHooksOnEachMessageDeletionOnDifferentMailboxes() throws Exception {
                 ComposedMessageId composeId1 = inboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session);
+                    .build(message), session).getIds();
                 ComposedMessageId composeId2 = anotherMailboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session);
+                    .build(message), session).getIds();
 
                 inboxManager.expunge(MessageRange.one(composeId1.getUid()), session);
                 anotherMailboxManager.expunge(MessageRange.one(composeId2.getUid()), session);
@@ -2362,7 +2370,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
 
                 ComposedMessageId composeId1 = inboxManager.appendMessage(AppendCommand.builder()
                     .withFlags(new Flags(Flags.Flag.DELETED))
-                    .build(message), session);
+                    .build(message), session).getIds();
                 assertThatThrownBy(() -> inboxManager.expunge(MessageRange.one(composeId1.getUid()), session))
                     .isInstanceOf(RuntimeException.class);
 
@@ -2389,7 +2397,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
                         return Mono.empty();
                     });
 
-                ComposedMessageId composeId1 = inboxManager.appendMessage(AppendCommand.builder().build(message), session);
+                ComposedMessageId composeId1 = inboxManager.appendMessage(AppendCommand.builder().build(message), session).getIds();
                 inboxManager.setFlags(new Flags(Flags.Flag.DELETED), MessageManager.FlagsUpdateMode.ADD,
                     MessageRange.one(composeId1.getUid()), session);
                 inboxManager.expunge(MessageRange.all(), session);
@@ -2420,7 +2428,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
         void getMessagesShouldIncludeHasAttachmentInformation() throws Exception {
             ComposedMessageId composeId = inboxManager.appendMessage(AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.DELETED))
-                .build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/twoAttachmentsApi.eml")), session);
+                .build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/twoAttachmentsApi.eml")), session).getIds();
 
             MessageResultIterator messages = inboxManager.getMessages(MessageRange.one(composeId.getUid()), FetchGroup.MINIMAL, session);
 
@@ -2434,7 +2442,7 @@ public abstract class MailboxManagerTest<T extends MailboxManager> {
         void getMessagesShouldNotIncludeAttachmentInformationWhenNone() throws Exception {
             ComposedMessageId composeId = inboxManager.appendMessage(AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.DELETED))
-                .build(message), session);
+                .build(message), session).getIds();
 
             MessageResultIterator messages = inboxManager.getMessages(MessageRange.one(composeId.getUid()), FetchGroup.MINIMAL, session);
 
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/manager/ManagerTestProvisionner.java b/mailbox/api/src/test/java/org/apache/james/mailbox/manager/ManagerTestProvisionner.java
index 555cdb7..309d48b 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/manager/ManagerTestProvisionner.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/manager/ManagerTestProvisionner.java
@@ -99,7 +99,9 @@ public class ManagerTestProvisionner {
 
     public MessageUid appendMessage(MessageManager messageManager, MailboxSession session, Flags flags) throws MailboxException, UnsupportedEncodingException {
         return messageManager.appendMessage(new ByteArrayInputStream(MockMail.MAIL_TEXT_PLAIN.getBytes(StandardCharsets.UTF_8)),
-            Calendar.getInstance().getTime(), session, true, flags).getUid();
+            Calendar.getInstance().getTime(), session, true, flags)
+            .getIds()
+            .getUid();
     }
 
 }
\ No newline at end of file
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
index 1813ef3..51983b3 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
@@ -131,7 +131,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
             Message.Builder.of()
                 .setTo(recipient)
                 .setBody(Strings.repeat("0à2345678é", 3200), StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
 
         elasticSearch.awaitForElasticSearch();
 
@@ -150,7 +150,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
             Message.Builder.of()
                 .setTo(recipient)
                 .setBody(Strings.repeat("0123456789", 3300), StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
 
         elasticSearch.awaitForElasticSearch();
 
@@ -169,7 +169,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
             Message.Builder.of()
                 .setTo(recipient)
                 .setBody(Strings.repeat("0123456789 ", 5000), StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
 
         elasticSearch.awaitForElasticSearch();
 
@@ -188,7 +188,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
             Message.Builder.of()
                 .setTo(recipient)
                 .setBody(Strings.repeat("0123456789 ", 5000) + " matchMe", StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
 
         elasticSearch.awaitForElasticSearch();
 
@@ -208,7 +208,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
             Message.Builder.of()
                 .setTo(recipient)
                 .setBody(reasonableLongTerm, StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
 
         elasticSearch.awaitForElasticSearch();
 
@@ -225,14 +225,14 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
         ComposedMessageId customDateHeaderMessageId = messageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(ClassLoader.getSystemResourceAsStream("eml/mailCustomDateHeader.eml")),
-            session);
+            session).getIds();
 
         elasticSearch.awaitForElasticSearch();
 
         ComposedMessageId customStringHeaderMessageId = messageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(ClassLoader.getSystemResourceAsStream("eml/mailCustomStringHeader.eml")),
-            session);
+            session).getIds();
 
         elasticSearch.awaitForElasticSearch();
 
@@ -256,7 +256,7 @@ class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest {
         ComposedMessageId customStringHeaderMessageId = messageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(ClassLoader.getSystemResourceAsStream("eml/mailCustomStringHeader.eml")),
-            session);
+            session).getIds();
 
         elasticSearch.awaitForElasticSearch();
 
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcherTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcherTest.java
index fcaa97b..444628f 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcherTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcherTest.java
@@ -167,6 +167,7 @@ class ElasticSearchSearcherTest {
             Message.Builder.of()
                 .setTo(recipient)
                 .setBody("Hello", StandardCharsets.UTF_8)),
-            session);
+            session)
+            .getIds();
     }
 }
\ No newline at end of file
diff --git a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultHookTest.java b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultHookTest.java
index 8c5cfc8..4f0bfc5 100644
--- a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultHookTest.java
+++ b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageVaultHookTest.java
@@ -102,7 +102,8 @@ class DeletedMessageVaultHookTest {
     private ComposedMessageId appendMessage(MessageManager messageManager) throws Exception {
         return messageManager.appendMessage(MessageManager.AppendCommand.builder()
                 .withInternalDate(INTERNAL_DATE)
-                .build(mailContent), aliceSession);
+                .build(mailContent), aliceSession)
+            .getIds();
     }
 
     @BeforeEach
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
index 9f2557b..1cb207e 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
@@ -44,6 +44,7 @@ import javax.mail.internet.SharedInputStream;
 import javax.mail.util.SharedFileInputStream;
 
 import org.apache.commons.io.input.TeeInputStream;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxManager.MessageCapabilities;
 import org.apache.james.mailbox.MailboxPathLocker;
@@ -301,7 +302,7 @@ public class StoreMessageManager implements MessageManager {
     }
 
     @Override
-    public ComposedMessageId appendMessage(AppendCommand appendCommand, MailboxSession session) throws MailboxException {
+    public AppendResult appendMessage(AppendCommand appendCommand, MailboxSession session) throws MailboxException {
         return appendMessage(
             appendCommand.getMsgIn(),
             appendCommand.getInternalDate(),
@@ -311,7 +312,7 @@ public class StoreMessageManager implements MessageManager {
     }
 
     @Override
-    public ComposedMessageId appendMessage(InputStream msgIn, Date internalDate, final MailboxSession mailboxSession, boolean isRecent, Flags flagsToBeSet) throws MailboxException {
+    public AppendResult appendMessage(InputStream msgIn, Date internalDate, final MailboxSession mailboxSession, boolean isRecent, Flags flagsToBeSet) throws MailboxException {
         File file = null;
 
         if (!isWriteable(mailboxSession)) {
@@ -443,13 +444,13 @@ public class StoreMessageManager implements MessageManager {
         return bodyStartOctet;
     }
 
-    private ComposedMessageId createAndDispatchMessage(Date internalDate, MailboxSession mailboxSession, File file, PropertyBuilder propertyBuilder, Flags flags, int bodyStartOctet) throws IOException, MailboxException {
+    private AppendResult createAndDispatchMessage(Date internalDate, MailboxSession mailboxSession, File file, PropertyBuilder propertyBuilder, Flags flags, int bodyStartOctet) throws IOException, MailboxException {
         try (SharedFileInputStream contentIn = new SharedFileInputStream(file)) {
             final int size = (int) file.length();
             new QuotaChecker(quotaManager, quotaRootResolver, mailbox).tryAddition(1, size);
 
             return locker.executeWithLock(getMailboxPath(), () -> {
-                MessageMetaData data = appendMessageToStore(internalDate, size, bodyStartOctet, contentIn, flags, propertyBuilder, mailboxSession);
+                Pair<MessageMetaData, List<MessageAttachment>> data = appendMessageToStore(internalDate, size, bodyStartOctet, contentIn, flags, propertyBuilder, mailboxSession);
 
                 Mailbox mailbox = getMailboxEntity();
 
@@ -457,12 +458,14 @@ public class StoreMessageManager implements MessageManager {
                     .randomEventId()
                     .mailboxSession(mailboxSession)
                     .mailbox(mailbox)
-                    .addMetaData(data)
+                    .addMetaData(data.getLeft())
                     .build(),
                     new MailboxIdRegistrationKey(mailbox.getMailboxId()))
                     .subscribeOn(Schedulers.elastic())
                     .block();
-                return new ComposedMessageId(mailbox.getMailboxId(), data.getMessageId(), data.getUid());
+                MessageMetaData messageMetaData = data.getLeft();
+                ComposedMessageId ids = new ComposedMessageId(mailbox.getMailboxId(), messageMetaData.getMessageId(), messageMetaData.getUid());
+                return new AppendResult(ids, data.getRight());
             }, MailboxPathLocker.LockType.Write);
         }
     }
@@ -668,14 +671,15 @@ public class StoreMessageManager implements MessageManager {
         }, MailboxPathLocker.LockType.Write);
     }
 
-    private MessageMetaData appendMessageToStore(Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, MailboxSession session) throws MailboxException {
+    private Pair<MessageMetaData, List<MessageAttachment>> appendMessageToStore(Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder, MailboxSession session) throws MailboxException {
         MessageMapper messageMapper = mapperFactory.getMessageMapper(session);
         MessageId messageId = messageIdFactory.generate();
 
         return mapperFactory.getMessageMapper(session).execute(() -> {
             List<MessageAttachment> attachments = storeAttachments(messageId, content, session);
             MailboxMessage message = createMessage(internalDate, size, bodyStartOctet, content, flags, propertyBuilder, attachments);
-            return messageMapper.add(getMailboxEntity(), message);
+            MessageMetaData metadata = messageMapper.add(getMailboxEntity(), message);
+            return Pair.of(metadata, attachments);
         });
     }
 
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractCombinationManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractCombinationManagerTest.java
index 03f5900..33a7280 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractCombinationManagerTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractCombinationManagerTest.java
@@ -98,7 +98,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMessageCountFromMessageManagerShouldReturnDataSetInMailboxesFromMessageIdManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -111,7 +111,7 @@ public abstract class AbstractCombinationManagerTest {
         query.andCriteria(SearchQuery.all());
 
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -124,7 +124,7 @@ public abstract class AbstractCombinationManagerTest {
         query.andCriteria(SearchQuery.all());
 
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.setInMailboxes(messageId,
             ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
@@ -142,7 +142,7 @@ public abstract class AbstractCombinationManagerTest {
         SearchQuery query = new SearchQuery();
         query.andCriteria(SearchQuery.all());
 
-        ComposedMessageId composedMessageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session);
+        ComposedMessageId composedMessageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session).getIds();
 
         messageIdManager.setInMailboxes(composedMessageId.getMessageId(),
             ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
@@ -161,7 +161,7 @@ public abstract class AbstractCombinationManagerTest {
         MultimailboxesSearchQuery multiMailboxesQuery = builder.build();
 
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -173,7 +173,7 @@ public abstract class AbstractCombinationManagerTest {
     void setFlagsToDeleteThenExpungeFromMessageManagerThenGetMessageFromMessageIdManagerShouldNotReturnAnything() throws Exception {
         Flags deleted = new Flags(Flag.DELETED);
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageManager1.setFlags(deleted, FlagsUpdateMode.ADD, MessageRange.all(), session);
         messageManager1.expunge(MessageRange.all(), session);
@@ -184,7 +184,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void expungeFromMessageManagerShouldWorkWhenSetFlagsToDeletedWithMessageIdManager() throws Exception {
         Flags deleted = new Flags(Flag.DELETED);
-        ComposedMessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session);
+        ComposedMessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session).getIds();
 
         messageIdManager.setFlags(deleted, FlagsUpdateMode.ADD, messageId.getMessageId(), ImmutableList.of(mailbox1.getMailboxId()), session);
 
@@ -199,7 +199,7 @@ public abstract class AbstractCombinationManagerTest {
         ComposedMessageId messageId = messageManager1.appendMessage(
             MessageManager.AppendCommand.builder()
                 .withFlags(deleted)
-                .build(mailContent), session);
+                .build(mailContent), session).getIds();
 
         messageIdManager.setInMailboxes(messageId.getMessageId(), ImmutableList.of(mailbox1.getMailboxId()), session);
 
@@ -211,7 +211,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMessageFromMessageIdManagerShouldReturnMessageWhenAppendMessageFromMessageManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         assertThat(messageIdManager.getMessage(messageId, FetchGroup.MINIMAL, session)).hasSize(1);
     }
@@ -219,7 +219,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMessageFromMessageIdManagerShouldReturnMessageWhenCopyMessageWithMailboxIdFromMailboxManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         mailboxManager.copyMessages(MessageRange.all(), mailbox1.getMailboxId(), mailbox2.getMailboxId(), session);
 
@@ -233,7 +233,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMessageFromMessageIdManagerShouldReturnMessageWhenCopyMessageWithMailboxPathFromMailboxManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         mailboxManager.copyMessages(MessageRange.all(), MailboxFixture.INBOX_ALICE, MailboxFixture.OUTBOX_ALICE, session);
 
@@ -247,7 +247,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMessageFromMessageIdManagerShouldReturnMessageWhenMoveMessageWithMailboxIdFromMailboxManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         mailboxManager.moveMessages(MessageRange.all(), MailboxFixture.INBOX_ALICE, MailboxFixture.OUTBOX_ALICE, session);
 
@@ -261,7 +261,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMessagesFromMessageManagerShouldReturnMessagesCreatedBySetInMailboxesFromMessageIdManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -276,7 +276,7 @@ public abstract class AbstractCombinationManagerTest {
         ComposedMessageId messageId = messageManager1.appendMessage(
             MessageManager.AppendCommand.builder()
                 .withFlags(recent)
-                .build(mailContent), session);
+                .build(mailContent), session).getIds();
 
         long mailbox2NextUid = messageManager2.getMetaData(true, session, MessageManager.MetaData.FetchGroup.UNSEEN_COUNT).getUidNext().asLong();
         messageIdManager.setInMailboxes(messageId.getMessageId(), ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
@@ -294,7 +294,7 @@ public abstract class AbstractCombinationManagerTest {
             MessageManager.AppendCommand.builder()
                 .withFlags(recent)
                 .build(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -307,7 +307,7 @@ public abstract class AbstractCombinationManagerTest {
         ComposedMessageId messageId = messageManager1.appendMessage(
             MessageManager.AppendCommand.builder()
                 .withFlags(recent)
-                .build(mailContent), session);
+                .build(mailContent), session).getIds();
 
         messageIdManager.setInMailboxes(messageId.getMessageId(), ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -327,7 +327,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMetadataFromMessageManagerShouldReturnHighestModSeqWhenSetInMailboxesFromMessageIdManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -337,7 +337,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMetadataFromMessageManagerShouldReturnMessageCountWhenSetInMailboxesFromMessageIdManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -347,7 +347,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMetadataFromMessageManagerShouldReturnNumberOfUnseenMessageWhenSetInMailboxesFromMessageIdManager() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -356,7 +356,7 @@ public abstract class AbstractCombinationManagerTest {
 
     @Test
     void getMetadataFromMessageManagerShouldReturnFirstUnseenMessageWhenSetInMailboxesFromMessageIdManager() throws Exception {
-        ComposedMessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session);
+        ComposedMessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session).getIds();
 
         messageIdManager.setInMailboxes(messageId.getMessageId(), ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -367,7 +367,7 @@ public abstract class AbstractCombinationManagerTest {
     void getMetadataFromMessageManagerShouldReturnNumberOfUnseenMessageWhenSetFlagsFromMessageIdManager() throws Exception {
         Flags newFlag = new Flags(Flag.RECENT);
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.setFlags(newFlag, FlagsUpdateMode.ADD, messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -377,7 +377,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void getMetadataFromMessageManagerShouldReturnFirstUnseenMessageWhenSetFlagsFromMessageIdManager() throws Exception {
         Flags newFlag = new Flags(Flag.USER);
-        ComposedMessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session);
+        ComposedMessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session).getIds();
 
         messageIdManager.setFlags(newFlag, FlagsUpdateMode.ADD, messageId.getMessageId(), ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -387,7 +387,7 @@ public abstract class AbstractCombinationManagerTest {
     @Test
     void setInMailboxesFromMessageIdManagerShouldMoveMessage() throws Exception {
         MessageId messageId = messageManager1.appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox2.getMailboxId()), session);
 
@@ -412,7 +412,7 @@ public abstract class AbstractCombinationManagerTest {
             MessageManager.AppendCommand.builder()
                 .withFlags(messageFlag)
                 .build(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -443,7 +443,7 @@ public abstract class AbstractCombinationManagerTest {
             MessageManager.AppendCommand.builder()
                 .withFlags(messageFlag)
                 .build(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.setFlags(deleted, FlagsUpdateMode.ADD, messageId, ImmutableList.of(mailbox1.getMailboxId()), session);
 
@@ -461,7 +461,7 @@ public abstract class AbstractCombinationManagerTest {
             MessageManager.AppendCommand.builder()
                 .withFlags(customFlag1)
                 .build(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
 
         messageIdManager.setFlags(customFlag2, FlagsUpdateMode.ADD, messageId, ImmutableList.of(mailbox1.getMailboxId()), session);
@@ -483,7 +483,7 @@ public abstract class AbstractCombinationManagerTest {
             MessageManager.AppendCommand.builder()
                 .withFlags(custom1)
                 .build(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
         messageManager2.setFlags(custom2, FlagsUpdateMode.ADD, MessageRange.all(), session);
@@ -500,7 +500,7 @@ public abstract class AbstractCombinationManagerTest {
     void getUidsShouldInteractWellWithSetInMailboxes() throws Exception {
         MessageId messageId = messageManager1
             .appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.setInMailboxes(messageId, ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
@@ -521,7 +521,7 @@ public abstract class AbstractCombinationManagerTest {
     void getUidsShouldInteractWellWithDelete() throws Exception {
         MessageId messageId = messageManager1
             .appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.delete(messageId, ImmutableList.of(mailbox1.getMailboxId()), session);
 
@@ -533,10 +533,10 @@ public abstract class AbstractCombinationManagerTest {
     void getUidsShouldInteractWellWithDeletes() throws Exception {
         MessageId messageId1 = messageManager1
             .appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
         MessageId messageId2 = messageManager1
             .appendMessage(MessageManager.AppendCommand.from(mailContent), session)
-            .getMessageId();
+            .getIds().getMessageId();
 
         messageIdManager.delete(ImmutableList.of(messageId1, messageId2), session);
 
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerStorageTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerStorageTest.java
index fa1c0ec..55914ad 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerStorageTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerStorageTest.java
@@ -969,6 +969,7 @@ public abstract class AbstractMessageIdManagerStorageTest {
             .appendMessage(MessageManager.AppendCommand.builder()
             .withFlags(new Flags(Flags.Flag.DELETED))
             .build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/twoAttachmentsApi.eml")), bobSession)
+            .getIds()
             .getMessageId();
 
         List<MessageResult> messages = messageIdManager.getMessage(messageId, FetchGroup.MINIMAL, bobSession);
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
index 6da8aa0..9063fd6 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
@@ -133,7 +133,7 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1388617200000L),
             session,
             RECENT,
-            new Flags(Flags.Flag.DELETED));
+            new Flags(Flags.Flag.DELETED)).getIds();
         // sentDate: Thu, 4 Jun 2015 09:23:37 +0000
         // Internal date : 2014/02/02 00:00:00.000
         m2 = inboxMessageManager.appendMessage(
@@ -141,7 +141,7 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1391295600000L),
             session,
             RECENT,
-            new Flags(Flags.Flag.ANSWERED));
+            new Flags(Flags.Flag.ANSWERED)).getIds();
         // sentDate: Thu, 4 Jun 2015 09:27:37 +0000
         // Internal date : 2014/03/02 00:00:00.000
         m3 = inboxMessageManager.appendMessage(
@@ -149,7 +149,7 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1393714800000L),
             session,
             RECENT,
-            new Flags(Flags.Flag.DRAFT));
+            new Flags(Flags.Flag.DRAFT)).getIds();
         // sentDate: Tue, 2 Jun 2015 08:16:19 +0000
         // Internal date : 2014/05/02 00:00:00.000
         m4 = inboxMessageManager.appendMessage(
@@ -157,7 +157,7 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1398981600000L),
             session,
             RECENT,
-            new Flags(Flags.Flag.RECENT));
+            new Flags(Flags.Flag.RECENT)).getIds();
         // sentDate: Fri, 15 May 2015 06:35:59 +0000
         // Internal date : 2014/04/02 00:00:00.000
         m5 = inboxMessageManager.appendMessage(
@@ -165,7 +165,7 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1396389600000L),
             session,
             RECENT,
-            new Flags(Flags.Flag.FLAGGED));
+            new Flags(Flags.Flag.FLAGGED)).getIds();
         // sentDate: Wed, 03 Jun 2015 19:14:32 +0000
         // Internal date : 2014/06/02 00:00:00.000
         m6 = inboxMessageManager.appendMessage(
@@ -173,7 +173,7 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1401660000000L),
             session,
             RECENT,
-            new Flags(Flags.Flag.SEEN));
+            new Flags(Flags.Flag.SEEN)).getIds();
         // sentDate: Thu, 04 Jun 2015 07:36:08 +0000
         // Internal date : 2014/07/02 00:00:00.000
         m7 = inboxMessageManager.appendMessage(
@@ -181,7 +181,7 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1404252000000L),
             session,
             NOT_RECENT,
-            new Flags());
+            new Flags()).getIds();
         // sentDate: Thu, 4 Jun 2015 06:08:41 +0200
         // Internal date : 2014/08/02 00:00:00.000
         m8 = inboxMessageManager.appendMessage(
@@ -189,7 +189,7 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1406930400000L),
             session,
             RECENT,
-            new Flags("Hello"));
+            new Flags("Hello")).getIds();
         // sentDate: Thu, 4 Jun 2015 06:08:41 +0200
         // Internal date : 2014/08/02 00:00:00.000
         mOther = myFolderMessageManager.appendMessage(
@@ -197,34 +197,34 @@ public abstract class AbstractMessageSearchIndexTest {
             new Date(1406930400000L),
             session,
             RECENT,
-            new Flags(Flags.Flag.SEEN));
+            new Flags(Flags.Flag.SEEN)).getIds();
         m9 = inboxMessageManager.appendMessage(
             ClassLoader.getSystemResourceAsStream("eml/frnog.eml"),
             new Date(1409608800000L),
             session,
             RECENT,
-            new Flags("Hello you"));
+            new Flags("Hello you")).getIds();
 
         mailWithAttachment = myFolderMessageManager.appendMessage(
             ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeTextInlined.eml"),
             new Date(1409608900000L),
             session,
             RECENT,
-            new Flags("Hello you"));
+            new Flags("Hello you")).getIds();
 
         mailWithInlinedAttachment = myFolderMessageManager.appendMessage(
             ClassLoader.getSystemResourceAsStream("eml/oneInlinedAttachment.eml"),
             new Date(1409608900000L),
             session,
             RECENT,
-            new Flags("Hello you"));
+            new Flags("Hello you")).getIds();
 
         m10 = otherInboxMessageManager.appendMessage(
             ClassLoader.getSystemResourceAsStream("eml/mail1.eml"),
             new Date(1391295600000L),
             otherSession,
             RECENT,
-            new Flags());
+            new Flags()).getIds();
 
         await();
     }
@@ -422,7 +422,7 @@ public abstract class AbstractMessageSearchIndexTest {
         ComposedMessageId mailWithDotsInHeader = myFolderMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(ClassLoader.getSystemResourceAsStream("eml/headerWithDot.eml")),
-            session);
+            session).getIds();
         await();
         
         SearchQuery searchQuery = new SearchQuery(SearchQuery.all());
@@ -437,7 +437,7 @@ public abstract class AbstractMessageSearchIndexTest {
         ComposedMessageId mailWithDotsInHeader = myFolderMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(ClassLoader.getSystemResourceAsStream("eml/headerWithDot.eml")),
-            session);
+            session).getIds();
         await();
 
         SearchQuery searchQuery = new SearchQuery(SearchQuery.headerExists("X-header.with.dots"));
@@ -453,7 +453,7 @@ public abstract class AbstractMessageSearchIndexTest {
         ComposedMessageId m11 = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
             .build(ClassLoader.getSystemResourceAsStream("eml/mail5.eml")),
-            session);
+            session).getIds();
 
         String emailToSearch = "luc.duzan@james.apache.org";
 
@@ -1362,7 +1362,7 @@ public abstract class AbstractMessageSearchIndexTest {
         ComposedMessageId messageWithBeautifulBananaAsTextAttachment = myFolderMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
             .build(ClassLoader.getSystemResourceAsStream("eml/emailWithTextAttachment.eml")),
-            session);
+            session).getIds();
         await();
 
         SearchQuery searchQuery = new SearchQuery(SearchQuery.mailContains("User message banana"));
@@ -1377,7 +1377,7 @@ public abstract class AbstractMessageSearchIndexTest {
         ComposedMessageId messageWithBeautifulBananaAsTextAttachment = myFolderMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(ClassLoader.getSystemResourceAsStream("eml/emailWithTextAttachment.eml")),
-            session);
+            session).getIds();
         await();
 
         SearchQuery searchQuery = new SearchQuery(SearchQuery.attachmentContains("beautiful banana"));
@@ -1401,7 +1401,7 @@ public abstract class AbstractMessageSearchIndexTest {
                 .setBody(multipart)
                 .build();
         ComposedMessageId messageWithBeautifulBananaAsPDFAttachment = myFolderMessageManager
-            .appendMessage(MessageManager.AppendCommand.from(message), session);
+            .appendMessage(MessageManager.AppendCommand.from(message), session).getIds();
         await();
 
         SearchQuery searchQuery = new SearchQuery(SearchQuery.attachmentContains("beautiful banana"));
@@ -1441,19 +1441,19 @@ public abstract class AbstractMessageSearchIndexTest {
             .build(Message.Builder.of()
                 .setSubject("test")
                 .setBody("testmail", StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
         ComposedMessageId message2 = messageManager.appendMessage(MessageManager.AppendCommand.builder()
             .withInternalDate(date2)
             .build(Message.Builder.of()
                 .setSubject("test")
                 .setBody("testmail", StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
         ComposedMessageId message3 = messageManager.appendMessage(MessageManager.AppendCommand.builder()
             .withInternalDate(date3)
             .build(Message.Builder.of()
                 .setSubject("test")
                 .setBody("testmail", StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
 
         await();
 
@@ -1480,7 +1480,7 @@ public abstract class AbstractMessageSearchIndexTest {
             .withInternalDate(date1)
             .build(Message.Builder.of()
                 .setSubject("test")
-                .setBody("testmail", StandardCharsets.UTF_8)), session);
+                .setBody("testmail", StandardCharsets.UTF_8)), session).getIds();
         ComposedMessageId message2 = messageManager.appendMessage(MessageManager.AppendCommand.builder()
             .withInternalDate(date2)
             .build(Message.Builder.of()
@@ -1488,12 +1488,12 @@ public abstract class AbstractMessageSearchIndexTest {
                 .setDate(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
                     .parse("2017/08/23 00:00:00 "), TimeZone.getTimeZone(ZoneId.of("+0200")))
                 .setBody("testmail", StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
         ComposedMessageId message3 = messageManager.appendMessage(MessageManager.AppendCommand.builder()
             .withInternalDate(date3)
             .build(Message.Builder.of()
                 .setSubject("test")
-                .setBody("testmail", StandardCharsets.UTF_8)), session);
+                .setBody("testmail", StandardCharsets.UTF_8)), session).getIds();
 
         await();
 
@@ -1555,7 +1555,7 @@ public abstract class AbstractMessageSearchIndexTest {
                                     .build())
                                 .build())
                             .build())),
-            session);
+            session).getIds();
 
         await();
 
diff --git a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/MessageIdReIndexerImplTest.java b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/MessageIdReIndexerImplTest.java
index 41a043f..694a73c 100644
--- a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/MessageIdReIndexerImplTest.java
+++ b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/MessageIdReIndexerImplTest.java
@@ -67,7 +67,7 @@ public class MessageIdReIndexerImplTest {
         ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
             .appendMessage(
                 MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                systemSession);
+                systemSession).getIds();
 
         reIndexer.reIndex(createdMessage.getMessageId()).run();
 
diff --git a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/ReIndexerImplTest.java b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/ReIndexerImplTest.java
index a24e48a..7399e20 100644
--- a/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/ReIndexerImplTest.java
+++ b/mailbox/tools/indexer/src/test/java/org/apache/mailbox/tools/indexer/ReIndexerImplTest.java
@@ -71,7 +71,7 @@ public class ReIndexerImplTest {
         ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
             .appendMessage(
                 MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                systemSession);
+                systemSession).getIds();
 
         reIndexer.reIndex(INBOX).run();
 
@@ -98,7 +98,7 @@ public class ReIndexerImplTest {
         ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
             .appendMessage(
                 MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                systemSession);
+                systemSession).getIds();
 
         reIndexer.reIndex().run();
         ArgumentCaptor<MailboxMessage> messageCaptor = ArgumentCaptor.forClass(MailboxMessage.class);
@@ -124,7 +124,7 @@ public class ReIndexerImplTest {
         ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
             .appendMessage(
                 MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                systemSession);
+                systemSession).getIds();
 
         reIndexer.reIndex(USERNAME).run();
         ArgumentCaptor<MailboxMessage> messageCaptor = ArgumentCaptor.forClass(MailboxMessage.class);
@@ -150,7 +150,7 @@ public class ReIndexerImplTest {
         ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
             .appendMessage(
                 MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                systemSession);
+                systemSession).getIds();
 
         reIndexer.reIndex(INBOX, createdMessage.getUid()).run();
         ArgumentCaptor<MailboxMessage> messageCaptor = ArgumentCaptor.forClass(MailboxMessage.class);
@@ -173,7 +173,7 @@ public class ReIndexerImplTest {
         ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
             .appendMessage(
                 MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                systemSession);
+                systemSession).getIds();
 
         reIndexer.reIndex(mailboxId, createdMessage.getUid()).run();
         ArgumentCaptor<MailboxMessage> messageCaptor = ArgumentCaptor.forClass(MailboxMessage.class);
@@ -216,7 +216,7 @@ public class ReIndexerImplTest {
         ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
             .appendMessage(
                 MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                systemSession);
+                systemSession).getIds();
 
         reIndexer.reIndex(mailboxId).run();
         ArgumentCaptor<MailboxMessage> messageCaptor = ArgumentCaptor.forClass(MailboxMessage.class);
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/AppendProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/AppendProcessor.java
index 2b348fd..1efaedb 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/AppendProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/AppendProcessor.java
@@ -127,7 +127,8 @@ public class AppendProcessor extends AbstractMailboxProcessor<AppendRequest> {
             final MailboxSession mailboxSession = session.getMailboxSession();
             final SelectedMailbox selectedMailbox = session.getSelected();
             final boolean isSelectedMailbox = selectedMailbox != null && selectedMailbox.getMailboxId().equals(mailbox.getId());
-            final ComposedMessageId messageId = mailbox.appendMessage(message, datetime, mailboxSession, !isSelectedMailbox, flagsToBeSet);
+            final ComposedMessageId messageId = mailbox.appendMessage(message, datetime, mailboxSession, !isSelectedMailbox, flagsToBeSet)
+                .getIds();
             if (isSelectedMailbox) {
                 selectedMailbox.addRecent(messageId.getUid());
             }
diff --git a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java
index f112583..c5b0c54 100644
--- a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java
+++ b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java
@@ -152,7 +152,7 @@ public class MailboxProbeImpl implements GuiceProbe, MailboxProbe {
 
         MailboxSession mailboxSession = mailboxManager.createSystemSession(Username.of(username));
         MessageManager messageManager = mailboxManager.getMailbox(mailboxPath, mailboxSession);
-        return messageManager.appendMessage(message, internalDate, mailboxSession, isRecent, flags);
+        return messageManager.appendMessage(message, internalDate, mailboxSession, isRecent, flags).getIds();
     }
 
     public ComposedMessageId appendMessage(String username, MailboxPath mailboxPath, MessageManager.AppendCommand appendCommand)
@@ -160,7 +160,7 @@ public class MailboxProbeImpl implements GuiceProbe, MailboxProbe {
 
         MailboxSession mailboxSession = mailboxManager.createSystemSession(Username.of(username));
         MessageManager messageManager = mailboxManager.getMailbox(mailboxPath, mailboxSession);
-        return messageManager.appendMessage(appendCommand, mailboxSession);
+        return messageManager.appendMessage(appendCommand, mailboxSession).getIds();
     }
 
     @Override
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailboxAppender.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailboxAppender.java
index 9722c19..f552ca4 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailboxAppender.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailboxAppender.java
@@ -26,6 +26,7 @@ import org.apache.james.core.Username;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.MessageManager.AppendResult;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MailboxExistsException;
 import org.apache.james.mailbox.model.ComposedMessageId;
@@ -49,7 +50,8 @@ public class MailboxAppender {
 
     public ComposedMessageId append(MimeMessage mail, Username user, String folder) throws MessagingException {
         MailboxSession session = createMailboxSession(user);
-        return append(mail, user, useSlashAsSeparator(folder, session), session);
+        return append(mail, user, useSlashAsSeparator(folder, session), session)
+            .getIds();
     }
 
     private String useSlashAsSeparator(String urlPath, MailboxSession session) throws MessagingException {
@@ -63,7 +65,7 @@ public class MailboxAppender {
         return destination;
     }
 
-    private ComposedMessageId append(MimeMessage mail, Username user, String folder, MailboxSession session) throws MessagingException {
+    private AppendResult append(MimeMessage mail, Username user, String folder, MailboxSession session) throws MessagingException {
         mailboxManager.startProcessingRequest(session);
         try {
             MailboxPath mailboxPath = MailboxPath.forUser(user, folder);
@@ -75,7 +77,7 @@ public class MailboxAppender {
         }
     }
 
-    private ComposedMessageId appendMessageToMailbox(MimeMessage mail, MailboxSession session, MailboxPath path) throws MailboxException, MessagingException {
+    private AppendResult appendMessageToMailbox(MimeMessage mail, MailboxSession session, MailboxPath path) throws MailboxException, MessagingException {
         createMailboxIfNotExist(session, path);
         final MessageManager mailbox = mailboxManager.getMailbox(path, session);
         if (mailbox == null) {
diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/LocalDeliveryTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/LocalDeliveryTest.java
index 601a78d..44716b2 100644
--- a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/LocalDeliveryTest.java
+++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/LocalDeliveryTest.java
@@ -36,6 +36,8 @@ import org.apache.james.core.builder.MimeMessageBuilder;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.MessageManager.AppendCommand;
+import org.apache.james.mailbox.MessageManager.AppendResult;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.metrics.tests.RecordingMetricFactory;
@@ -86,6 +88,7 @@ public class LocalDeliveryTest {
         Username username = Username.of("receiver@domain.com");
         MailboxPath inbox = MailboxPath.inbox(username);
         MessageManager messageManager = mock(MessageManager.class);
+        when(messageManager.appendMessage(any(AppendCommand.class), any(MailboxSession.class))).thenReturn(mock(AppendResult.class));
 
         when(usersRepository.supportVirtualHosting()).thenReturn(true);
         when(usersRepository.getUsername(new MailAddress(username.asString()))).thenReturn(username);
@@ -98,7 +101,7 @@ public class LocalDeliveryTest {
         testee.service(mail);
 
         // Then
-        verify(messageManager).appendMessage(any(MessageManager.AppendCommand.class), any(MailboxSession.class));
+        verify(messageManager).appendMessage(any(AppendCommand.class), any(MailboxSession.class));
     }
 
     @Test
@@ -107,6 +110,7 @@ public class LocalDeliveryTest {
         Username username = Username.of("receiver");
         MailboxPath inbox = MailboxPath.inbox(username);
         MessageManager messageManager = mock(MessageManager.class);
+        when(messageManager.appendMessage(any(AppendCommand.class), any(MailboxSession.class))).thenReturn(mock(AppendResult.class));
         when(usersRepository.supportVirtualHosting()).thenReturn(false);
         when(usersRepository.getUsername(new MailAddress("receiver@localhost"))).thenReturn(username);
         when(usersRepository.getUsername(new MailAddress(RECEIVER_DOMAIN_COM))).thenReturn(username);
@@ -119,7 +123,7 @@ public class LocalDeliveryTest {
         testee.service(mail);
 
         // Then
-        verify(messageManager).appendMessage(any(MessageManager.AppendCommand.class), any(MailboxSession.class));
+        verify(messageManager).appendMessage(any(AppendCommand.class), any(MailboxSession.class));
     }
 
     private Mail createMail() throws MessagingException, IOException {
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageAppender.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageAppender.java
index 595dce4..3b76e13 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageAppender.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageAppender.java
@@ -38,6 +38,7 @@ import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.MessageManager.AppendResult;
 import org.apache.james.mailbox.exception.AttachmentNotFoundException;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.AttachmentId;
@@ -74,8 +75,8 @@ public class MessageAppender {
     }
 
     public MetaDataWithContent appendMessageInMailboxes(CreationMessageEntry createdEntry,
-                                                                               List<MailboxId> targetMailboxes,
-                                                                               MailboxSession session) throws MailboxException {
+                                                        List<MailboxId> targetMailboxes,
+                                                        MailboxSession session) throws MailboxException {
         Preconditions.checkArgument(!targetMailboxes.isEmpty());
         ImmutableList<MessageAttachment> messageAttachments = getMessageAttachments(session, createdEntry.getValue().getAttachments());
         byte[] messageContent = mimeMessageConverter.convert(createdEntry, messageAttachments, session);
@@ -83,53 +84,54 @@ public class MessageAppender {
         Date internalDate = Date.from(createdEntry.getValue().getDate().toInstant());
 
         MessageManager mailbox = mailboxManager.getMailbox(targetMailboxes.get(0), session);
-        ComposedMessageId message = mailbox.appendMessage(
+        AppendResult appendResult = mailbox.appendMessage(
             MessageManager.AppendCommand.builder()
                 .withInternalDate(internalDate)
                 .withFlags(getFlags(createdEntry.getValue()))
                 .notRecent()
                 .build(content),
             session);
+        ComposedMessageId ids = appendResult.getIds();
         if (targetMailboxes.size() > 1) {
-            messageIdManager.setInMailboxes(message.getMessageId(), targetMailboxes, session);
+            messageIdManager.setInMailboxes(ids.getMessageId(), targetMailboxes, session);
         }
 
         return MetaDataWithContent.builder()
-            .uid(message.getUid())
+            .uid(ids.getUid())
             .keywords(createdEntry.getValue().getKeywords())
             .internalDate(internalDate.toInstant())
             .sharedContent(content)
             .size(messageContent.length)
-            .attachments(messageAttachments)
+            .attachments(appendResult.getMessageAttachments())
             .mailboxId(mailbox.getId())
-            .messageId(message.getMessageId())
+            .messageId(ids.getMessageId())
             .build();
     }
 
     public MetaDataWithContent appendMessageInMailbox(org.apache.james.mime4j.dom.Message message,
-                                                                             MessageManager messageManager,
-                                                                             List<MessageAttachment> attachments,
-                                                                             Flags flags,
-                                                                             MailboxSession session) throws MailboxException {
+                                                      MessageManager messageManager,
+                                                      Flags flags,
+                                                      MailboxSession session) throws MailboxException {
 
 
         byte[] messageContent = asBytes(message);
         SharedByteArrayInputStream content = new SharedByteArrayInputStream(messageContent);
         Date internalDate = new Date();
 
-        ComposedMessageId appendedMessage = messageManager.appendMessage(MessageManager.AppendCommand.builder()
+        AppendResult appendResult = messageManager.appendMessage(MessageManager.AppendCommand.builder()
             .withFlags(flags)
             .build(content), session);
+        ComposedMessageId ids = appendResult.getIds();
 
         return MetaDataWithContent.builder()
-            .uid(appendedMessage.getUid())
+            .uid(ids.getUid())
             .keywords(Keywords.lenientFactory().fromFlags(flags))
             .internalDate(internalDate.toInstant())
             .sharedContent(content)
             .size(messageContent.length)
-            .attachments(attachments)
+            .attachments(appendResult.getMessageAttachments())
             .mailboxId(messageManager.getId())
-            .messageId(appendedMessage.getMessageId())
+            .messageId(ids.getMessageId())
             .build();
     }
 
@@ -141,12 +143,6 @@ public class MessageAppender {
         }
     }
 
-    public MetaDataWithContent appendMessageInMailbox(CreationMessageEntry createdEntry,
-                                                                             MailboxId targetMailbox,
-                                                                             MailboxSession session) throws MailboxException {
-        return appendMessageInMailboxes(createdEntry, ImmutableList.of(targetMailbox), session);
-    }
-
     private Flags getFlags(CreationMessage message) {
         return message.getKeywords().asFlags();
     }
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SendMDNProcessor.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SendMDNProcessor.java
index 9b782ec..98f6675 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SendMDNProcessor.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/SendMDNProcessor.java
@@ -22,7 +22,6 @@ package org.apache.james.jmap.draft.methods;
 import static org.apache.james.jmap.draft.methods.Method.JMAP_PREFIX;
 
 import java.io.IOException;
-import java.nio.charset.StandardCharsets;
 import java.util.List;
 
 import javax.inject.Inject;
@@ -43,13 +42,9 @@ import org.apache.james.mailbox.Role;
 import org.apache.james.mailbox.SystemMailboxesProvider;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.OverQuotaException;
-import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.FetchGroup;
-import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageResult;
-import org.apache.james.mdn.MDN;
-import org.apache.james.mdn.MDNReport;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.mime4j.codec.DecodeMonitor;
 import org.apache.james.mime4j.dom.Message;
@@ -60,8 +55,6 @@ import org.apache.james.server.core.Envelope;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.ImmutableList;
-
 public class SendMDNProcessor implements SetMessagesProcessor {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(SendMDNProcessor.class);
@@ -145,14 +138,12 @@ public class SendMDNProcessor implements SetMessagesProcessor {
 
         JmapMDN mdn = MDNCreationEntry.getValue();
         Message originalMessage = retrieveOriginalMessage(mdn, mailboxSession);
-        MDNReport mdnReport = mdn.generateReport(originalMessage, mailboxSession);
-        List<MessageAttachment> reportAsAttachment = ImmutableList.of(convertReportToAttachment(mdnReport));
 
         Message mdnAnswer = mdn.generateMDNMessage(originalMessage, mailboxSession);
 
         Flags seen = new Flags(Flags.Flag.SEEN);
         MetaDataWithContent metaDataWithContent = messageAppender.appendMessageInMailbox(mdnAnswer,
-            getOutbox(mailboxSession), reportAsAttachment, seen, mailboxSession);
+            getOutbox(mailboxSession), seen, mailboxSession);
 
         messageSender.sendMessage(metaDataWithContent,
             Envelope.fromMime4JMessage(mdnAnswer), mailboxSession);
@@ -173,19 +164,6 @@ public class SendMDNProcessor implements SetMessagesProcessor {
         return messageBuilder.parseMessage(messages.get(0).getHeaders().getInputStream());
     }
 
-    private MessageAttachment convertReportToAttachment(MDNReport mdnReport) {
-        Attachment attachment = Attachment.builder()
-            .bytes(mdnReport.formattedValue().getBytes(StandardCharsets.UTF_8))
-            .type(MDN.DISPOSITION_CONTENT_TYPE)
-            .build();
-
-        return MessageAttachment.builder()
-            .attachment(attachment)
-            .isInline(true)
-            .build();
-    }
-
-
     private MessageManager getOutbox(MailboxSession mailboxSession) throws MailboxException {
         return systemMailboxesProvider.getMailboxByRole(Role.OUTBOX, mailboxSession.getUser())
             .findAny()
diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/JmapMDN.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/JmapMDN.java
index ecc6429..57194b4 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/JmapMDN.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/JmapMDN.java
@@ -176,8 +176,7 @@ public class JmapMDN {
             .findFirst();
     }
 
-
-    public MDNReport generateReport(Message originalMessage, MailboxSession mailboxSession) throws InvalidOriginMessageForMDNException {
+    private MDNReport generateReport(Message originalMessage, MailboxSession mailboxSession) throws InvalidOriginMessageForMDNException {
         if (originalMessage.getMessageId() == null) {
             throw InvalidOriginMessageForMDNException.missingHeader("Message-ID");
         }
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/MessageFastViewProjectionItemFactoryTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/MessageFastViewProjectionItemFactoryTest.java
index 84fe433..a042f8e 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/MessageFastViewProjectionItemFactoryTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/MessageFastViewProjectionItemFactoryTest.java
@@ -136,7 +136,7 @@ class MessageFastViewProjectionItemFactoryTest {
 
     MessageResult toMessageResult(String messageAsString) throws Exception {
         ComposedMessageId composedMessageId = mailbox.appendMessage(MessageManager.AppendCommand.builder()
-            .build(messageAsString), session);
+            .build(messageAsString), session).getIds();
 
         return mailbox.getMessages(MessageRange.one(composedMessageId.getUid()), FetchGroup.FULL_CONTENT, session)
             .next();
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/GetMessagesMethodTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/GetMessagesMethodTest.java
index 41b2ad1..c726407 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/GetMessagesMethodTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/GetMessagesMethodTest.java
@@ -180,9 +180,9 @@ public class GetMessagesMethodTest {
     @SuppressWarnings("unchecked")
     public void processShouldFetchMessages() throws Exception {
         MessageManager inbox = mailboxManager.getMailbox(inboxPath, session);
-        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session);
-        ComposedMessageId message2 = inbox.appendMessage(AppendCommand.from(messageContent2), session);
-        ComposedMessageId message3 = inbox.appendMessage(AppendCommand.from(messageContent3), session);
+        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session).getIds();
+        ComposedMessageId message2 = inbox.appendMessage(AppendCommand.from(messageContent2), session).getIds();
+        ComposedMessageId message3 = inbox.appendMessage(AppendCommand.from(messageContent3), session).getIds();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId(),
@@ -215,7 +215,7 @@ public class GetMessagesMethodTest {
                 org.apache.james.mime4j.dom.Message.Builder.of()
                     .setSubject("message 1 subject")
                     .setBody("my <b>HTML</b> message", "html", StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message.getMessageId()))
@@ -237,7 +237,7 @@ public class GetMessagesMethodTest {
     @Test
     public void processShouldReturnOnlyMandatoryPropertiesOnEmptyPropertyList() throws Exception {
         MessageManager inbox = mailboxManager.getMailbox(inboxPath, session);
-        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(this.messageContent1), session);
+        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(this.messageContent1), session).getIds();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId()))
@@ -255,7 +255,7 @@ public class GetMessagesMethodTest {
     public void processShouldReturnAllPropertiesWhenNoPropertyGiven() throws Exception {
         MessageManager inbox = mailboxManager.getMailbox(inboxPath, session);
 
-        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session);
+        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session).getIds();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId()))
@@ -271,7 +271,7 @@ public class GetMessagesMethodTest {
     public void processShouldAddMandatoryPropertiesWhenNotInPropertyList() throws Exception {
         MessageManager inbox = mailboxManager.getMailbox(inboxPath, session);
 
-        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session);
+        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session).getIds();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId()))
@@ -290,7 +290,7 @@ public class GetMessagesMethodTest {
     public void processShouldReturnTextBodyWhenBodyInPropertyListAndEmptyHtmlBody() throws Exception {
         MessageManager inbox = mailboxManager.getMailbox(inboxPath, session);
 
-        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session);
+        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent1), session).getIds();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId()))
@@ -316,7 +316,7 @@ public class GetMessagesMethodTest {
                 org.apache.james.mime4j.dom.Message.Builder.of()
                     .setSubject("message 1 subject")
                     .setBody("my <b>HTML</b> message", "html", StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message.getMessageId()))
@@ -344,7 +344,7 @@ public class GetMessagesMethodTest {
             AppendCommand.from(org.apache.james.mime4j.dom.Message.Builder.of()
                 .setSubject("message 1 subject")
                 .setBody("", "html", StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message.getMessageId()))
@@ -378,7 +378,7 @@ public class GetMessagesMethodTest {
                     .addBodyPart(BodyPartBuilder.create()
                         .setBody("<a>The </a> <strong>HTML</strong> message", "html", StandardCharsets.UTF_8))
                     .build())),
-            session);
+            session).getIds();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message.getMessageId()))
@@ -409,7 +409,7 @@ public class GetMessagesMethodTest {
                     .setField(new RawField("HEADer2", "Header2Content"))
                     .setSubject("message 1 subject")
                     .setBody("my message", StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId()))
@@ -437,7 +437,7 @@ public class GetMessagesMethodTest {
                     .setField(new RawField("HEADer2", "Header2Content"))
                     .setSubject("message 1 subject")
                     .setBody("my message", StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId()))
@@ -469,7 +469,7 @@ public class GetMessagesMethodTest {
                     .setField(new RawField("HEADer2", "Header2Content"))
                     .setSubject("message 1 subject")
                     .setBody("my message", StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
 
         MailboxId customMailboxId = mailboxManager.getMailbox(customMailboxPath, session).getId();
         messageIdManager.setInMailboxes(message1.getMessageId(),
@@ -506,7 +506,7 @@ public class GetMessagesMethodTest {
                     .setField(new RawField("HEADer2", "Header2Content"))
                     .setSubject("message 1 subject")
                     .setBody("my message", StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
 
         MailboxId customMailboxId = mailboxManager.getMailbox(customMailboxPath, session).getId();
         messageIdManager.setInMailboxes(message1.getMessageId(),
@@ -541,7 +541,7 @@ public class GetMessagesMethodTest {
                     .setField(new RawField("HEADer2", "Header2Content"))
                     .setSubject("message 1 subject")
                     .setBody("my message", StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
 
         MailboxId customMailboxId = mailboxManager.getMailbox(customMailboxPath, session).getId();
         messageIdManager.setInMailboxes(message1.getMessageId(),
@@ -576,7 +576,7 @@ public class GetMessagesMethodTest {
                     .setField(new RawField("HEADer2", "Header2Content"))
                     .setSubject("message 1 subject")
                     .setBody("my message", StandardCharsets.UTF_8)),
-            session);
+            session).getIds();
 
         MailboxId customMailboxId = mailboxManager.getMailbox(customMailboxPath, session).getId();
         messageIdManager.setInMailboxes(message1.getMessageId(),
@@ -611,8 +611,8 @@ public class GetMessagesMethodTest {
             .setBody("my message", StandardCharsets.UTF_8)
             .build();
 
-        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent), session);
-        ComposedMessageId message2 = inbox.appendMessage(AppendCommand.from(messageContent), session);
+        ComposedMessageId message1 = inbox.appendMessage(AppendCommand.from(messageContent), session).getIds();
+        ComposedMessageId message2 = inbox.appendMessage(AppendCommand.from(messageContent), session).getIds();
 
         doCallRealMethod()
             .doThrow(new RuntimeException())
@@ -643,17 +643,17 @@ public class GetMessagesMethodTest {
             AppendCommand.builder()
                 .withFlags(flags)
                 .build(messageContent1),
-            session);
+            session).getIds();
         ComposedMessageId message2 = inbox.appendMessage(
             AppendCommand.builder()
                 .withFlags(flags)
                 .build(messageContent2),
-            session);
+            session).getIds();
         ComposedMessageId message3 = inbox.appendMessage(
             AppendCommand.builder()
                 .withFlags(flags)
                 .build(messageContent3),
-            session);
+            session).getIds();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId(),
@@ -702,17 +702,17 @@ public class GetMessagesMethodTest {
             AppendCommand.builder()
                 .withFlags(flags1)
                 .build(messageContent1),
-            session);
+            session).getIds();
         ComposedMessageId message2 = inbox.appendMessage(
             AppendCommand.builder()
                 .withFlags(flags2)
                 .build(messageContent2),
-            session);
+            session).getIds();
         ComposedMessageId message3 = inbox.appendMessage(
             AppendCommand.builder()
                 .withFlags(flags3)
                 .build(messageContent3),
-            session);
+            session).getIds();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId(),
@@ -756,7 +756,7 @@ public class GetMessagesMethodTest {
             AppendCommand.builder()
                 .withFlags(flags)
                 .build(messageContent1),
-            session);
+            session).getIds();
 
         GetMessagesRequest request = GetMessagesRequest.builder()
             .ids(ImmutableList.of(message1.getMessageId()))
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesUpdateProcessorTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesUpdateProcessorTest.java
index 1afbcb1..a9a8c8d 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesUpdateProcessorTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/methods/SetMessagesUpdateProcessorTest.java
@@ -204,7 +204,9 @@ public class SetMessagesUpdateProcessorTest {
         when(outbox.getMailboxPath()).thenReturn(MailboxPath.forUser(USER, OUTBOX));
 
         when(outbox.appendMessage(any(MessageManager.AppendCommand.class), any(MailboxSession.class)))
-            .thenReturn(new ComposedMessageId(OUTBOX_ID, TestMessageId.of(23), MessageUid.of(1)));
+            .thenReturn(new MessageManager.AppendResult(
+                new ComposedMessageId(OUTBOX_ID, TestMessageId.of(23), MessageUid.of(1)),
+                Optional.empty()));
 
         drafts = mock(MessageManager.class);
         when(drafts.getId()).thenReturn(DRAFTS_ID);
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFastViewFactoryTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFastViewFactoryTest.java
index 1c1463b..a871a02 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFastViewFactoryTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFastViewFactoryTest.java
@@ -121,19 +121,19 @@ class MessageFastViewFactoryTest {
         previewComputedMessage1 = bobInbox.appendMessage(MessageManager.AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.SEEN))
                 .build(ClassLoaderUtils.getSystemResourceAsSharedStream("fullMessage.eml")),
-            session);
+            session).getIds();
         missingPreviewComputedMessage1 = bobInbox.appendMessage(MessageManager.AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.SEEN))
                 .build(ClassLoaderUtils.getSystemResourceAsSharedStream("fullMessage.eml")),
-            session);
+            session).getIds();
         previewComputedMessage2 = bobInbox.appendMessage(MessageManager.AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.SEEN))
                 .build(ClassLoaderUtils.getSystemResourceAsSharedStream("fullMessage.eml")),
-            session);
+            session).getIds();
         previewComputedMessage3 = bobInbox.appendMessage(MessageManager.AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.SEEN))
                 .build(ClassLoaderUtils.getSystemResourceAsSharedStream("fullMessage.eml")),
-            session);
+            session).getIds();
 
         fastViewProjection = new MemoryMessageFastViewProjection(new RecordingMetricFactory());
 
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java
index f6423e4..14f7221 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java
@@ -121,7 +121,7 @@ class MessageFullViewFactoryTest {
         message1 = bobInbox.appendMessage(MessageManager.AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.SEEN))
                 .build(ClassLoaderUtils.getSystemResourceAsSharedStream("fullMessage.eml")),
-            session);
+            session).getIds();
 
         fastViewProjection = spy(new MemoryMessageFastViewProjection(new RecordingMetricFactory()));
         messageFullViewFactory = new MessageFullViewFactory(resources.getBlobManager(), messageContentExtractor, htmlTextExtractor,
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageHeaderViewFactoryTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageHeaderViewFactoryTest.java
index 8ed0b63..06b28fc 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageHeaderViewFactoryTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageHeaderViewFactoryTest.java
@@ -74,7 +74,7 @@ class MessageHeaderViewFactoryTest {
         message1 = bobInbox.appendMessage(MessageManager.AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.SEEN))
                 .build(ClassLoaderUtils.getSystemResourceAsSharedStream("fullMessage.eml")),
-            session);
+            session).getIds();
 
         testee = new MessageHeaderViewFactory(resources.getBlobManager(), messageIdManager);
     }
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageMetadataViewFactoryTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageMetadataViewFactoryTest.java
index 348e1ef..f1423c8 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageMetadataViewFactoryTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageMetadataViewFactoryTest.java
@@ -66,7 +66,7 @@ class MessageMetadataViewFactoryTest {
         message1 = bobInbox.appendMessage(MessageManager.AppendCommand.builder()
                 .withFlags(new Flags(Flags.Flag.SEEN))
                 .build("header: value\r\n\r\nbody"),
-            session);
+            session).getIds();
 
         testee = new MessageMetadataViewFactory(resources.getBlobManager(), messageIdManager);
     }
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/send/PostDequeueDecoratorTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/send/PostDequeueDecoratorTest.java
index 1b4f256..2111440 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/send/PostDequeueDecoratorTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/send/PostDequeueDecoratorTest.java
@@ -114,7 +114,7 @@ public class PostDequeueDecoratorTest {
         mailboxManager.createMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
         mailboxManager.createMailbox(SENT_MAILBOX_PATH, mailboxSession);
         MessageManager messageManager = mailboxManager.getMailbox(SENT_MAILBOX_PATH, mailboxSession);
-        ComposedMessageId sentMessageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession);
+        ComposedMessageId sentMessageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getIds();
         mail.setAttribute(messageIdAttribute(sentMessageId.getMessageId().serialize()));
         mail.setAttribute(USERNAME_ATTRIBUTE);
         
@@ -126,7 +126,7 @@ public class PostDequeueDecoratorTest {
         MailboxSession mailboxSession = mailboxManager.createSystemSession(USERNAME);
         mailboxManager.createMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
         MessageManager messageManager = mailboxManager.getMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
-        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession);
+        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getIds();
         mail.setAttribute(messageIdAttribute(messageId.getMessageId().serialize()));
         mail.setAttribute(USERNAME_ATTRIBUTE);
 
@@ -139,7 +139,7 @@ public class PostDequeueDecoratorTest {
         mailboxManager.createMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
         mailboxManager.createMailbox(SENT_MAILBOX_PATH, mailboxSession);
         MessageManager messageManager = mailboxManager.getMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
-        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession);
+        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getIds();
         mail.setAttribute(messageIdAttribute(messageId.getMessageId().serialize()));
         mail.setAttribute(USERNAME_ATTRIBUTE);
         
@@ -157,7 +157,7 @@ public class PostDequeueDecoratorTest {
         mailboxManager.createMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
         mailboxManager.createMailbox(SENT_MAILBOX_PATH, mailboxSession);
         MessageManager messageManager = mailboxManager.getMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
-        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession);
+        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getIds();
         mail.setAttribute(messageIdAttribute(messageId.getMessageId().serialize()));
         mail.setAttribute(USERNAME_ATTRIBUTE);
         
@@ -175,7 +175,7 @@ public class PostDequeueDecoratorTest {
         mailboxManager.createMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
         mailboxManager.createMailbox(SENT_MAILBOX_PATH, mailboxSession);
         MessageManager messageManager = mailboxManager.getMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
-        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession);
+        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getIds();
         mail.setAttribute(messageIdAttribute(messageId.getMessageId().serialize()));
         mail.setAttribute(USERNAME_ATTRIBUTE);
         
@@ -209,7 +209,7 @@ public class PostDequeueDecoratorTest {
         mailboxManager.createMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
         mailboxManager.createMailbox(SENT_MAILBOX_PATH, mailboxSession);
         MessageManager messageManager = mailboxManager.getMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
-        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession);
+        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getIds();
         mail.setAttribute(messageIdAttribute(messageId.getMessageId().serialize()));
         
         testee.done(true);
@@ -265,7 +265,7 @@ public class PostDequeueDecoratorTest {
         mailboxManager.createMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
         MailboxId sentMailboxId = mailboxManager.createMailbox(SENT_MAILBOX_PATH, mailboxSession).get();
         MessageManager messageManager = mailboxManager.getMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
-        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession);
+        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getIds();
         mail.setAttribute(messageIdAttribute(messageId.getMessageId().serialize()));
         mail.setAttribute(USERNAME_ATTRIBUTE);
 
@@ -293,7 +293,7 @@ public class PostDequeueDecoratorTest {
         mailboxManager.createMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
         mailboxManager.createMailbox(SENT_MAILBOX_PATH, mailboxSession).get();
         MessageManager messageManager = mailboxManager.getMailbox(OUTBOX_MAILBOX_PATH, mailboxSession);
-        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession);
+        ComposedMessageId messageId = messageManager.appendMessage(AppendCommand.from(message), mailboxSession).getIds();
         mail.setAttribute(messageIdAttribute(messageId.getMessageId().serialize()));
         mail.setAttribute(USERNAME_ATTRIBUTE);
 
diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/event/ComputeMessageFastViewProjectionListenerTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/event/ComputeMessageFastViewProjectionListenerTest.java
index 5a22e2d..ce2c2a8 100644
--- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/event/ComputeMessageFastViewProjectionListenerTest.java
+++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/event/ComputeMessageFastViewProjectionListenerTest.java
@@ -162,7 +162,7 @@ class ComputeMessageFastViewProjectionListenerTest {
         ComposedMessageId composedId = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(previewMessage()),
-            mailboxSession);
+            mailboxSession).getIds();
 
         assertThat(Mono.from(messageFastViewProjection.retrieve(composedId.getMessageId())).block())
             .isEqualTo(PRECOMPUTED_PROPERTIES_PREVIEW);
@@ -173,7 +173,7 @@ class ComputeMessageFastViewProjectionListenerTest {
         ComposedMessageId composedId = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(emptyMessage()),
-            mailboxSession);
+            mailboxSession).getIds();
 
         assertThat(Mono.from(messageFastViewProjection.retrieve(composedId.getMessageId())).block())
             .isEqualTo(PRECOMPUTED_PROPERTIES_EMPTY);
@@ -184,7 +184,7 @@ class ComputeMessageFastViewProjectionListenerTest {
         ComposedMessageId composedId = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(ClassLoaderUtils.getSystemResourceAsSharedStream("fullMessage.eml")),
-            mailboxSession);
+            mailboxSession).getIds();
 
         assertThat(Mono.from(messageFastViewProjection.retrieve(composedId.getMessageId())).block())
             .isEqualTo(PRECOMPUTED_PROPERTIES_PREVIEW_HAS_ATTACHMENT);
@@ -195,7 +195,7 @@ class ComputeMessageFastViewProjectionListenerTest {
         ComposedMessageId composedId = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(ClassLoaderUtils.getSystemResourceAsSharedStream("emptyBodyMessageWithOneAttachment.eml")),
-            mailboxSession);
+            mailboxSession).getIds();
 
         assertThat(Mono.from(messageFastViewProjection.retrieve(composedId.getMessageId())).block())
             .isEqualTo(PRECOMPUTED_PROPERTIES_HAS_ATTACHMENT);
@@ -206,12 +206,12 @@ class ComputeMessageFastViewProjectionListenerTest {
         ComposedMessageId composedId1 = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(previewMessage()),
-            mailboxSession);
+            mailboxSession).getIds();
 
         ComposedMessageId composedId2 = inboxMessageManager.appendMessage(
             MessageManager.AppendCommand.builder()
                 .build(emptyMessage()),
-            mailboxSession);
+            mailboxSession).getIds();
 
         SoftAssertions.assertSoftly(softly -> {
             softly.assertThat(Mono.from(messageFastViewProjection.retrieve(composedId1.getMessageId())).block())
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java
index ef1e5e6..c58245b 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeAllFastViewProjectionItemsRequestToTaskTest.java
@@ -304,7 +304,7 @@ class RecomputeAllFastViewProjectionItemsRequestToTaskTest {
         Optional<MailboxId> mailboxId = mailboxManager.createMailbox(MailboxPath.inbox(BOB), session);
         ComposedMessageId messageId = mailboxManager.getMailbox(mailboxId.get(), session).appendMessage(
             MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-            session);
+            session).getIds();
 
         String taskId = with()
             .queryParam("action", "recomputeFastViewProjectionItems")
@@ -327,7 +327,7 @@ class RecomputeAllFastViewProjectionItemsRequestToTaskTest {
         Optional<MailboxId> mailboxId = mailboxManager.createMailbox(MailboxPath.inbox(BOB), session);
         ComposedMessageId messageId = mailboxManager.getMailbox(mailboxId.get(), session).appendMessage(
             MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-            session);
+            session).getIds();
 
         String taskId1 = with()
             .queryParam("action", "recomputeFastViewProjectionItems")
diff --git a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTaskTest.java b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTaskTest.java
index 807d799..866cc7a 100644
--- a/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTaskTest.java
+++ b/server/protocols/webadmin/webadmin-jmap/src/test/java/org/apache/james/webadmin/data/jmap/RecomputeUserFastViewProjectionItemsRequestToTaskTest.java
@@ -372,7 +372,7 @@ class RecomputeUserFastViewProjectionItemsRequestToTaskTest {
     void recomputeUserShouldUpdateProjection() throws Exception {
         ComposedMessageId messageId = mailboxManager.getMailbox(bobInboxboxId, bobSession).appendMessage(
             MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-            bobSession);
+            bobSession).getIds();
 
         String taskId = with()
             .queryParam("action", "recomputeFastViewProjectionItems")
@@ -392,7 +392,7 @@ class RecomputeUserFastViewProjectionItemsRequestToTaskTest {
     void recomputeUserShouldBeIdempotent() throws Exception {
         ComposedMessageId messageId = mailboxManager.getMailbox(bobInboxboxId, bobSession).appendMessage(
             MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-            bobSession);
+            bobSession).getIds();
 
         String taskId1 = with()
             .queryParam("action", "recomputeFastViewProjectionItems")
diff --git a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/RestoreService.java b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/RestoreService.java
index 7f2c6a5..3331980 100644
--- a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/RestoreService.java
+++ b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/RestoreService.java
@@ -80,7 +80,7 @@ class RestoreService {
     private Mono<RestoreResult> appendToMailbox(MessageManager restoreMailboxManager, DeletedMessage deletedMessage, MailboxSession session) {
         return appendCommand(deletedMessage)
             .map(Throwing.<AppendCommand, ComposedMessageId>function(
-                appendCommand -> restoreMailboxManager.appendMessage(appendCommand, session)).sneakyThrow())
+                appendCommand -> restoreMailboxManager.appendMessage(appendCommand, session).getIds()).sneakyThrow())
             .map(any -> RESTORE_SUCCEED)
             .onErrorResume(throwable -> {
                 LOGGER.error("append message {} to restore mailbox of user {} didn't success",
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MailboxesRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MailboxesRoutesTest.java
index 50da3b0..cba4c7a 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MailboxesRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MailboxesRoutesTest.java
@@ -207,7 +207,7 @@ class MailboxesRoutesTest {
                 ComposedMessageId composedMessageId = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession);
+                        systemSession).getIds();
 
                 doThrow(new RuntimeException())
                     .when(searchIndex)
@@ -244,7 +244,7 @@ class MailboxesRoutesTest {
                 ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession);
+                        systemSession).getIds();
 
                 String taskId = with()
                     .post("/mailboxes?task=reIndex")
@@ -395,7 +395,7 @@ class MailboxesRoutesTest {
                 ComposedMessageId composedMessageId = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession);
+                        systemSession).getIds();
 
                 doThrow(new RuntimeException())
                     .when(searchIndex)
@@ -433,7 +433,7 @@ class MailboxesRoutesTest {
                 ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession);
+                        systemSession).getIds();
 
                 String taskId = when()
                     .post("/mailboxes/" + mailboxId.serialize() + "?task=reIndex")
@@ -566,7 +566,7 @@ class MailboxesRoutesTest {
                 ComposedMessageId composedMessageId = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession);
+                        systemSession).getIds();
 
                 String taskId = when()
                     .post("/mailboxes/" + mailboxId.serialize() + "/mails/"
@@ -599,7 +599,7 @@ class MailboxesRoutesTest {
                 ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession);
+                        systemSession).getIds();
 
                 String taskId = when()
                     .post("/mailboxes/" + mailboxId.serialize() + "/mails/"
@@ -781,7 +781,7 @@ class MailboxesRoutesTest {
                 ComposedMessageId composedMessageId = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession);
+                        systemSession).getIds();
 
                 doThrow(new RuntimeException())
                     .when(searchIndex)
@@ -829,7 +829,7 @@ class MailboxesRoutesTest {
                 ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession);
+                        systemSession).getIds();
 
                 doThrow(new RuntimeException()).when(searchIndex).add(any(MailboxSession.class), any(Mailbox.class), any(MailboxMessage.class));
 
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MessageRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MessageRoutesTest.java
index 46ef7e6..4ac0ccd 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MessageRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/MessageRoutesTest.java
@@ -166,7 +166,7 @@ class MessageRoutesTest {
                 ComposedMessageId composedMessageId = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession);
+                        systemSession).getIds();
 
                 String taskId = when()
                     .post("/messages/" + composedMessageId.getMessageId().serialize() + "?task=reIndex")
@@ -197,7 +197,7 @@ class MessageRoutesTest {
                 ComposedMessageId composedMessageId = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession);
+                        systemSession).getIds();
 
                 String taskId = when()
                     .post("/messages/" + composedMessageId.getMessageId().serialize() + "?task=reIndex")
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java
index 6f52c47..4cc023f 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java
@@ -1159,7 +1159,7 @@ class UserMailboxesRoutesTest {
                 ComposedMessageId composedMessageId = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession);
+                        systemSession).getIds();
 
                 doThrow(new RuntimeException())
                     .when(searchIndex)
@@ -1197,7 +1197,7 @@ class UserMailboxesRoutesTest {
                 ComposedMessageId createdMessage = mailboxManager.getMailbox(INBOX, systemSession)
                     .appendMessage(
                         MessageManager.AppendCommand.builder().build("header: value\r\n\r\nbody"),
-                        systemSession);
+                        systemSession).getIds();
 
                 String taskId = given()
                     .queryParam("task", "reIndex")
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/ExportServiceTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/ExportServiceTest.java
index ea86287..e21fc07 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/ExportServiceTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/ExportServiceTest.java
@@ -115,7 +115,8 @@ class ExportServiceTest {
         return testSystem.mailboxManager.getMailbox(bobInboxPath, testSystem.bobSession)
             .appendMessage(MessageManager.AppendCommand.builder()
                     .build(message),
-                testSystem.bobSession);
+                testSystem.bobSession)
+            .getIds();
     }
 
     @Test
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/MailboxesExportRequestToTaskTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/MailboxesExportRequestToTaskTest.java
index 949bd4a..9dfe1e5 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/MailboxesExportRequestToTaskTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/service/MailboxesExportRequestToTaskTest.java
@@ -348,7 +348,7 @@ class MailboxesExportRequestToTaskTest {
 
         ComposedMessageId id = testSystem.mailboxManager.getMailbox(bobInboxboxId, testSystem.bobSession).appendMessage(
             MessageManager.AppendCommand.builder().build(MESSAGE_CONTENT),
-            testSystem.bobSession);
+            testSystem.bobSession).getIds();
 
         String taskId = with()
             .queryParam("action", "export")
@@ -375,7 +375,7 @@ class MailboxesExportRequestToTaskTest {
 
         ComposedMessageId id = testSystem.mailboxManager.getMailbox(bobInboxboxId, testSystem.bobSession).appendMessage(
             MessageManager.AppendCommand.builder().build(MESSAGE_CONTENT),
-            testSystem.bobSession);
+            testSystem.bobSession).getIds();
 
         testSystem.usersRepository.addUser(CEDRIC, PASSWORD);
         MailboxSession cedricSession = testSystem.mailboxManager.createSystemSession(CEDRIC);


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


[james-project] 14/37: JAMES-2997 step #12 Attachment builder should require attachmentId

Posted by bt...@apache.org.
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 0f4142ef954c39cbed61e2cb5c29514fc1f24f2c
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Jan 17 16:14:49 2020 +0700

    JAMES-2997 step #12 Attachment builder should require attachmentId
    
    It should not be set implicitly
---
 .../org/apache/james/mailbox/model/Attachment.java   | 20 ++++++--------------
 .../james/mailbox/model/MessageAttachmentTest.java   |  6 ++++++
 ...ElasticSearchListeningMessageSearchIndexTest.java |  2 ++
 .../james/vault/DeletedMessageConverterTest.java     |  2 ++
 .../mail/model/impl/SimpleMailboxMessageTest.java    |  2 ++
 5 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
index 934d044..6e36f8c 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/Attachment.java
@@ -25,12 +25,7 @@ import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 
 public class Attachment {
-    public static Builder builder() {
-        return new Builder();
-    }
-
     public static class Builder {
-
         private AttachmentId attachmentId;
         private Long size;
         private String type;
@@ -56,19 +51,16 @@ public class Attachment {
         public Attachment build() {
             Preconditions.checkState(type != null, "'type' is mandatory");
             Preconditions.checkState(size != null, "'size' is mandatory");
-            AttachmentId builtAttachmentId = attachmentId();
-            Preconditions.checkState(builtAttachmentId != null, "'attachmentId' is mandatory");
-            return new Attachment(builtAttachmentId, type, size);
-        }
+            Preconditions.checkState(attachmentId != null, "'attachmentId' is mandatory");
 
-        private AttachmentId attachmentId() {
-            if (attachmentId != null) {
-                return attachmentId;
-            }
-            return AttachmentId.random();
+            return new Attachment(attachmentId, type, size);
         }
     }
 
+    public static Builder builder() {
+        return new Builder();
+    }
+
     private final AttachmentId attachmentId;
     private final String type;
     private final long size;
diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageAttachmentTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageAttachmentTest.java
index d501c30..638985a 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageAttachmentTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/MessageAttachmentTest.java
@@ -45,6 +45,7 @@ class MessageAttachmentTest {
     @Test
     void buildShouldWorkWhenMandatoryAttributesAreGiven() {
         Attachment attachment = Attachment.builder()
+            .attachmentId(AttachmentId.from("1"))
             .size(36)
             .type("type")
             .build();
@@ -60,6 +61,7 @@ class MessageAttachmentTest {
     @Test
     void buildShouldAcceptIsInlineAndNoCid() {
         Attachment attachment = Attachment.builder()
+            .attachmentId(AttachmentId.from("1"))
             .size(36)
             .type("type")
             .build();
@@ -75,6 +77,7 @@ class MessageAttachmentTest {
     @Test
     void buildShouldSetAttributesWhenAllAreGiven() {
         Attachment attachment = Attachment.builder()
+            .attachmentId(AttachmentId.from("1"))
             .size(36)
             .type("type")
             .build();
@@ -93,6 +96,7 @@ class MessageAttachmentTest {
     @Test
     void isInlinedWithCidShouldReturnTrueWhenIsInlineAndHasCid() throws Exception {
         Attachment attachment = Attachment.builder()
+            .attachmentId(AttachmentId.from("1"))
             .size(36)
             .type("type")
             .build();
@@ -110,6 +114,7 @@ class MessageAttachmentTest {
     @Test
     void isInlinedWithCidShouldReturnFalseWhenIsNotInline() throws Exception {
         Attachment attachment = Attachment.builder()
+            .attachmentId(AttachmentId.from("1"))
             .size(36)
             .type("type")
             .build();
@@ -127,6 +132,7 @@ class MessageAttachmentTest {
     @Test
     void isInlinedWithCidShouldReturnFalseWhenIsInlineButNoCid() throws Exception {
         Attachment attachment = Attachment.builder()
+            .attachmentId(AttachmentId.from("1"))
             .size(36)
             .type("type")
             .build();
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
index 73a6b0c..d01eb29 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
@@ -56,6 +56,7 @@ import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
 import org.apache.james.mailbox.manager.ManagerTestProvisionner;
 import org.apache.james.mailbox.model.Attachment;
+import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.Mailbox;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageAttachment;
@@ -114,6 +115,7 @@ class ElasticSearchListeningMessageSearchIndexTest {
 
     static final MessageAttachment MESSAGE_ATTACHMENT = MessageAttachment.builder()
         .attachment(Attachment.builder()
+            .attachmentId(AttachmentId.from("1"))
             .type("type")
             .size(523)
             .build())
diff --git a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageConverterTest.java b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageConverterTest.java
index eeb6a1c..57d5b5d 100644
--- a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageConverterTest.java
+++ b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/DeletedMessageConverterTest.java
@@ -42,6 +42,7 @@ import java.util.List;
 import org.apache.james.core.MaybeSender;
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.model.Attachment;
+import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.store.MessageBuilder;
@@ -72,6 +73,7 @@ class DeletedMessageConverterTest {
     private static final Collection<MessageAttachment> NO_ATTACHMENT = ImmutableList.of();
     private static final Collection<MessageAttachment> ATTACHMENTS = ImmutableList.of(MessageAttachment.builder()
         .attachment(Attachment.builder()
+            .attachmentId(AttachmentId.from("1"))
             .type("type")
             .size(48)
             .build())
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessageTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessageTest.java
index 0e13f97..c1f5d9e 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessageTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessageTest.java
@@ -36,6 +36,7 @@ import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.model.Attachment;
+import org.apache.james.mailbox.model.AttachmentId;
 import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.TestId;
@@ -177,6 +178,7 @@ class SimpleMailboxMessageTest {
         MessageUid uid = MessageUid.of(45);
         MessageAttachment messageAttachment = MessageAttachment.builder()
             .attachment(Attachment.builder()
+                .attachmentId(AttachmentId.from("1"))
                 .type("type")
                 .size(485)
                 .build())


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


[james-project] 20/37: JAMES-2997 Renable BlobTest AbstractMailboxManagerAttachmentTest

Posted by bt...@apache.org.
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 09c2ebb5037abdec25b7fb5dd33891395239b2f5
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Jan 20 10:22:50 2020 +0700

    JAMES-2997 Renable BlobTest AbstractMailboxManagerAttachmentTest
---
 .../cassandra/mail/CassandraMailboxManagerAttachmentTest.java    | 3 ---
 .../inmemory/mail/InMemoryMailboxManagerAttachmentTest.java      | 3 ---
 .../mailbox/store/AbstractMailboxManagerAttachmentTest.java      | 9 ++++-----
 3 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java
index 2e4821e..9ea857c 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxManagerAttachmentTest.java
@@ -56,7 +56,6 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
 class CassandraMailboxManagerAttachmentTest extends AbstractMailboxManagerAttachmentTest {
-/*
     @RegisterExtension
     static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(MailboxAggregateModule.MODULE);
 
@@ -117,6 +116,4 @@ class CassandraMailboxManagerAttachmentTest extends AbstractMailboxManagerAttach
     protected AttachmentMapperFactory getAttachmentMapperFactory() {
         return mailboxSessionMapperFactory;
     }
-
- */
 }
diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxManagerAttachmentTest.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxManagerAttachmentTest.java
index dcf5c69..0ea7f7b 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxManagerAttachmentTest.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxManagerAttachmentTest.java
@@ -35,7 +35,6 @@ import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
 import org.junit.jupiter.api.BeforeEach;
 
 class InMemoryMailboxManagerAttachmentTest extends AbstractMailboxManagerAttachmentTest {
-/*
     InMemoryMailboxManager mailboxManager;
     InMemoryMailboxManager parseFailingMailboxManager;
 
@@ -80,6 +79,4 @@ class InMemoryMailboxManagerAttachmentTest extends AbstractMailboxManagerAttachm
     protected AttachmentMapperFactory getAttachmentMapperFactory() {
         return (AttachmentMapperFactory) mailboxManager.getMapperFactory();
     }
-
- */
 }
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
index a6c864d..ea6bef1 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
@@ -51,7 +51,6 @@ import com.github.fge.lambdas.Throwing;
 import com.google.common.collect.ImmutableList;
 
 public abstract class AbstractMailboxManagerAttachmentTest {
-/*
     private static final Username USERNAME = Username.of("user@domain.tld");
 
     private MailboxManager mailboxManager;
@@ -130,7 +129,7 @@ public abstract class AbstractMailboxManagerAttachmentTest {
         assertThat(messages.hasNext()).isTrue();
         List<MessageAttachment> attachments = messages.next().getAttachments();
         assertThat(attachments).hasSize(1);
-        assertThat(attachmentMapper.getAttachment(attachments.get(0).getAttachmentId()).getStream())
+        assertThat(attachmentMapper.loadAttachmentContent(attachments.get(0).getAttachmentId()))
             .hasSameContentAs(ClassLoader.getSystemResourceAsStream("eml/gimp.png"));
     }
 
@@ -161,7 +160,9 @@ public abstract class AbstractMailboxManagerAttachmentTest {
             .stream()
             .map(MessageAttachment::getAttachmentId)
             .map(Throwing.function(attachmentMapper::getAttachment))
-            .map(Attachment::getBytes)
+            .map(Attachment::getAttachmentId)
+            .map(Throwing.function(attachmentMapper::loadAttachmentContent))
+            .map(Throwing.function(IOUtils::toByteArray))
             .collect(ImmutableList.toImmutableList());
 
         ImmutableList<byte[]> files = Stream.of("eml/4037_014.jpg", "eml/4037_015.jpg")
@@ -199,7 +200,5 @@ public abstract class AbstractMailboxManagerAttachmentTest {
         List<MessageAttachment> attachments = messages.next().getAttachments();
         assertThat(attachments).hasSize(0);
     }
-
- */
 }
 


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