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 21b64687dda36b15e800d3a125f8d9075cbcdbab Author: quanth <hqt...@linagora.com> AuthorDate: Fri May 28 13:34:57 2021 +0700 JAMES-3516 Exposing AppendResult::getThreadId allow advertising the threadId as part of Email/set and Email/Import results --- .../org/apache/james/mailbox/MessageManager.java | 15 ++++++++-- .../org/apache/james/mailbox/AppendResultTest.java | 32 ++++++++++++++++++++++ .../james/mailbox/store/StoreMessageManager.java | 2 +- .../james/jmap/json/EmailSetSerializer.scala | 4 +-- .../scala/org/apache/james/jmap/mail/Email.scala | 6 +++- .../org/apache/james/jmap/mail/EmailSet.scala | 2 +- .../james/jmap/method/EmailImportMethod.scala | 5 ++-- .../jmap/method/EmailSetCreatePerformer.scala | 5 ++-- 8 files changed, 59 insertions(+), 12 deletions(-) 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 6e23e26..e214865 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 @@ -53,6 +53,7 @@ import org.apache.james.mailbox.model.MessageRange; import org.apache.james.mailbox.model.MessageResult; import org.apache.james.mailbox.model.MessageResultIterator; import org.apache.james.mailbox.model.SearchQuery; +import org.apache.james.mailbox.model.ThreadId; import org.apache.james.mailbox.model.UidValidity; import org.apache.james.mime4j.dom.Message; import org.apache.james.mime4j.message.DefaultMessageWriter; @@ -152,11 +153,13 @@ public interface MessageManager { private final ComposedMessageId id; private final Long size; private final Optional<List<MessageAttachmentMetadata>> messageAttachments; + private final ThreadId threadId; - public AppendResult(ComposedMessageId id, Long size, Optional<List<MessageAttachmentMetadata>> messageAttachments) { + public AppendResult(ComposedMessageId id, Long size, Optional<List<MessageAttachmentMetadata>> messageAttachments, ThreadId threadId) { this.id = id; this.size = size; this.messageAttachments = messageAttachments; + this.threadId = threadId; } public ComposedMessageId getId() { @@ -172,20 +175,26 @@ public interface MessageManager { return messageAttachments.get(); } + public ThreadId getThreadId() { + return threadId; + } + @Override public final boolean equals(Object o) { if (o instanceof AppendResult) { AppendResult that = (AppendResult) o; return Objects.equals(this.id, that.id) - && Objects.equals(this.messageAttachments, that.messageAttachments); + && Objects.equals(this.messageAttachments, that.messageAttachments) + && Objects.equals(this.size, that.size) + && Objects.equals(this.threadId, that.threadId); } return false; } @Override public final int hashCode() { - return Objects.hash(id, messageAttachments); + return Objects.hash(id, messageAttachments, size, threadId); } } diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/AppendResultTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/AppendResultTest.java new file mode 100644 index 0000000..be1d939 --- /dev/null +++ b/mailbox/api/src/test/java/org/apache/james/mailbox/AppendResultTest.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.mailbox; + +import org.junit.jupiter.api.Test; + +import nl.jqno.equalsverifier.EqualsVerifier; + +public class AppendResultTest { + @Test + void shouldMatchBeanContract() { + EqualsVerifier.forClass(MessageManager.AppendResult.class) + .verify(); + } +} 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 ab62237..60d7a5a 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 @@ -511,7 +511,7 @@ public class StoreMessageManager implements MessageManager { private AppendResult computeAppendResult(Pair<MessageMetaData, Optional<List<MessageAttachmentMetadata>>> data, Mailbox mailbox) { MessageMetaData messageMetaData = data.getLeft(); ComposedMessageId ids = new ComposedMessageId(mailbox.getMailboxId(), messageMetaData.getMessageId(), messageMetaData.getUid()); - return new AppendResult(ids, messageMetaData.getSize(), data.getRight()); + return new AppendResult(ids, messageMetaData.getSize(), data.getRight(), messageMetaData.getThreadId()); } private PropertyBuilder getPropertyBuilder(MaximalBodyDescriptor descriptor, String mediaType, String subType) { diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/EmailSetSerializer.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/EmailSetSerializer.scala index 41c206e..fcd8ab6 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/EmailSetSerializer.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/EmailSetSerializer.scala @@ -28,8 +28,7 @@ import javax.inject.Inject import org.apache.james.jmap.core.Id.IdConstraint import org.apache.james.jmap.core.{Id, SetError, UTCDate, UuidState} import org.apache.james.jmap.mail.KeywordsFactory.STRICT_KEYWORDS_FACTORY -import org.apache.james.jmap.mail.{AddressesHeaderValue, AsAddresses, AsDate, AsGroupedAddresses, AsMessageIds, AsRaw, AsText, AsURLs, Attachment, BlobId, Charset, ClientBody, ClientCid, ClientEmailBodyValue, ClientPartId, DateHeaderValue, DestroyIds, Disposition, EmailAddress, EmailAddressGroup, EmailCreationId, EmailCreationRequest, EmailCreationResponse, EmailHeader, EmailHeaderName, EmailHeaderValue, EmailSetRequest, EmailSetResponse, EmailSetUpdate, EmailerName, GroupName, GroupedAd [...] -import org.apache.james.jmap.mail.{AddressesHeaderValue, AsAddresses, AsDate, AsGroupedAddresses, AsMessageIds, AsRaw, AsText, AsURLs, Attachment, BlobId, Charset, ClientBody, ClientCid, ClientEmailBodyValue, ClientPartId, DateHeaderValue, DestroyIds, Disposition, EmailAddress, EmailAddressGroup, EmailCreationRequest, EmailCreationResponse, EmailHeader, EmailHeaderName, EmailHeaderValue, EmailImport, EmailImportRequest, EmailImportResponse, EmailSetRequest, EmailSetResponse, EmailSetUpda [...] +import org.apache.james.jmap.mail.{AddressesHeaderValue, AsAddresses, AsDate, AsGroupedAddresses, AsMessageIds, AsRaw, AsText, AsURLs, Attachment, BlobId, Charset, ClientBody, ClientCid, ClientEmailBodyValue, ClientPartId, DateHeaderValue, DestroyIds, Disposition, EmailAddress, EmailAddressGroup, EmailCreationId, EmailCreationRequest, EmailCreationResponse, EmailHeader, EmailHeaderName, EmailHeaderValue, EmailImport, EmailImportRequest, EmailImportResponse, EmailSetRequest, EmailSetRespo [...] import org.apache.james.mailbox.model.{MailboxId, MessageId} import play.api.libs.json.{Format, JsArray, JsBoolean, JsError, JsNull, JsObject, JsResult, JsString, JsSuccess, JsValue, Json, OWrites, Reads, Writes} @@ -229,6 +228,7 @@ class EmailSetSerializer @Inject()(messageIdFactory: MessageId.Factory, mailboxI private implicit val destroyIdsReads: Reads[DestroyIds] = Json.valueFormat[DestroyIds] private implicit val destroyIdsWrites: Writes[DestroyIds] = Json.valueWrites[DestroyIds] private implicit val emailRequestSetReads: Reads[EmailSetRequest] = Json.reads[EmailSetRequest] + private implicit val threadIdWrites: Writes[ThreadId] = Json.valueWrites[ThreadId] private implicit val emailCreationResponseWrites: Writes[EmailCreationResponse] = Json.writes[EmailCreationResponse] private implicit val createsMapWrites: Writes[Map[EmailCreationId, EmailCreationResponse]] = mapWrites[EmailCreationId, EmailCreationResponse](_.id.value, emailCreationResponseWrites) diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Email.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Email.scala index 6699876..db66bfa 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Email.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Email.scala @@ -36,7 +36,7 @@ import org.apache.james.jmap.mail.EmailHeaderName.{ADDRESSES_NAMES, DATE, MESSAG import org.apache.james.jmap.mail.KeywordsFactory.LENIENT_KEYWORDS_FACTORY import org.apache.james.jmap.method.ZoneIdProvider import org.apache.james.mailbox.model.FetchGroup.{FULL_CONTENT, HEADERS, MINIMAL} -import org.apache.james.mailbox.model.{FetchGroup, MailboxId, MessageId, MessageResult} +import org.apache.james.mailbox.model.{FetchGroup, MailboxId, MessageId, MessageResult, ThreadId => JavaThreadId} import org.apache.james.mailbox.{MailboxSession, MessageIdManager} import org.apache.james.mime4j.codec.DecodeMonitor import org.apache.james.mime4j.dom.field.{AddressListField, DateTimeField, MailboxField, MailboxListField} @@ -233,6 +233,10 @@ case class MailboxIds(value: List[MailboxId]) { def --(ids: MailboxIds) = MailboxIds((value.toSet -- ids.value.toSet).toList) } +object ThreadId { + def fromJava(threadId: JavaThreadId): ThreadId = ThreadId(threadId.serialize) +} + case class ThreadId(value: String) extends AnyVal case class HasAttachment(value: Boolean) extends AnyVal diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailSet.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailSet.scala index d6a88e4..ef69a2c 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailSet.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailSet.scala @@ -398,5 +398,5 @@ case class InvalidEmailPropertyException(property: String, cause: String) extend case class InvalidEmailUpdateException(property: String, cause: String) extends EmailUpdateValidationException -case class EmailCreationResponse(id: MessageId, blobId: Option[BlobId], threadId: Option[BlobId], size: Size) +case class EmailCreationResponse(id: MessageId, blobId: Option[BlobId], threadId: ThreadId, size: Size) diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailImportMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailImportMethod.scala index 8fa4ea2..5598083 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailImportMethod.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailImportMethod.scala @@ -30,7 +30,7 @@ import org.apache.james.jmap.core.Invocation.{Arguments, MethodName} import org.apache.james.jmap.core.SetError.SetErrorDescription import org.apache.james.jmap.core.{ClientId, Id, Invocation, ServerId, SetError, UuidState} import org.apache.james.jmap.json.{EmailSetSerializer, ResponseSerializer} -import org.apache.james.jmap.mail.{BlobId, Email, EmailCreationId, EmailCreationResponse, EmailImport, EmailImportRequest, EmailImportResponse, ValidatedEmailImport} +import org.apache.james.jmap.mail.{BlobId, Email, EmailCreationId, EmailCreationResponse, EmailImport, EmailImportRequest, EmailImportResponse, ThreadId, ValidatedEmailImport} import org.apache.james.jmap.method.EmailImportMethod.{ImportFailure, ImportResult, ImportResults, ImportSuccess, ImportWithBlob} import org.apache.james.jmap.routes.{Blob, BlobNotFoundException, BlobResolvers, ProcessingContext, SessionSupplier} import org.apache.james.mailbox.MessageManager.AppendCommand @@ -172,7 +172,8 @@ class EmailImportMethod @Inject() (val metricFactory: MetricFactory, private def asEmailCreationResponse(appendResult: MessageManager.AppendResult): EmailCreationResponse = { val blobId: Option[BlobId] = BlobId.of(appendResult.getId.getMessageId).toOption - EmailCreationResponse(appendResult.getId.getMessageId, blobId, blobId, Email.sanitizeSize(appendResult.getSize)) + val threadId: ThreadId = ThreadId.fromJava(appendResult.getThreadId) + EmailCreationResponse(appendResult.getId.getMessageId, blobId, threadId, Email.sanitizeSize(appendResult.getSize)) } private def retrieveState(capabilities: Set[CapabilityIdentifier], mailboxSession: MailboxSession): SMono[UuidState] = diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetCreatePerformer.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetCreatePerformer.scala index bd490e7..bc108af 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetCreatePerformer.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetCreatePerformer.scala @@ -28,7 +28,7 @@ import javax.mail.Flags import org.apache.james.jmap.core.SetError.SetErrorDescription import org.apache.james.jmap.core.{Properties, SetError, UTCDate} import org.apache.james.jmap.json.EmailSetSerializer -import org.apache.james.jmap.mail.{BlobId, Email, EmailCreationId, EmailCreationRequest, EmailCreationResponse, EmailSetRequest} +import org.apache.james.jmap.mail.{BlobId, Email, EmailCreationId, EmailCreationRequest, EmailCreationResponse, EmailSetRequest, ThreadId} import org.apache.james.jmap.method.EmailSetCreatePerformer.{CreationFailure, CreationResult, CreationResults, CreationSuccess} import org.apache.james.jmap.routes.{BlobNotFoundException, BlobResolvers} import org.apache.james.mailbox.MessageManager.AppendCommand @@ -103,7 +103,8 @@ class EmailSetCreatePerformer @Inject()(serializer: EmailSetSerializer, appendResult <- SMono(mailbox.appendMessageReactive(appendCommand, mailboxSession)) } yield { val blobId: Option[BlobId] = BlobId.of(appendResult.getId.getMessageId).toOption - CreationSuccess(clientId, EmailCreationResponse(appendResult.getId.getMessageId, blobId, blobId, Email.sanitizeSize(appendResult.getSize))) + val threadId: ThreadId = ThreadId.fromJava(appendResult.getThreadId) + CreationSuccess(clientId, EmailCreationResponse(appendResult.getId.getMessageId, blobId, threadId, Email.sanitizeSize(appendResult.getSize))) } } --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@james.apache.org For additional commands, e-mail: notifications-h...@james.apache.org