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

Reply via email to