This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch james-3926-mailbox-current-quotas
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 85bef866fb552c5935b0273782f232dae61e2806
Author: Rene Cordier <[email protected]>
AuthorDate: Fri Aug 25 15:36:21 2023 +0700

    JAMES-3926 Implement CassandraCurrentQuotaManagerV2
---
 .../quota/CassandraCurrentQuotaManagerV2.java      | 115 +++++++++++++++++++++
 .../quota/CassandraCurrentQuotaManagerV2Test.java  |  46 +++++++++
 2 files changed, 161 insertions(+)

diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraCurrentQuotaManagerV2.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraCurrentQuotaManagerV2.java
new file mode 100644
index 0000000000..7eb85da2b0
--- /dev/null
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraCurrentQuotaManagerV2.java
@@ -0,0 +1,115 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.quota;
+
+import java.util.function.Predicate;
+
+import javax.inject.Inject;
+
+import 
org.apache.james.backends.cassandra.components.CassandraQuotaCurrentValueDao;
+import 
org.apache.james.backends.cassandra.components.CassandraQuotaCurrentValueDao.QuotaKey;
+import org.apache.james.core.quota.QuotaComponent;
+import org.apache.james.core.quota.QuotaCountUsage;
+import org.apache.james.core.quota.QuotaCurrentValue;
+import org.apache.james.core.quota.QuotaSizeUsage;
+import org.apache.james.core.quota.QuotaType;
+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.quota.CurrentQuotaManager;
+
+import reactor.core.publisher.Mono;
+
+public class CassandraCurrentQuotaManagerV2 implements CurrentQuotaManager {
+    private final CassandraQuotaCurrentValueDao currentValueDao;
+
+    @Inject
+    public CassandraCurrentQuotaManagerV2(CassandraQuotaCurrentValueDao 
currentValueDao) {
+        this.currentValueDao = currentValueDao;
+    }
+
+    @Override
+    public Mono<QuotaCountUsage> getCurrentMessageCount(QuotaRoot quotaRoot) {
+        return currentValueDao.getQuotaCurrentValue(asQuotaKeyCount(quotaRoot))
+            .map(QuotaCurrentValue::getCurrentValue)
+            .map(QuotaCountUsage::count)
+            .defaultIfEmpty(QuotaCountUsage.count(0L));
+    }
+
+    @Override
+    public Mono<QuotaSizeUsage> getCurrentStorage(QuotaRoot quotaRoot) {
+        return currentValueDao.getQuotaCurrentValue(asQuotaKeySize(quotaRoot))
+            .map(QuotaCurrentValue::getCurrentValue)
+            .map(QuotaSizeUsage::size)
+            .defaultIfEmpty(QuotaSizeUsage.size(0L));
+    }
+
+    @Override
+    public Mono<CurrentQuotas> getCurrentQuotas(QuotaRoot quotaRoot) {
+        return Mono.zip(
+                getCurrentMessageCount(quotaRoot),
+                getCurrentStorage(quotaRoot))
+            .map(tuple2 -> new CurrentQuotas(tuple2.getT1(), tuple2.getT2()));
+    }
+
+    @Override
+    public Mono<Void> increase(QuotaOperation quotaOperation) {
+        return 
currentValueDao.increase(asQuotaKeyCount(quotaOperation.quotaRoot()), 
quotaOperation.count().asLong())
+            
.then(currentValueDao.increase(asQuotaKeySize(quotaOperation.quotaRoot()), 
quotaOperation.size().asLong()));
+    }
+
+    @Override
+    public Mono<Void> decrease(QuotaOperation quotaOperation) {
+        return decrease(quotaOperation.quotaRoot(), quotaOperation.count(), 
quotaOperation.size());
+    }
+
+    private Mono<Void> decrease(QuotaRoot quotaRoot, QuotaCountUsage count, 
QuotaSizeUsage size) {
+        return currentValueDao.decrease(asQuotaKeyCount(quotaRoot), 
count.asLong())
+            .then(currentValueDao.decrease(asQuotaKeySize(quotaRoot), 
size.asLong()));
+    }
+
+    @Override
+    public Mono<Void> setCurrentQuotas(QuotaOperation quotaOperation) {
+        return getCurrentQuotas(quotaOperation.quotaRoot())
+            
.filter(Predicate.not(Predicate.isEqual(CurrentQuotas.from(quotaOperation))))
+            .flatMap(storedQuotas -> {
+                long count = quotaOperation.count().asLong() - 
storedQuotas.count().asLong();
+                long size = quotaOperation.size().asLong() - 
storedQuotas.size().asLong();
+
+                return 
currentValueDao.increase(asQuotaKeyCount(quotaOperation.quotaRoot()), count)
+                    
.then(currentValueDao.increase(asQuotaKeySize(quotaOperation.quotaRoot()), 
size));
+            });
+    }
+
+    private QuotaKey asQuotaKeyCount(QuotaRoot quotaRoot) {
+        return asQuotaKey(quotaRoot, QuotaType.COUNT);
+    }
+
+    private QuotaKey asQuotaKeySize(QuotaRoot quotaRoot) {
+        return asQuotaKey(quotaRoot, QuotaType.SIZE);
+    }
+
+    private QuotaKey asQuotaKey(QuotaRoot quotaRoot, QuotaType quotaType) {
+        return QuotaKey.of(
+            QuotaComponent.MAILBOX,
+            quotaRoot.asString(),
+            quotaType);
+    }
+}
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/CassandraCurrentQuotaManagerV2Test.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/CassandraCurrentQuotaManagerV2Test.java
new file mode 100644
index 0000000000..80750f0c96
--- /dev/null
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/CassandraCurrentQuotaManagerV2Test.java
@@ -0,0 +1,46 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.cassandra.quota;
+
+import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import 
org.apache.james.backends.cassandra.components.CassandraMutualizedQuotaModule;
+import 
org.apache.james.backends.cassandra.components.CassandraQuotaCurrentValueDao;
+import org.apache.james.mailbox.quota.CurrentQuotaManager;
+import org.apache.james.mailbox.store.quota.CurrentQuotaManagerContract;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+public class CassandraCurrentQuotaManagerV2Test implements 
CurrentQuotaManagerContract {
+    @RegisterExtension
+    static CassandraClusterExtension cassandraCluster = new 
CassandraClusterExtension(CassandraMutualizedQuotaModule.MODULE);
+
+    private CassandraCurrentQuotaManagerV2 currentQuotaManager;
+
+    @BeforeEach
+    void setUp(CassandraCluster cassandra) {
+        currentQuotaManager = new CassandraCurrentQuotaManagerV2(new 
CassandraQuotaCurrentValueDao(cassandra.getConf()));
+    }
+
+    @Override
+    public CurrentQuotaManager testee() {
+        return currentQuotaManager;
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to