You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by rc...@apache.org on 2023/06/13 02:54:52 UTC
[james-project] 02/02: JAMES-3911 JPA: Prevent concurrent operations on the same EntityManager
This is an automated email from the ASF dual-hosted git repository.
rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 25db4645440f6e50c4b471a414e11cff6dcf9c1b
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Jun 9 18:41:57 2023 +0700
JAMES-3911 JPA: Prevent concurrent operations on the same EntityManager
---
.../mailbox/jpa/openjpa/OpenJPAMessageManager.java | 37 +++++++++++++++++++++-
.../james/mailbox/store/StoreMailboxManager.java | 2 +-
.../james/mailbox/store/StoreMessageManager.java | 10 +++---
3 files changed, 42 insertions(+), 7 deletions(-)
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 567e8d5ac6..7226fb046a 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
@@ -20,14 +20,18 @@
package org.apache.james.mailbox.jpa.openjpa;
import java.time.Clock;
+import java.util.EnumSet;
import javax.mail.Flags;
import org.apache.james.events.EventBus;
import org.apache.james.mailbox.MailboxPathLocker;
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.MailboxACL;
import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.UidValidity;
import org.apache.james.mailbox.quota.QuotaManager;
import org.apache.james.mailbox.quota.QuotaRootResolver;
import org.apache.james.mailbox.store.BatchSizes;
@@ -37,23 +41,35 @@ 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.MessageMapper;
import org.apache.james.mailbox.store.mail.ThreadIdGuessingAlgorithm;
import org.apache.james.mailbox.store.search.MessageSearchIndex;
+import com.github.fge.lambdas.Throwing;
+
+import reactor.core.publisher.Mono;
+
/**
* OpenJPA implementation of Mailbox
*/
public class OpenJPAMessageManager extends StoreMessageManager {
+ private final MailboxSessionMapperFactory mapperFactory;
+ private final StoreRightManager storeRightManager;
+ private final Mailbox mailbox;
public OpenJPAMessageManager(MailboxSessionMapperFactory mapperFactory,
MessageSearchIndex index, EventBus eventBus,
MailboxPathLocker locker, Mailbox mailbox,
QuotaManager quotaManager, QuotaRootResolver quotaRootResolver,
MessageId.Factory messageIdFactory, BatchSizes batchSizes,
- StoreRightManager storeRightManager, ThreadIdGuessingAlgorithm threadIdGuessingAlgorithm, Clock clock) {
+ StoreRightManager storeRightManager, ThreadIdGuessingAlgorithm threadIdGuessingAlgorithm,
+ Clock clock) {
super(StoreMailboxManager.DEFAULT_NO_MESSAGE_CAPABILITIES, mapperFactory, index, eventBus, locker, mailbox,
quotaManager, quotaRootResolver, batchSizes, storeRightManager, PreDeletionHooks.NO_PRE_DELETION_HOOK,
new MessageStorer.WithoutAttachment(mapperFactory, messageIdFactory, new OpenJPAMessageFactory(OpenJPAMessageFactory.AdvancedFeature.None), threadIdGuessingAlgorithm, clock));
+ this.storeRightManager = storeRightManager;
+ this.mapperFactory = mapperFactory;
+ this.mailbox = mailbox;
}
/**
@@ -65,4 +81,23 @@ public class OpenJPAMessageManager extends StoreMessageManager {
flags.add(Flags.Flag.USER);
return flags;
}
+
+ public Mono<MailboxMetaData> getMetaDataReactive(MailboxMetaData.RecentMode recentMode, MailboxSession mailboxSession, EnumSet<MailboxMetaData.Item> items) throws MailboxException {
+ MailboxACL resolvedAcl = getResolvedAcl(mailboxSession);
+ if (!storeRightManager.hasRight(mailbox, MailboxACL.Right.Read, mailboxSession)) {
+ return Mono.just(MailboxMetaData.sensibleInformationFree(resolvedAcl, getMailboxEntity().getUidValidity(), isWriteable(mailboxSession)));
+ }
+ Flags permanentFlags = getPermanentFlags(mailboxSession);
+ UidValidity uidValidity = getMailboxEntity().getUidValidity();
+ MessageMapper messageMapper = mapperFactory.getMessageMapper(mailboxSession);
+
+ return messageMapper.executeReactive(
+ nextUid(messageMapper, items)
+ .flatMap(nextUid -> highestModSeq(messageMapper, items)
+ .flatMap(highestModSeq -> firstUnseen(messageMapper, items)
+ .flatMap(Throwing.function(firstUnseen -> recent(recentMode, mailboxSession)
+ .flatMap(recents -> mailboxCounters(messageMapper, items)
+ .map(counters -> new MailboxMetaData(recents, permanentFlags, uidValidity, nextUid, highestModSeq, counters.getCount(),
+ counters.getUnseen(), firstUnseen.orElse(null), isWriteable(mailboxSession), resolvedAcl))))))));
+ }
}
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 5c530d907f..e1d272c5f8 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
@@ -658,7 +658,7 @@ public class StoreMailboxManager implements MailboxManager {
return mailboxId;
})
.then(Mono.from(locker.executeReactiveWithLockReactive(from, mapper.findMailboxWithPathLike(query)
- .flatMap(sub -> {
+ .concatMap(sub -> {
String subOriginalName = sub.getName();
String subNewName = newMailboxPath.getName() + subOriginalName.substring(from.getName().length());
MailboxPath fromPath = new MailboxPath(from, subOriginalName);
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 8ef76f2931..a5fe322689 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
@@ -594,14 +594,14 @@ public class StoreMessageManager implements MessageManager {
t5.getT4().getUnseen(), t5.getT3().orElse(null), isWriteable(mailboxSession), resolvedAcl)));
}
- private Mono<ModSeq> highestModSeq(MessageMapper messageMapper, EnumSet<MailboxMetaData.Item> items) {
+ protected Mono<ModSeq> highestModSeq(MessageMapper messageMapper, EnumSet<MailboxMetaData.Item> items) {
if (items.contains(MailboxMetaData.Item.HighestModSeq)) {
return messageMapper.getHighestModSeqReactive(mailbox);
}
return Mono.just(ModSeq.first());
}
- private Mono<MessageUid> nextUid(MessageMapper messageMapper, EnumSet<MailboxMetaData.Item> items) {
+ protected Mono<MessageUid> nextUid(MessageMapper messageMapper, EnumSet<MailboxMetaData.Item> items) {
if (items.contains(MailboxMetaData.Item.NextUid)) {
return messageMapper.getLastUidReactive(mailbox)
.map(optional -> optional
@@ -611,14 +611,14 @@ public class StoreMessageManager implements MessageManager {
return Mono.just(MessageUid.MIN_VALUE);
}
- private Mono<Optional<MessageUid>> firstUnseen(MessageMapper messageMapper, EnumSet<MailboxMetaData.Item> items) {
+ protected Mono<Optional<MessageUid>> firstUnseen(MessageMapper messageMapper, EnumSet<MailboxMetaData.Item> items) {
if (items.contains(MailboxMetaData.Item.FirstUnseen)) {
return messageMapper.findFirstUnseenMessageUidReactive(getMailboxEntity());
}
return Mono.just(Optional.empty());
}
- private Mono<MailboxCounters> mailboxCounters(MessageMapper messageMapper, EnumSet<MailboxMetaData.Item> items) {
+ protected Mono<MailboxCounters> mailboxCounters(MessageMapper messageMapper, EnumSet<MailboxMetaData.Item> items) {
if (items.contains(MailboxMetaData.Item.MailboxCounters)) {
return messageMapper.getMailboxCountersReactive(getMailboxEntity());
}
@@ -777,7 +777,7 @@ public class StoreMessageManager implements MessageManager {
* Return a List which holds all uids of recent messages and optional reset
* the recent flag on the messages for the uids
*/
- private Mono<List<MessageUid>> recent(RecentMode recentMode, MailboxSession mailboxSession) throws MailboxException {
+ protected Mono<List<MessageUid>> recent(RecentMode recentMode, MailboxSession mailboxSession) throws MailboxException {
MessageMapper messageMapper = mapperFactory.getMessageMapper(mailboxSession);
switch (recentMode) {
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org