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 7c4bda28c236bebe51f0aa4b5e8b3bf87fb555bd Author: Benoit Tellier <[email protected]> AuthorDate: Fri May 7 18:13:13 2021 +0700 [REFACTORING] Fasten JMAP Mailbox/get Reactive quotas --- .../james/mailbox/quota/MaxQuotaManager.java | 22 ++++++++ .../apache/james/mailbox/quota/QuotaManager.java | 3 ++ .../james/mailbox/quota/QuotaRootResolver.java | 4 ++ .../quota/CassandraPerUserMaxQuotaManager.java | 44 +++++++++------- .../store/quota/DefaultUserQuotaRootResolver.java | 15 +++++- .../store/quota/ListeningCurrentQuotaUpdater.java | 4 +- .../james/mailbox/store/quota/NoQuotaManager.java | 8 +++ .../mailbox/store/quota/StoreQuotaManager.java | 27 ++++++++-- .../draft/utils/quotas/DefaultQuotaLoader.java | 25 +++++---- .../james/jmap/draft/utils/quotas/QuotaLoader.java | 5 +- .../quotas/QuotaLoaderWithDefaultPreloaded.java | 61 +++++++++------------- .../james/jmap/utils/quotas/QuotaLoader.scala | 2 - .../quotas/QuotaLoaderWithPreloadedDefault.scala | 13 ++--- .../james/jmap/utils/quotas/QuotaReader.scala | 16 +++--- 14 files changed, 155 insertions(+), 94 deletions(-) diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java index b105b42..3d2cb5c 100644 --- a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/MaxQuotaManager.java @@ -32,9 +32,13 @@ import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.model.Quota; import org.apache.james.mailbox.model.Quota.Scope; import org.apache.james.mailbox.model.QuotaRoot; +import org.reactivestreams.Publisher; import com.github.fge.lambdas.Throwing; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; + /** * This interface describe how to set the max quotas for users * Part of RFC 2087 implementation @@ -150,12 +154,30 @@ public interface MaxQuotaManager { Map<Quota.Scope, QuotaCountLimit> listMaxMessagesDetails(QuotaRoot quotaRoot); + default Publisher<Map<Scope, QuotaCountLimit>> listMaxMessagesDetailsReactive(QuotaRoot quotaRoot) { + return Mono.fromCallable(() -> listMaxMessagesDetails(quotaRoot)) + .subscribeOn(Schedulers.elastic()); + } + Map<Quota.Scope, QuotaSizeLimit> listMaxStorageDetails(QuotaRoot quotaRoot); + default Publisher<Map<Quota.Scope, QuotaSizeLimit>> listMaxStorageDetailsReactive(QuotaRoot quotaRoot) { + return Mono.fromCallable(() -> listMaxStorageDetails(quotaRoot)) + .subscribeOn(Schedulers.elastic()); + } + + default QuotaDetails quotaDetails(QuotaRoot quotaRoot) { return new QuotaDetails(listMaxMessagesDetails(quotaRoot), listMaxStorageDetails(quotaRoot)); } + default Publisher<QuotaDetails> quotaDetailsReactive(QuotaRoot quotaRoot) { + return Mono.zip( + Mono.from(listMaxMessagesDetailsReactive(quotaRoot)), + Mono.from(listMaxStorageDetailsReactive(quotaRoot))) + .map(tuple -> new QuotaDetails(tuple.getT1(), tuple.getT2())); + } + Optional<QuotaCountLimit> getDomainMaxMessage(Domain domain); void setDomainMaxMessage(Domain domain, QuotaCountLimit count) throws MailboxException; diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaManager.java index a08c0bc..4d34ecf 100644 --- a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaManager.java +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaManager.java @@ -25,6 +25,7 @@ import org.apache.james.core.quota.QuotaSizeUsage; import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.model.Quota; import org.apache.james.mailbox.model.QuotaRoot; +import org.reactivestreams.Publisher; /** @@ -68,4 +69,6 @@ public interface QuotaManager { Quota<QuotaSizeLimit, QuotaSizeUsage> getStorageQuota(QuotaRoot quotaRoot) throws MailboxException; Quotas getQuotas(QuotaRoot quotaRoot) throws MailboxException; + + Publisher<Quotas> getQuotasReactive(QuotaRoot quotaRoot); } diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaRootResolver.java b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaRootResolver.java index 60510f6..efbc244 100644 --- a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaRootResolver.java +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaRootResolver.java @@ -37,10 +37,14 @@ public interface QuotaRootResolver extends QuotaRootDeserializer { */ QuotaRoot getQuotaRoot(MailboxPath mailboxPath) throws MailboxException; + Publisher<QuotaRoot> getQuotaRootReactive(MailboxPath mailboxPath); + QuotaRoot getQuotaRoot(MailboxId mailboxId) throws MailboxException; QuotaRoot getQuotaRoot(Mailbox mailbox) throws MailboxException; + Publisher<QuotaRoot> getQuotaRootReactive(Mailbox mailbox); + Publisher<QuotaRoot> getQuotaRootReactive(MailboxId mailboxId); Publisher<Mailbox> retrieveAssociatedMailboxes(QuotaRoot quotaRoot, MailboxSession mailboxSession); diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManager.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManager.java index 5fe0095..dd6884b 100644 --- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManager.java +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManager.java @@ -136,34 +136,42 @@ public class CassandraPerUserMaxQuotaManager implements MaxQuotaManager { @Override public Map<Quota.Scope, QuotaCountLimit> listMaxMessagesDetails(QuotaRoot quotaRoot) { + return listMaxMessagesDetailsReactive(quotaRoot).block(); + } + + @Override + public Mono<Map<Quota.Scope, QuotaCountLimit>> listMaxMessagesDetailsReactive(QuotaRoot quotaRoot) { return Flux.merge( - perUserQuota.getMaxMessage(quotaRoot) - .map(limit -> Pair.of(Quota.Scope.User, limit)), - Mono.justOrEmpty(quotaRoot.getDomain()) - .flatMap(perDomainQuota::getMaxMessage) - .map(limit -> Pair.of(Quota.Scope.Domain, limit)), - globalQuota.getGlobalMaxMessage() - .map(limit -> Pair.of(Quota.Scope.Global, limit))) + perUserQuota.getMaxMessage(quotaRoot) + .map(limit -> Pair.of(Quota.Scope.User, limit)), + Mono.justOrEmpty(quotaRoot.getDomain()) + .flatMap(perDomainQuota::getMaxMessage) + .map(limit -> Pair.of(Quota.Scope.Domain, limit)), + globalQuota.getGlobalMaxMessage() + .map(limit -> Pair.of(Quota.Scope.Global, limit))) .collect(Guavate.toImmutableMap( Pair::getKey, - Pair::getValue)) - .block(); + Pair::getValue)); } @Override public Map<Quota.Scope, QuotaSizeLimit> listMaxStorageDetails(QuotaRoot quotaRoot) { + return listMaxStorageDetailsReactive(quotaRoot).block(); + } + + @Override + public Mono<Map<Quota.Scope, QuotaSizeLimit>> listMaxStorageDetailsReactive(QuotaRoot quotaRoot) { return Flux.merge( - perUserQuota.getMaxStorage(quotaRoot) - .map(limit -> Pair.of(Quota.Scope.User, limit)), - Mono.justOrEmpty(quotaRoot.getDomain()) - .flatMap(perDomainQuota::getMaxStorage) - .map(limit -> Pair.of(Quota.Scope.Domain, limit)), - globalQuota.getGlobalMaxStorage() - .map(limit -> Pair.of(Quota.Scope.Global, limit))) + perUserQuota.getMaxStorage(quotaRoot) + .map(limit -> Pair.of(Quota.Scope.User, limit)), + Mono.justOrEmpty(quotaRoot.getDomain()) + .flatMap(perDomainQuota::getMaxStorage) + .map(limit -> Pair.of(Quota.Scope.Domain, limit)), + globalQuota.getGlobalMaxStorage() + .map(limit -> Pair.of(Quota.Scope.Global, limit))) .collect(Guavate.toImmutableMap( Pair::getKey, - Pair::getValue)) - .block(); + Pair::getValue)); } @Override diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolver.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolver.java index b6f2069..629d6aa 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolver.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/DefaultUserQuotaRootResolver.java @@ -37,6 +37,7 @@ import org.apache.james.mailbox.model.search.MailboxQuery; import org.apache.james.mailbox.quota.QuotaRootDeserializer; import org.apache.james.mailbox.quota.UserQuotaRootResolver; import org.apache.james.mailbox.store.MailboxSessionMapperFactory; +import org.reactivestreams.Publisher; import com.google.common.base.Preconditions; import com.google.common.base.Splitter; @@ -95,12 +96,12 @@ public class DefaultUserQuotaRootResolver implements UserQuotaRootResolver { } @Override - public QuotaRoot getQuotaRoot(Mailbox mailbox) throws MailboxException { + public QuotaRoot getQuotaRoot(Mailbox mailbox) { return getQuotaRoot(mailbox.generateAssociatedPath()); } @Override - public QuotaRoot getQuotaRoot(MailboxId mailboxId) throws MailboxException { + public QuotaRoot getQuotaRoot(MailboxId mailboxId) { return getQuotaRootReactive(mailboxId).block(); } @@ -116,6 +117,16 @@ public class DefaultUserQuotaRootResolver implements UserQuotaRootResolver { } @Override + public Publisher<QuotaRoot> getQuotaRootReactive(MailboxPath mailboxPath) { + return Mono.just(getQuotaRoot(mailboxPath)); + } + + @Override + public Publisher<QuotaRoot> getQuotaRootReactive(Mailbox mailbox) { + return Mono.just(getQuotaRoot(mailbox)); + } + + @Override public QuotaRoot fromString(String serializedQuotaRoot) throws MailboxException { return QUOTA_ROOT_DESERIALIZER.fromString(serializedQuotaRoot); } diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdater.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdater.java index 2bafe64..cfe2d80 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdater.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/ListeningCurrentQuotaUpdater.java @@ -110,9 +110,7 @@ public class ListeningCurrentQuotaUpdater implements EventListener.ReactiveGroup } private Mono<Void> dispatchNewQuota(QuotaRoot quotaRoot, Username username) { - Mono<QuotaManager.Quotas> quotasMono = Mono.fromCallable(() -> quotaManager.getQuotas(quotaRoot)); - - return quotasMono.subscribeOn(Schedulers.elastic()) + return Mono.from(quotaManager.getQuotasReactive(quotaRoot)) .flatMap(quotas -> eventBus.dispatch( EventFactory.quotaUpdated() .randomEventId() diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/NoQuotaManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/NoQuotaManager.java index e40b084..89e3d63 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/NoQuotaManager.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/NoQuotaManager.java @@ -26,6 +26,9 @@ import org.apache.james.core.quota.QuotaSizeUsage; import org.apache.james.mailbox.model.Quota; import org.apache.james.mailbox.model.QuotaRoot; import org.apache.james.mailbox.quota.QuotaManager; +import org.reactivestreams.Publisher; + +import reactor.core.publisher.Mono; /** * This quota manager is intended to be used when you want to deactivate the Quota feature @@ -52,4 +55,9 @@ public class NoQuotaManager implements QuotaManager { public Quotas getQuotas(QuotaRoot quotaRoot) { return new Quotas(getMessageQuota(quotaRoot), getStorageQuota(quotaRoot)); } + + @Override + public Publisher<Quotas> getQuotasReactive(QuotaRoot quotaRoot) { + return Mono.just(getQuotas(quotaRoot)); + } } diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/StoreQuotaManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/StoreQuotaManager.java index 17d80e7..aa010bc 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/StoreQuotaManager.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/StoreQuotaManager.java @@ -27,7 +27,6 @@ import org.apache.james.core.quota.QuotaCountLimit; import org.apache.james.core.quota.QuotaCountUsage; import org.apache.james.core.quota.QuotaSizeLimit; import org.apache.james.core.quota.QuotaSizeUsage; -import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.model.CurrentQuotas; import org.apache.james.mailbox.model.Quota; import org.apache.james.mailbox.model.Quota.Scope; @@ -35,8 +34,10 @@ import org.apache.james.mailbox.model.QuotaRoot; import org.apache.james.mailbox.quota.CurrentQuotaManager; import org.apache.james.mailbox.quota.MaxQuotaManager; import org.apache.james.mailbox.quota.QuotaManager; +import org.reactivestreams.Publisher; import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; /** * Default implementation for the Quota Manager. @@ -54,7 +55,7 @@ public class StoreQuotaManager implements QuotaManager { } @Override - public Quota<QuotaCountLimit, QuotaCountUsage> getMessageQuota(QuotaRoot quotaRoot) throws MailboxException { + public Quota<QuotaCountLimit, QuotaCountUsage> getMessageQuota(QuotaRoot quotaRoot) { Map<Scope, QuotaCountLimit> maxMessageDetails = maxQuotaManager.listMaxMessagesDetails(quotaRoot); return Quota.<QuotaCountLimit, QuotaCountUsage>builder() .used(Mono.from(currentQuotaManager.getCurrentMessageCount(quotaRoot)).block()) @@ -65,7 +66,7 @@ public class StoreQuotaManager implements QuotaManager { @Override - public Quota<QuotaSizeLimit, QuotaSizeUsage> getStorageQuota(QuotaRoot quotaRoot) throws MailboxException { + public Quota<QuotaSizeLimit, QuotaSizeUsage> getStorageQuota(QuotaRoot quotaRoot) { Map<Scope, QuotaSizeLimit> maxStorageDetails = maxQuotaManager.listMaxStorageDetails(quotaRoot); return Quota.<QuotaSizeLimit, QuotaSizeUsage>builder() .used(Mono.from(currentQuotaManager.getCurrentStorage(quotaRoot)).block()) @@ -75,7 +76,7 @@ public class StoreQuotaManager implements QuotaManager { } @Override - public Quotas getQuotas(QuotaRoot quotaRoot) throws MailboxException { + public Quotas getQuotas(QuotaRoot quotaRoot) { MaxQuotaManager.QuotaDetails quotaDetails = maxQuotaManager.quotaDetails(quotaRoot); CurrentQuotas currentQuotas = Mono.from(currentQuotaManager.getCurrentQuotas(quotaRoot)).block(); return new Quotas( @@ -90,4 +91,22 @@ public class StoreQuotaManager implements QuotaManager { .limitsByScope(quotaDetails.getMaxStorageDetails()) .build()); } + + @Override + public Publisher<Quotas> getQuotasReactive(QuotaRoot quotaRoot) { + return Mono.zip( + Mono.from(maxQuotaManager.quotaDetailsReactive(quotaRoot)), + Mono.from(currentQuotaManager.getCurrentQuotas(quotaRoot))) + .map(tuple -> new Quotas( + Quota.<QuotaCountLimit, QuotaCountUsage>builder() + .used(tuple.getT2().count()) + .computedLimit(maxQuotaManager.getMaxMessage(tuple.getT1().getMaxMessageDetails()).orElse(QuotaCountLimit.unlimited())) + .limitsByScope(tuple.getT1().getMaxMessageDetails()) + .build(), + Quota.<QuotaSizeLimit, QuotaSizeUsage>builder() + .used(tuple.getT2().size()) + .computedLimit(maxQuotaManager.getMaxStorage(tuple.getT1().getMaxStorageDetails()).orElse(QuotaSizeLimit.unlimited())) + .limitsByScope(tuple.getT1().getMaxStorageDetails()) + .build())); + } } \ No newline at end of file diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/utils/quotas/DefaultQuotaLoader.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/utils/quotas/DefaultQuotaLoader.java index 25a851f..e1aa415 100644 --- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/utils/quotas/DefaultQuotaLoader.java +++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/utils/quotas/DefaultQuotaLoader.java @@ -21,12 +21,12 @@ package org.apache.james.jmap.draft.utils.quotas; import javax.inject.Inject; import org.apache.james.jmap.draft.model.mailbox.Quotas; -import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.model.MailboxPath; -import org.apache.james.mailbox.model.QuotaRoot; import org.apache.james.mailbox.quota.QuotaManager; import org.apache.james.mailbox.quota.QuotaRootResolver; +import reactor.core.publisher.Mono; + public class DefaultQuotaLoader extends QuotaLoader { private final QuotaRootResolver quotaRootResolver; @@ -38,15 +38,18 @@ public class DefaultQuotaLoader extends QuotaLoader { this.quotaManager = quotaManager; } - public Quotas getQuotas(MailboxPath mailboxPath) throws MailboxException { - QuotaRoot quotaRoot = quotaRootResolver.getQuotaRoot(mailboxPath); - Quotas.QuotaId quotaId = Quotas.QuotaId.fromQuotaRoot(quotaRoot); - QuotaManager.Quotas quotas = quotaManager.getQuotas(quotaRoot); - return Quotas.from( - quotaId, - Quotas.Quota.from( - quotaToValue(quotas.getStorageQuota()), - quotaToValue(quotas.getMessageQuota()))); + public Mono<Quotas> getQuotas(MailboxPath mailboxPath) { + return Mono.from(quotaRootResolver.getQuotaRootReactive(mailboxPath)) + .flatMap(quotaRoot -> Mono.from(quotaManager.getQuotasReactive(quotaRoot)) + .map(quotas -> { + Quotas.QuotaId quotaId = Quotas.QuotaId.fromQuotaRoot(quotaRoot); + + return Quotas.from( + quotaId, + Quotas.Quota.from( + quotaToValue(quotas.getStorageQuota()), + quotaToValue(quotas.getMessageQuota()))); + })); } } diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/utils/quotas/QuotaLoader.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/utils/quotas/QuotaLoader.java index 76bd371..77a6aea 100644 --- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/utils/quotas/QuotaLoader.java +++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/utils/quotas/QuotaLoader.java @@ -24,13 +24,14 @@ import org.apache.james.core.quota.QuotaLimitValue; import org.apache.james.core.quota.QuotaUsageValue; import org.apache.james.jmap.draft.model.Number; import org.apache.james.jmap.draft.model.mailbox.Quotas; -import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.model.MailboxPath; import org.apache.james.mailbox.model.Quota; +import reactor.core.publisher.Mono; + public abstract class QuotaLoader { - public abstract Quotas getQuotas(MailboxPath mailboxPath) throws MailboxException; + public abstract Mono<Quotas> getQuotas(MailboxPath mailboxPath); protected <T extends QuotaLimitValue<T>, U extends QuotaUsageValue<U, T>> Quotas.Value<T, U> quotaToValue(Quota<T, U> quota) { return new Quotas.Value<>( diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/utils/quotas/QuotaLoaderWithDefaultPreloaded.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/utils/quotas/QuotaLoaderWithDefaultPreloaded.java index 326f0d2..876dfbd 100644 --- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/utils/quotas/QuotaLoaderWithDefaultPreloaded.java +++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/utils/quotas/QuotaLoaderWithDefaultPreloaded.java @@ -22,42 +22,44 @@ import java.util.Optional; import org.apache.james.jmap.draft.model.mailbox.Quotas; import org.apache.james.mailbox.MailboxSession; -import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.model.MailboxPath; -import org.apache.james.mailbox.model.QuotaRoot; import org.apache.james.mailbox.quota.QuotaManager; import org.apache.james.mailbox.quota.QuotaRootResolver; +import reactor.core.publisher.Mono; + public class QuotaLoaderWithDefaultPreloaded extends QuotaLoader { + public static Mono<QuotaLoaderWithDefaultPreloaded> preLoad(QuotaRootResolver quotaRootResolver, + QuotaManager quotaManager, + MailboxSession session) { + DefaultQuotaLoader defaultQuotaLoader = new DefaultQuotaLoader(quotaRootResolver, quotaManager); + + return defaultQuotaLoader.getQuotas(MailboxPath.inbox(session)) + .map(Optional::of) + .switchIfEmpty(Mono.just(Optional.empty())) + .map(quotas -> new QuotaLoaderWithDefaultPreloaded(quotaRootResolver, defaultQuotaLoader, quotas)); + } + private final QuotaRootResolver quotaRootResolver; - private final QuotaManager quotaManager; + private final DefaultQuotaLoader defaultQuotaLoader; private final Optional<Quotas> preloadedUserDefaultQuotas; - private final MailboxSession session; - public QuotaLoaderWithDefaultPreloaded(QuotaRootResolver quotaRootResolver, - QuotaManager quotaManager, - MailboxSession session) throws MailboxException { + private QuotaLoaderWithDefaultPreloaded(QuotaRootResolver quotaRootResolver, DefaultQuotaLoader defaultQuotaLoader, Optional<Quotas> preloadedUserDefaultQuotas) { this.quotaRootResolver = quotaRootResolver; - this.quotaManager = quotaManager; - this.session = session; - preloadedUserDefaultQuotas = Optional.of(getUserDefaultQuotas()); - + this.defaultQuotaLoader = defaultQuotaLoader; + this.preloadedUserDefaultQuotas = preloadedUserDefaultQuotas; } - public Quotas getQuotas(MailboxPath mailboxPath) throws MailboxException { - QuotaRoot quotaRoot = quotaRootResolver.getQuotaRoot(mailboxPath); - Quotas.QuotaId quotaId = Quotas.QuotaId.fromQuotaRoot(quotaRoot); - - if (containsQuotaId(preloadedUserDefaultQuotas, quotaId)) { - return preloadedUserDefaultQuotas.get(); - } - QuotaManager.Quotas quotas = quotaManager.getQuotas(quotaRoot); - return Quotas.from( - quotaId, - Quotas.Quota.from( - quotaToValue(quotas.getStorageQuota()), - quotaToValue(quotas.getMessageQuota()))); + public Mono<Quotas> getQuotas(MailboxPath mailboxPath) { + return Mono.from(quotaRootResolver.getQuotaRootReactive(mailboxPath)) + .flatMap(quotaRoot -> { + Quotas.QuotaId quotaId = Quotas.QuotaId.fromQuotaRoot(quotaRoot); + if (containsQuotaId(preloadedUserDefaultQuotas, quotaId)) { + return Mono.just(preloadedUserDefaultQuotas.get()); + } + return defaultQuotaLoader.getQuotas(mailboxPath); + }); } private boolean containsQuotaId(Optional<Quotas> preloadedUserDefaultQuotas, Quotas.QuotaId quotaId) { @@ -67,15 +69,4 @@ public class QuotaLoaderWithDefaultPreloaded extends QuotaLoader { .orElse(false); } - private Quotas getUserDefaultQuotas() throws MailboxException { - QuotaRoot quotaRoot = quotaRootResolver.getQuotaRoot(MailboxPath.inbox(session)); - Quotas.QuotaId quotaId = Quotas.QuotaId.fromQuotaRoot(quotaRoot); - QuotaManager.Quotas quotas = quotaManager.getQuotas(quotaRoot); - return Quotas.from( - quotaId, - Quotas.Quota.from( - quotaToValue(quotas.getStorageQuota()), - quotaToValue(quotas.getMessageQuota()))); - } - } diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaLoader.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaLoader.scala index 0c770c7..447ca25 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaLoader.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaLoader.scala @@ -20,11 +20,9 @@ package org.apache.james.jmap.utils.quotas import org.apache.james.jmap.mail.Quotas -import org.apache.james.mailbox.exception.MailboxException import org.apache.james.mailbox.model.MailboxPath import reactor.core.scala.publisher.SMono trait QuotaLoader { - @throws[MailboxException] def getQuotas(mailboxPath: MailboxPath): SMono[Quotas] } diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaLoaderWithPreloadedDefault.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaLoaderWithPreloadedDefault.scala index 8a4c458..6e56928 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaLoaderWithPreloadedDefault.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaLoaderWithPreloadedDefault.scala @@ -22,7 +22,6 @@ package org.apache.james.jmap.utils.quotas import javax.inject.Inject import org.apache.james.jmap.mail.{QuotaRoot, Quotas} import org.apache.james.mailbox.MailboxSession -import org.apache.james.mailbox.exception.MailboxException import org.apache.james.mailbox.model.{MailboxPath, QuotaRoot => ModelQuotaRoot} import org.apache.james.mailbox.quota.UserQuotaRootResolver import reactor.core.scala.publisher.SMono @@ -31,14 +30,13 @@ import reactor.core.scala.publisher.SMono class QuotaLoaderWithPreloadedDefaultFactory @Inject()(quotaRootResolver: UserQuotaRootResolver, quotaReader: QuotaReader) { def loadFor(session: MailboxSession): SMono[QuotaLoaderWithPreloadedDefault] = - SMono.fromCallable(() => new QuotaLoaderWithPreloadedDefault( + getUserDefaultQuotas(session) + .map(qotas => new QuotaLoaderWithPreloadedDefault( quotaRootResolver, quotaReader, session, - getUserDefaultQuotas(session))) + qotas)) - - @throws[MailboxException] private def getUserDefaultQuotas(session:MailboxSession): SMono[Quotas] = { val quotaRoot: ModelQuotaRoot = quotaRootResolver.forUser(session.getUser) quotaReader.retrieveQuotas(QuotaRoot.toJmap(quotaRoot)) @@ -48,11 +46,10 @@ class QuotaLoaderWithPreloadedDefaultFactory @Inject()(quotaRootResolver: UserQu class QuotaLoaderWithPreloadedDefault(quotaRootResolver: UserQuotaRootResolver, quotaReader: QuotaReader, session: MailboxSession, - preloadedUserDefaultQuotas: SMono[Quotas]) extends QuotaLoader { - @throws[MailboxException] + preloadedUserDefaultQuotas: Quotas) extends QuotaLoader { override def getQuotas(mailboxPath: MailboxPath): SMono[Quotas] = if (mailboxPath.belongsTo(session)) { - preloadedUserDefaultQuotas + SMono.just(preloadedUserDefaultQuotas) } else { val quotaRoot: ModelQuotaRoot = quotaRootResolver.getQuotaRoot(mailboxPath) quotaReader.retrieveQuotas(QuotaRoot.toJmap(quotaRoot)) diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaReader.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaReader.scala index de77245..de646c0 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaReader.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/quotas/QuotaReader.scala @@ -31,15 +31,13 @@ import reactor.core.scala.publisher.SMono class QuotaReader @Inject() (quotaManager: QuotaManager) { @throws[MailboxException] - def retrieveQuotas(quotaRoot: QuotaRoot): SMono[Quotas] = { - val quotaId = QuotaId.fromQuotaRoot(quotaRoot) - val quotas = quotaManager.getQuotas(quotaRoot.toModel) - SMono.just(Quotas.from( - quotaId, - Quota.from(Map( - Quotas.Storage -> quotaToValue(quotas.getStorageQuota), - Quotas.Message -> quotaToValue(quotas.getMessageQuota))))) - } + def retrieveQuotas(quotaRoot: QuotaRoot): SMono[Quotas] = + SMono(quotaManager.getQuotasReactive(quotaRoot.toModel)) + .map(quotas => Quotas.from( + QuotaId.fromQuotaRoot(quotaRoot), + Quota.from(Map( + Quotas.Storage -> quotaToValue(quotas.getStorageQuota), + Quotas.Message -> quotaToValue(quotas.getMessageQuota))))) private def quotaToValue[T <: QuotaLimitValue[T], U <: QuotaUsageValue[U, T]](quota: ModelQuota[T, U]): Value = Value( --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
