You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2021/05/14 06:42:35 UTC
[james-project] 03/15: [REFACTORING] Fasten JMAP Mailbox/get
Reactive quotas
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 <bt...@linagora.com>
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: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org