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 273129e75e2312c4e68ea5e8124a751cf6326262 Author: Rene Cordier <rcord...@linagora.com> AuthorDate: Fri Apr 10 16:07:16 2020 +0700 JAMES-3138 Allow resetting current quotas --- .../apache/james/mailbox/model/CurrentQuotas.java | 4 ++ .../apache/james/mailbox/model/QuotaOperation.java | 4 +- .../james/mailbox/model/QuotaOperationTest.java | 13 +++--- .../mailbox/jpa/quota/JpaCurrentQuotaManager.java | 14 ++++++ .../store/quota/StoreCurrentQuotaManager.java | 12 ++++++ .../store/quota/StoreCurrentQuotaManagerTest.java | 50 +++++++++++++++++++--- 6 files changed, 84 insertions(+), 13 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 3b82866..38acbaf 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 @@ -32,6 +32,10 @@ public class CurrentQuotas { return new CurrentQuotas(QuotaCountUsage.count(0L), QuotaSizeUsage.size(0L)); } + public static CurrentQuotas from(QuotaOperation quotaOperation) { + return new CurrentQuotas(quotaOperation.count(), quotaOperation.size()); + } + public CurrentQuotas(QuotaCountUsage count, QuotaSizeUsage size) { this.count = count; this.size = size; diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/QuotaOperation.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/QuotaOperation.java index f788c40..7fbd3ba 100644 --- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/QuotaOperation.java +++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/QuotaOperation.java @@ -32,8 +32,8 @@ public class QuotaOperation { private final QuotaSizeUsage size; public QuotaOperation(QuotaRoot quotaRoot, QuotaCountUsage count, QuotaSizeUsage size) { - Preconditions.checkArgument(count.asLong() > 0, "Count should be strictly positive"); - Preconditions.checkArgument(size.asLong() > 0, "Size should be strictly positive"); + Preconditions.checkArgument(count.asLong() >= 0, "Count should be positive"); + Preconditions.checkArgument(size.asLong() >= 0, "Size should be positive"); this.quotaRoot = quotaRoot; this.count = count; diff --git a/mailbox/api/src/test/java/org/apache/james/mailbox/model/QuotaOperationTest.java b/mailbox/api/src/test/java/org/apache/james/mailbox/model/QuotaOperationTest.java index 2a71822..2383c36 100644 --- a/mailbox/api/src/test/java/org/apache/james/mailbox/model/QuotaOperationTest.java +++ b/mailbox/api/src/test/java/org/apache/james/mailbox/model/QuotaOperationTest.java @@ -19,6 +19,7 @@ package org.apache.james.mailbox.model; +import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.Optional; @@ -39,9 +40,9 @@ class QuotaOperationTest { } @Test - void shouldThrowWhenCountIsZero() { - assertThatThrownBy(() -> new QuotaOperation(QUOTA_ROOT, QuotaCountUsage.count(0), QuotaSizeUsage.size(5))) - .isInstanceOf(IllegalArgumentException.class); + void shouldNotThrowWhenCountIsZero() { + assertThatCode(() -> new QuotaOperation(QUOTA_ROOT, QuotaCountUsage.count(0), QuotaSizeUsage.size(5))) + .doesNotThrowAnyException(); } @Test @@ -51,9 +52,9 @@ class QuotaOperationTest { } @Test - void shouldThrowWhenSizeIsZero() { - assertThatThrownBy(() -> new QuotaOperation(QUOTA_ROOT, QuotaCountUsage.count(5), QuotaSizeUsage.size(0))) - .isInstanceOf(IllegalArgumentException.class); + void shouldNotThrowWhenSizeIsZero() { + assertThatCode(() -> new QuotaOperation(QUOTA_ROOT, QuotaCountUsage.count(5), QuotaSizeUsage.size(0))) + .doesNotThrowAnyException(); } @Test 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 f79f4a1..d2f57ec 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 @@ -107,6 +107,20 @@ public class JpaCurrentQuotaManager implements StoreCurrentQuotaManager { })); } + @Override + public Mono<Void> resetCurrentQuotas(QuotaOperation quotaOperation) { + return Mono.fromCallable(() -> getCurrentQuotas(quotaOperation.quotaRoot())) + .flatMap(storedQuotas -> Mono.fromRunnable(() -> + transactionRunner.run( + entityManager -> { + if (!storedQuotas.equals(CurrentQuotas.from(quotaOperation))) { + entityManager.merge(new JpaCurrentQuota(quotaOperation.quotaRoot().getValue(), + quotaOperation.count().asLong(), + quotaOperation.size().asLong())); + } + }))); + } + private JpaCurrentQuota retrieveUserQuota(EntityManager entityManager, QuotaRoot quotaRoot) { return entityManager.find(JpaCurrentQuota.class, quotaRoot.getValue()); } diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/StoreCurrentQuotaManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/StoreCurrentQuotaManager.java index 5d6cb08..3891326 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/StoreCurrentQuotaManager.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/quota/StoreCurrentQuotaManager.java @@ -19,6 +19,7 @@ package org.apache.james.mailbox.store.quota; +import org.apache.james.mailbox.model.CurrentQuotas; import org.apache.james.mailbox.model.QuotaOperation; import org.apache.james.mailbox.quota.CurrentQuotaManager; @@ -30,4 +31,15 @@ public interface StoreCurrentQuotaManager extends CurrentQuotaManager { Mono<Void> decrease(QuotaOperation quotaOperation); + default Mono<Void> resetCurrentQuotas(QuotaOperation quotaOperation) { + return Mono.from(getCurrentQuotas(quotaOperation.quotaRoot())) + .flatMap(storedQuotas -> { + if (!storedQuotas.equals(CurrentQuotas.from(quotaOperation))) { + return decrease(new QuotaOperation(quotaOperation.quotaRoot(), storedQuotas.count(), storedQuotas.size())) + .then(increase(quotaOperation)); + } + return Mono.empty(); + }); + } + } 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 74ca11c..4ba155c 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 @@ -39,6 +39,7 @@ 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)); + private static final QuotaOperation RESET_QUOTA_OPERATION = new QuotaOperation(QUOTA_ROOT, QuotaCountUsage.count(10), QuotaSizeUsage.size(100)); protected abstract StoreCurrentQuotaManager provideTestee(); @@ -50,12 +51,12 @@ public abstract class StoreCurrentQuotaManagerTest { } @Test - void getCurrentStorageShouldReturnZeroByDefault() throws Exception { + void getCurrentStorageShouldReturnZeroByDefault() { assertThat(Mono.from(testee.getCurrentStorage(QUOTA_ROOT)).block()).isEqualTo(QuotaSizeUsage.size(0)); } @Test - void getCurrentMessageCountShouldReturnZeroByDefault() throws Exception { + void getCurrentMessageCountShouldReturnZeroByDefault() { assertThat(Mono.from(testee.getCurrentMessageCount(QUOTA_ROOT)).block()).isEqualTo(QuotaCountUsage.count(0)); } @@ -65,7 +66,7 @@ public abstract class StoreCurrentQuotaManagerTest { } @Test - void increaseShouldWork() throws Exception { + void increaseShouldWork() { testee.increase(new QuotaOperation(QUOTA_ROOT, QuotaCountUsage.count(10), QuotaSizeUsage.size(100))).block(); SoftAssertions.assertSoftly(Throwing.consumer(softly -> { @@ -76,7 +77,7 @@ public abstract class StoreCurrentQuotaManagerTest { } @Test - void decreaseShouldWork() throws Exception { + void decreaseShouldWork() { testee.increase(new QuotaOperation(QUOTA_ROOT, QuotaCountUsage.count(20), QuotaSizeUsage.size(200))).block(); testee.decrease(new QuotaOperation(QUOTA_ROOT, QuotaCountUsage.count(10), QuotaSizeUsage.size(100))).block(); @@ -89,7 +90,7 @@ public abstract class StoreCurrentQuotaManagerTest { } @Test - void decreaseShouldNotFailWhenItLeadsToNegativeValues() throws Exception { + void decreaseShouldNotFailWhenItLeadsToNegativeValues() { testee.decrease(new QuotaOperation(QUOTA_ROOT, QuotaCountUsage.count(10), QuotaSizeUsage.size(100))).block(); SoftAssertions.assertSoftly(Throwing.consumer(softly -> { @@ -99,4 +100,43 @@ public abstract class StoreCurrentQuotaManagerTest { softly.assertThat(Mono.from(testee.getCurrentStorage(QUOTA_ROOT)).block()).isEqualTo(QuotaSizeUsage.size(-100)); })); } + + @Test + void resetCurrentQuotasShouldNoopWhenZeroAndNoData() { + QuotaOperation quotaOperation = new QuotaOperation(QUOTA_ROOT, QuotaCountUsage.count(0), QuotaSizeUsage.size(0)); + + testee.resetCurrentQuotas(quotaOperation).block(); + + assertThat(Mono.from(testee.getCurrentQuotas(QUOTA_ROOT)).block()) + .isEqualTo(CurrentQuotas.emptyQuotas()); + } + + @Test + void resetCurrentQuotasShouldReInitQuotasWhenNothing() { + testee.resetCurrentQuotas(RESET_QUOTA_OPERATION).block(); + + assertThat(Mono.from(testee.getCurrentQuotas(QUOTA_ROOT)).block()) + .isEqualTo(CURRENT_QUOTAS); + } + + @Test + void resetCurrentQuotasShouldReInitQuotasWhenData() { + testee.increase(new QuotaOperation(QUOTA_ROOT, QuotaCountUsage.count(20), QuotaSizeUsage.size(200))).block(); + + testee.resetCurrentQuotas(RESET_QUOTA_OPERATION).block(); + + assertThat(Mono.from(testee.getCurrentQuotas(QUOTA_ROOT)).block()) + .isEqualTo(CURRENT_QUOTAS); + } + + @Test + void resetCurrentQuotasShouldBeIdempotent() { + testee.increase(new QuotaOperation(QUOTA_ROOT, QuotaCountUsage.count(20), QuotaSizeUsage.size(200))).block(); + + testee.resetCurrentQuotas(RESET_QUOTA_OPERATION).block(); + testee.resetCurrentQuotas(RESET_QUOTA_OPERATION).block(); + + assertThat(Mono.from(testee.getCurrentQuotas(QUOTA_ROOT)).block()) + .isEqualTo(CURRENT_QUOTAS); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org