You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2020/04/22 07:24:34 UTC
[james-project] 02/10: JAMES-3138 Add getCurrentQuotas in
CurrentQuotaManager
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 4a7dfcbf03bc4dbfb3662f08af44496f4b847b37
Author: Rene Cordier <rc...@linagora.com>
AuthorDate: Fri Apr 10 15:05:40 2020 +0700
JAMES-3138 Add getCurrentQuotas in CurrentQuotaManager
---
.../apache/james/mailbox/model/CurrentQuotas.java | 4 +++
.../james/mailbox/quota/CurrentQuotaManager.java | 2 ++
.../quota/CassandraCurrentQuotaManager.java | 37 ++++++++++++++++------
.../mailbox/jpa/quota/JpaCurrentQuotaManager.java | 8 +++++
.../quota/InMemoryCurrentQuotaManager.java | 6 ++++
.../quota/InMemoryCurrentQuotaManagerTest.java | 19 +++++++++++
.../store/quota/StoreCurrentQuotaManagerTest.java | 37 ++++++++++++++++++----
7 files changed, 97 insertions(+), 16 deletions(-)
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/CurrentQuotas.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/CurrentQuotas.java
index e155841..3b82866 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/CurrentQuotas.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/CurrentQuotas.java
@@ -28,6 +28,10 @@ public class CurrentQuotas {
private final QuotaCountUsage count;
private final QuotaSizeUsage size;
+ public static CurrentQuotas emptyQuotas() {
+ return new CurrentQuotas(QuotaCountUsage.count(0L), QuotaSizeUsage.size(0L));
+ }
+
public CurrentQuotas(QuotaCountUsage count, QuotaSizeUsage size) {
this.count = count;
this.size = size;
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/CurrentQuotaManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/CurrentQuotaManager.java
index f1f3d41..1e84e09 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/CurrentQuotaManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/CurrentQuotaManager.java
@@ -21,6 +21,7 @@ package org.apache.james.mailbox.quota;
import org.apache.james.core.quota.QuotaCountUsage;
import org.apache.james.core.quota.QuotaSizeUsage;
+import org.apache.james.mailbox.model.CurrentQuotas;
import org.apache.james.mailbox.model.QuotaRoot;
import org.reactivestreams.Publisher;
@@ -33,4 +34,5 @@ public interface CurrentQuotaManager {
Publisher<QuotaSizeUsage> getCurrentStorage(QuotaRoot quotaRoot);
+ Publisher<CurrentQuotas> getCurrentQuotas(QuotaRoot quotaRoot);
}
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraCurrentQuotaManager.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraCurrentQuotaManager.java
index a4ba974..fcda0ca 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraCurrentQuotaManager.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraCurrentQuotaManager.java
@@ -25,6 +25,9 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
import static com.datastax.driver.core.querybuilder.QueryBuilder.incr;
import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
import static com.datastax.driver.core.querybuilder.QueryBuilder.update;
+import static org.apache.james.mailbox.cassandra.table.CassandraCurrentQuota.MESSAGE_COUNT;
+import static org.apache.james.mailbox.cassandra.table.CassandraCurrentQuota.STORAGE;
+import static org.apache.james.mailbox.cassandra.table.CassandraCurrentQuota.TABLE_NAME;
import javax.inject.Inject;
@@ -32,6 +35,7 @@ import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
import org.apache.james.core.quota.QuotaCountUsage;
import org.apache.james.core.quota.QuotaSizeUsage;
import org.apache.james.mailbox.cassandra.table.CassandraCurrentQuota;
+import org.apache.james.mailbox.model.CurrentQuotas;
import org.apache.james.mailbox.model.QuotaOperation;
import org.apache.james.mailbox.model.QuotaRoot;
import org.apache.james.mailbox.store.quota.StoreCurrentQuotaManager;
@@ -48,23 +52,27 @@ public class CassandraCurrentQuotaManager implements StoreCurrentQuotaManager {
private final PreparedStatement decreaseStatement;
private final PreparedStatement getCurrentMessageCountStatement;
private final PreparedStatement getCurrentStorageStatement;
+ private final PreparedStatement getCurrentQuotasStatement;
@Inject
public CassandraCurrentQuotaManager(Session session) {
this.cassandraAsyncExecutor = new CassandraAsyncExecutor(session);
- this.increaseStatement = session.prepare(update(CassandraCurrentQuota.TABLE_NAME)
- .with(incr(CassandraCurrentQuota.MESSAGE_COUNT, bindMarker()))
- .and(incr(CassandraCurrentQuota.STORAGE, bindMarker()))
+ this.increaseStatement = session.prepare(update(TABLE_NAME)
+ .with(incr(MESSAGE_COUNT, bindMarker()))
+ .and(incr(STORAGE, bindMarker()))
.where(eq(CassandraCurrentQuota.QUOTA_ROOT, bindMarker())));
- this.decreaseStatement = session.prepare(update(CassandraCurrentQuota.TABLE_NAME)
- .with(decr(CassandraCurrentQuota.MESSAGE_COUNT, bindMarker()))
- .and(decr(CassandraCurrentQuota.STORAGE, bindMarker()))
+ this.decreaseStatement = session.prepare(update(TABLE_NAME)
+ .with(decr(MESSAGE_COUNT, bindMarker()))
+ .and(decr(STORAGE, bindMarker()))
.where(eq(CassandraCurrentQuota.QUOTA_ROOT, bindMarker())));
- this.getCurrentMessageCountStatement = session.prepare(select(CassandraCurrentQuota.MESSAGE_COUNT)
- .from(CassandraCurrentQuota.TABLE_NAME)
+ this.getCurrentMessageCountStatement = session.prepare(select(MESSAGE_COUNT)
+ .from(TABLE_NAME)
.where(eq(CassandraCurrentQuota.QUOTA_ROOT, bindMarker())));
- this.getCurrentStorageStatement = session.prepare(select(CassandraCurrentQuota.STORAGE)
- .from(CassandraCurrentQuota.TABLE_NAME)
+ this.getCurrentStorageStatement = session.prepare(select(STORAGE)
+ .from(TABLE_NAME)
+ .where(eq(CassandraCurrentQuota.QUOTA_ROOT, bindMarker())));
+ this.getCurrentQuotasStatement = session.prepare(select(MESSAGE_COUNT, STORAGE)
+ .from(TABLE_NAME)
.where(eq(CassandraCurrentQuota.QUOTA_ROOT, bindMarker())));
}
@@ -95,4 +103,13 @@ public class CassandraCurrentQuotaManager implements StoreCurrentQuotaManager {
.map(row -> QuotaSizeUsage.size(row.getLong(CassandraCurrentQuota.STORAGE)))
.defaultIfEmpty(QuotaSizeUsage.size(0L));
}
+
+ @Override
+ public Mono<CurrentQuotas> getCurrentQuotas(QuotaRoot quotaRoot) {
+ return cassandraAsyncExecutor.executeSingleRow(getCurrentQuotasStatement.bind(quotaRoot.getValue()))
+ .map(row -> new CurrentQuotas(
+ QuotaCountUsage.count(row.getLong(MESSAGE_COUNT)),
+ QuotaSizeUsage.size(row.getLong(STORAGE))))
+ .defaultIfEmpty(CurrentQuotas.emptyQuotas());
+ }
}
diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JpaCurrentQuotaManager.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JpaCurrentQuotaManager.java
index f56bab0..f79f4a1 100644
--- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JpaCurrentQuotaManager.java
+++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JpaCurrentQuotaManager.java
@@ -29,6 +29,7 @@ import org.apache.james.backends.jpa.TransactionRunner;
import org.apache.james.core.quota.QuotaCountUsage;
import org.apache.james.core.quota.QuotaSizeUsage;
import org.apache.james.mailbox.jpa.quota.model.JpaCurrentQuota;
+import org.apache.james.mailbox.model.CurrentQuotas;
import org.apache.james.mailbox.model.QuotaOperation;
import org.apache.james.mailbox.model.QuotaRoot;
import org.apache.james.mailbox.store.quota.StoreCurrentQuotaManager;
@@ -67,6 +68,13 @@ public class JpaCurrentQuotaManager implements StoreCurrentQuotaManager {
.orElse(QuotaSizeUsage.size(NO_STORED_BYTES)));
}
+ public Mono<CurrentQuotas> getCurrentQuotas(QuotaRoot quotaRoot) {
+ EntityManager entityManager = entityManagerFactory.createEntityManager();
+ return Mono.fromCallable(() -> Optional.ofNullable(retrieveUserQuota(entityManager, quotaRoot))
+ .map(jpaCurrentQuota -> new CurrentQuotas(jpaCurrentQuota.getMessageCount(), jpaCurrentQuota.getSize()))
+ .orElse(CurrentQuotas.emptyQuotas()));
+ }
+
@Override
public Mono<Void> increase(QuotaOperation quotaOperation) {
return Mono.fromRunnable(() ->
diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/quota/InMemoryCurrentQuotaManager.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/quota/InMemoryCurrentQuotaManager.java
index 326640c..32b55cc 100644
--- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/quota/InMemoryCurrentQuotaManager.java
+++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/quota/InMemoryCurrentQuotaManager.java
@@ -77,6 +77,12 @@ public class InMemoryCurrentQuotaManager implements StoreCurrentQuotaManager {
.onErrorMap(this::wrapAsMailboxException);
}
+ @Override
+ public Mono<CurrentQuotas> getCurrentQuotas(QuotaRoot quotaRoot) {
+ return Mono.fromCallable(() -> quotaCache.get(quotaRoot).get())
+ .onErrorMap(this::wrapAsMailboxException);
+ }
+
private Mono<Void> updateQuota(QuotaRoot quotaRoot, UnaryOperator<CurrentQuotas> quotaFunction) {
return Mono.fromCallable(() -> quotaCache.get(quotaRoot).updateAndGet(quotaFunction))
.onErrorMap(this::wrapAsMailboxException)
diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/quota/InMemoryCurrentQuotaManagerTest.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/quota/InMemoryCurrentQuotaManagerTest.java
index 9320964..99d1191 100644
--- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/quota/InMemoryCurrentQuotaManagerTest.java
+++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/quota/InMemoryCurrentQuotaManagerTest.java
@@ -78,4 +78,23 @@ class InMemoryCurrentQuotaManagerTest {
assertThat(testee.getCurrentMessageCount(QUOTA_ROOT).block()).isEqualTo(QuotaCountUsage.count(28));
assertThat(testee.getCurrentStorage(QUOTA_ROOT).block()).isEqualTo(QuotaSizeUsage.size(612));
}
+
+ @Test
+ void getCurrentQuotasShouldReturnRecalculateSizeWhenEntryIsNotInitialized() throws Exception {
+ when(mockedCurrentQuotaCalculator.recalculateCurrentQuotas(QUOTA_ROOT, null))
+ .thenReturn(CURRENT_QUOTAS);
+
+ assertThat(testee.getCurrentQuotas(QUOTA_ROOT).block()).isEqualTo(CURRENT_QUOTAS);
+ }
+
+ @Test
+ void getCurrentQuotasShouldReRetrieveStoredQuotasWhenCalculateOnUnknownQuotaIsTrue() throws Exception {
+ when(mockedCurrentQuotaCalculator.recalculateCurrentQuotas(QUOTA_ROOT, null))
+ .thenReturn(CURRENT_QUOTAS);
+
+ QuotaOperation quotaOperation = new QuotaOperation(QUOTA_ROOT, QuotaCountUsage.count(10), QuotaSizeUsage.size(100));
+ testee.increase(quotaOperation).block();
+
+ assertThat(testee.getCurrentQuotas(QUOTA_ROOT).block()).isEqualTo(new CurrentQuotas(QuotaCountUsage.count(28), QuotaSizeUsage.size(612)));
+ }
}
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/StoreCurrentQuotaManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/StoreCurrentQuotaManagerTest.java
index 02701fb..74ca11c 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/StoreCurrentQuotaManagerTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/quota/StoreCurrentQuotaManagerTest.java
@@ -25,15 +25,20 @@ import java.util.Optional;
import org.apache.james.core.quota.QuotaCountUsage;
import org.apache.james.core.quota.QuotaSizeUsage;
+import org.apache.james.mailbox.model.CurrentQuotas;
import org.apache.james.mailbox.model.QuotaOperation;
import org.apache.james.mailbox.model.QuotaRoot;
+import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import com.github.fge.lambdas.Throwing;
+
import reactor.core.publisher.Mono;
public abstract class StoreCurrentQuotaManagerTest {
private static final QuotaRoot QUOTA_ROOT = QuotaRoot.quotaRoot("benwa", Optional.empty());
+ private static final CurrentQuotas CURRENT_QUOTAS = new CurrentQuotas(QuotaCountUsage.count(10), QuotaSizeUsage.size(100));
protected abstract StoreCurrentQuotaManager provideTestee();
@@ -50,11 +55,24 @@ public abstract class StoreCurrentQuotaManagerTest {
}
@Test
+ void getCurrentMessageCountShouldReturnZeroByDefault() throws Exception {
+ assertThat(Mono.from(testee.getCurrentMessageCount(QUOTA_ROOT)).block()).isEqualTo(QuotaCountUsage.count(0));
+ }
+
+ @Test
+ void getCurrentQuotasShouldReturnZeroByDefault() {
+ assertThat(Mono.from(testee.getCurrentQuotas(QUOTA_ROOT)).block()).isEqualTo(CurrentQuotas.emptyQuotas());
+ }
+
+ @Test
void increaseShouldWork() throws Exception {
testee.increase(new QuotaOperation(QUOTA_ROOT, QuotaCountUsage.count(10), QuotaSizeUsage.size(100))).block();
- assertThat(Mono.from(testee.getCurrentMessageCount(QUOTA_ROOT)).block()).isEqualTo(QuotaCountUsage.count(10));
- assertThat(Mono.from(testee.getCurrentStorage(QUOTA_ROOT)).block()).isEqualTo(QuotaSizeUsage.size(100));
+ SoftAssertions.assertSoftly(Throwing.consumer(softly -> {
+ softly.assertThat(Mono.from(testee.getCurrentQuotas(QUOTA_ROOT)).block()).isEqualTo(CURRENT_QUOTAS);
+ softly.assertThat(Mono.from(testee.getCurrentMessageCount(QUOTA_ROOT)).block()).isEqualTo(QuotaCountUsage.count(10));
+ softly.assertThat(Mono.from(testee.getCurrentStorage(QUOTA_ROOT)).block()).isEqualTo(QuotaSizeUsage.size(100));
+ }));
}
@Test
@@ -63,15 +81,22 @@ public abstract class StoreCurrentQuotaManagerTest {
testee.decrease(new QuotaOperation(QUOTA_ROOT, QuotaCountUsage.count(10), QuotaSizeUsage.size(100))).block();
- assertThat(Mono.from(testee.getCurrentMessageCount(QUOTA_ROOT)).block()).isEqualTo(QuotaCountUsage.count(10));
- assertThat(Mono.from(testee.getCurrentStorage(QUOTA_ROOT)).block()).isEqualTo(QuotaSizeUsage.size(100));
+ SoftAssertions.assertSoftly(Throwing.consumer(softly -> {
+ softly.assertThat(Mono.from(testee.getCurrentQuotas(QUOTA_ROOT)).block()).isEqualTo(CURRENT_QUOTAS);
+ softly.assertThat(Mono.from(testee.getCurrentMessageCount(QUOTA_ROOT)).block()).isEqualTo(QuotaCountUsage.count(10));
+ softly.assertThat(Mono.from(testee.getCurrentStorage(QUOTA_ROOT)).block()).isEqualTo(QuotaSizeUsage.size(100));
+ }));
}
@Test
void decreaseShouldNotFailWhenItLeadsToNegativeValues() throws Exception {
testee.decrease(new QuotaOperation(QUOTA_ROOT, QuotaCountUsage.count(10), QuotaSizeUsage.size(100))).block();
- assertThat(Mono.from(testee.getCurrentMessageCount(QUOTA_ROOT)).block()).isEqualTo(QuotaCountUsage.count(-10));
- assertThat(Mono.from(testee.getCurrentStorage(QUOTA_ROOT)).block()).isEqualTo(QuotaSizeUsage.size(-100));
+ SoftAssertions.assertSoftly(Throwing.consumer(softly -> {
+ softly.assertThat(Mono.from(testee.getCurrentQuotas(QUOTA_ROOT)).block())
+ .isEqualTo(new CurrentQuotas(QuotaCountUsage.count(-10), QuotaSizeUsage.size(-100)));
+ softly.assertThat(Mono.from(testee.getCurrentMessageCount(QUOTA_ROOT)).block()).isEqualTo(QuotaCountUsage.count(-10));
+ softly.assertThat(Mono.from(testee.getCurrentStorage(QUOTA_ROOT)).block()).isEqualTo(QuotaSizeUsage.size(-100));
+ }));
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org