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 2021/05/17 02:21:47 UTC
[james-project] 04/11: [REFACTORING] Reactive
StoreMessageIdManager::validateQuota
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 4f5d8c43f4ae83a1847476dea698428b8d8788fd
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu May 13 15:39:52 2021 +0700
[REFACTORING] Reactive StoreMessageIdManager::validateQuota
This ensures using StoreMessageIdManager::setInMailboxesReactive do
not block for the purpose of quota validation for copy use cases.
---
.../james/mailbox/store/StoreMessageIdManager.java | 60 +++++++++++++---------
.../AbstractMessageIdManagerSideEffectTest.java | 22 ++++----
2 files changed, 49 insertions(+), 33 deletions(-)
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 a7fa33b..b1ac262 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
@@ -46,6 +46,7 @@ import org.apache.james.mailbox.RightManager;
import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.exception.MailboxNotFoundException;
+import org.apache.james.mailbox.exception.OverQuotaException;
import org.apache.james.mailbox.extension.PreDeletionHook;
import org.apache.james.mailbox.model.ComposedMessageIdWithMetaData;
import org.apache.james.mailbox.model.DeleteResult;
@@ -357,7 +358,7 @@ public class StoreMessageIdManager implements MessageIdManager {
.map(mailbox -> Pair.of(message, mailbox)))
.collect(Guavate.toImmutableList());
- return Mono.fromRunnable(Throwing.runnable(() -> validateQuota(messageMoves, mailboxMessage.get())).sneakyThrow())
+ return validateQuota(messageMoves, mailboxMessage.get())
.then(Mono.fromRunnable(Throwing.runnable(() ->
addMessageToMailboxes(mailboxMessage.get(), messageMoves.addedMailboxes(), mailboxSession)).sneakyThrow()))
.then(removeMessageFromMailboxes(mailboxMessage.get().getMessageId(), messagesToRemove, mailboxSession))
@@ -415,33 +416,44 @@ public class StoreMessageIdManager implements MessageIdManager {
return Mono.empty();
}
- private void validateQuota(MessageMovesWithMailbox messageMoves, MailboxMessage mailboxMessage) throws MailboxException {
+ private Mono<Void> validateQuota(MessageMovesWithMailbox messageMoves, MailboxMessage mailboxMessage) {
Map<QuotaRoot, Integer> messageCountByQuotaRoot = buildMapQuotaRoot(messageMoves);
- for (Map.Entry<QuotaRoot, Integer> entry : messageCountByQuotaRoot.entrySet()) {
- Integer additionalCopyCount = entry.getValue();
- if (additionalCopyCount > 0) {
- long additionalOccupiedSpace = additionalCopyCount * mailboxMessage.getFullContentOctets();
- new QuotaChecker(quotaManager.getQuotas(entry.getKey()), entry.getKey())
- .tryAddition(additionalCopyCount, additionalOccupiedSpace);
- }
- }
+
+ return Flux.fromIterable(messageCountByQuotaRoot.entrySet())
+ .filter(entry -> entry.getValue() > 0)
+ .flatMap(entry -> Mono.from(quotaManager.getQuotasReactive(entry.getKey()))
+ .map(quotas -> new QuotaChecker(quotas, entry.getKey()))
+ .handle((quotaChecker, sink) -> {
+ Integer additionalCopyCount = entry.getValue();
+ long additionalOccupiedSpace = additionalCopyCount * mailboxMessage.getFullContentOctets();
+ try {
+ quotaChecker.tryAddition(additionalCopyCount, additionalOccupiedSpace);
+ } catch (OverQuotaException e) {
+ sink.error(e);
+ }
+ }))
+ .then();
}
- private Map<QuotaRoot, Integer> buildMapQuotaRoot(MessageMovesWithMailbox messageMoves) throws MailboxException {
- Map<QuotaRoot, Integer> messageCountByQuotaRoot = new HashMap<>();
- for (Mailbox mailbox : messageMoves.addedMailboxes()) {
- QuotaRoot quotaRoot = quotaRootResolver.getQuotaRoot(mailbox);
- int currentCount = Optional.ofNullable(messageCountByQuotaRoot.get(quotaRoot))
- .orElse(0);
- messageCountByQuotaRoot.put(quotaRoot, currentCount + 1);
- }
- for (Mailbox mailbox : messageMoves.removedMailboxes()) {
- QuotaRoot quotaRoot = quotaRootResolver.getQuotaRoot(mailbox);
- int currentCount = Optional.ofNullable(messageCountByQuotaRoot.get(quotaRoot))
- .orElse(0);
- messageCountByQuotaRoot.put(quotaRoot, currentCount - 1);
+ private Map<QuotaRoot, Integer> buildMapQuotaRoot(MessageMovesWithMailbox messageMoves) {
+ try {
+ Map<QuotaRoot, Integer> messageCountByQuotaRoot = new HashMap<>();
+ for (Mailbox mailbox : messageMoves.addedMailboxes()) {
+ QuotaRoot quotaRoot = quotaRootResolver.getQuotaRoot(mailbox);
+ int currentCount = Optional.ofNullable(messageCountByQuotaRoot.get(quotaRoot))
+ .orElse(0);
+ messageCountByQuotaRoot.put(quotaRoot, currentCount + 1);
+ }
+ for (Mailbox mailbox : messageMoves.removedMailboxes()) {
+ QuotaRoot quotaRoot = quotaRootResolver.getQuotaRoot(mailbox);
+ int currentCount = Optional.ofNullable(messageCountByQuotaRoot.get(quotaRoot))
+ .orElse(0);
+ messageCountByQuotaRoot.put(quotaRoot, currentCount - 1);
+ }
+ return messageCountByQuotaRoot;
+ } catch (MailboxException e) {
+ throw new RuntimeException(e);
}
- return messageCountByQuotaRoot;
}
private void addMessageToMailboxes(MailboxMessage mailboxMessage, Set<Mailbox> mailboxes, MailboxSession mailboxSession) throws MailboxException {
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
index a6011de..1c86c65 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
@@ -56,7 +56,6 @@ import org.apache.james.mailbox.events.MailboxEvents.Expunged;
import org.apache.james.mailbox.events.MailboxEvents.FlagsUpdated;
import org.apache.james.mailbox.events.MailboxEvents.MailboxEvent;
import org.apache.james.mailbox.events.MessageMoveEvent;
-import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.exception.OverQuotaException;
import org.apache.james.mailbox.extension.PreDeletionHook;
import org.apache.james.mailbox.fixture.MailboxFixture;
@@ -115,6 +114,11 @@ public abstract class AbstractMessageIdManagerSideEffectTest {
eventCollector = new EventCollector();
quotaManager = mock(QuotaManager.class);
+ when(quotaManager.getQuotasReactive(any(QuotaRoot.class)))
+ .thenReturn(Mono.just(new QuotaManager.Quotas(
+ Quota.<QuotaCountLimit, QuotaCountUsage>builder().used(QuotaCountUsage.count(102)).computedLimit(QuotaCountLimit.unlimited()).build(),
+ Quota.<QuotaSizeLimit, QuotaSizeUsage>builder().used(QuotaSizeUsage.size(2)).computedLimit(QuotaSizeLimit.unlimited()).build())));
+
session = MailboxSessionUtil.create(ALICE);
setupMockForPreDeletionHooks();
testingData = createTestSystem(quotaManager, eventBus, ImmutableSet.of(preDeletionHook1, preDeletionHook2));
@@ -382,13 +386,13 @@ public abstract class AbstractMessageIdManagerSideEffectTest {
}
@Test
- void setInMailboxesShouldThrowExceptionWhenOverQuota() throws Exception {
+ void setInMailboxesShouldThrowExceptionWhenOverQuota() {
MessageId messageId = testingData.persist(mailbox1.getMailboxId(), messageUid1, FLAGS, session);
- when(quotaManager.getQuotas(any(QuotaRoot.class)))
- .thenReturn(new QuotaManager.Quotas(
+ when(quotaManager.getQuotasReactive(any(QuotaRoot.class)))
+ .thenReturn(Mono.just(new QuotaManager.Quotas(
OVER_QUOTA,
- Quota.<QuotaSizeLimit, QuotaSizeUsage>builder().used(QuotaSizeUsage.size(2)).computedLimit(QuotaSizeLimit.unlimited()).build()));
+ Quota.<QuotaSizeLimit, QuotaSizeUsage>builder().used(QuotaSizeUsage.size(2)).computedLimit(QuotaSizeLimit.unlimited()).build())));
assertThatThrownBy(() -> messageIdManager.setInMailboxes(messageId,
ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()),
@@ -553,10 +557,10 @@ public abstract class AbstractMessageIdManagerSideEffectTest {
assertThat(eventCollector.getEvents()).isEmpty();
}
- protected void givenUnlimitedQuota() throws MailboxException {
- when(quotaManager.getQuotas(any(QuotaRoot.class)))
- .thenReturn(new QuotaManager.Quotas(
+ protected void givenUnlimitedQuota() {
+ when(quotaManager.getQuotasReactive(any(QuotaRoot.class)))
+ .thenReturn(Mono.just(new QuotaManager.Quotas(
Quota.<QuotaCountLimit, QuotaCountUsage>builder().used(QuotaCountUsage.count(2)).computedLimit(QuotaCountLimit.unlimited()).build(),
- Quota.<QuotaSizeLimit, QuotaSizeUsage>builder().used(QuotaSizeUsage.size(2)).computedLimit(QuotaSizeLimit.unlimited()).build()));
+ Quota.<QuotaSizeLimit, QuotaSizeUsage>builder().used(QuotaSizeUsage.size(2)).computedLimit(QuotaSizeLimit.unlimited()).build())));
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org