You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by rc...@apache.org on 2023/08/23 09:34:01 UTC

[james-project] branch master updated: JAMES-4840 refactor quota for cassandra: create cassandra DAOs (#1673)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 5243d007fc JAMES-4840 refactor quota for cassandra: create cassandra DAOs (#1673)
5243d007fc is described below

commit 5243d007fcfd934f92ca4c14674a300ce3f77a56
Author: hungphan227 <45...@users.noreply.github.com>
AuthorDate: Wed Aug 23 16:33:55 2023 +0700

    JAMES-4840 refactor quota for cassandra: create cassandra DAOs (#1673)
---
 .../apache/james/core/quota/QuotaCurrentValue.java |  12 +-
 .../cassandra/modules/CassandraQuotaModule.java    |  23 +++
 .../quota/CassandraQuotaCurrentValueDao.java       | 205 ++++++++++++++++++++
 .../cassandra/quota/CassandraQuotaLimitDao.java    | 209 +++++++++++++++++++++
 .../table/CassandraQuotaCurrentValueTable.java     |  31 +++
 .../cassandra/table/CassandraQuotaLimitTable.java  |  32 ++++
 .../quota/CassandraQuotaCurrentValueDaoTest.java   | 136 ++++++++++++++
 .../quota/CassandraQuotaLimitDaoTest.java          |  91 +++++++++
 .../modules/mailbox/CassandraQuotaModule.java      |   4 +
 9 files changed, 736 insertions(+), 7 deletions(-)

diff --git a/core/src/main/java/org/apache/james/core/quota/QuotaCurrentValue.java b/core/src/main/java/org/apache/james/core/quota/QuotaCurrentValue.java
index 22f6b3f004..682f10c7bc 100644
--- a/core/src/main/java/org/apache/james/core/quota/QuotaCurrentValue.java
+++ b/core/src/main/java/org/apache/james/core/quota/QuotaCurrentValue.java
@@ -21,8 +21,6 @@ package org.apache.james.core.quota;
 
 import java.util.Objects;
 
-import org.apache.james.core.Username;
-
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
 
@@ -30,7 +28,7 @@ public class QuotaCurrentValue {
 
     public static class Builder {
         private QuotaComponent quotaComponent;
-        private Username identifier;
+        private String identifier;
         private QuotaType quotaType;
         private long currentValue;
 
@@ -39,7 +37,7 @@ public class QuotaCurrentValue {
             return this;
         }
 
-        public Builder identifier(Username identifier) {
+        public Builder identifier(String identifier) {
             this.identifier = identifier;
             return this;
         }
@@ -68,11 +66,11 @@ public class QuotaCurrentValue {
     }
 
     private final QuotaComponent quotaComponent;
-    private final Username identifier;
+    private final String identifier;
     private final QuotaType quotaType;
     private final long currentValue;
 
-    private QuotaCurrentValue(QuotaComponent quotaComponent, Username identifier, QuotaType quotaType, long currentValue) {
+    private QuotaCurrentValue(QuotaComponent quotaComponent, String identifier, QuotaType quotaType, long currentValue) {
         this.quotaComponent = quotaComponent;
         this.identifier = identifier;
         this.quotaType = quotaType;
@@ -83,7 +81,7 @@ public class QuotaCurrentValue {
         return quotaComponent;
     }
 
-    public Username getIdentifier() {
+    public String getIdentifier() {
         return identifier;
     }
 
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraQuotaModule.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraQuotaModule.java
index ae44dad59c..9164b27a7a 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraQuotaModule.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/modules/CassandraQuotaModule.java
@@ -30,6 +30,8 @@ import org.apache.james.mailbox.cassandra.table.CassandraCurrentQuota;
 import org.apache.james.mailbox.cassandra.table.CassandraDomainMaxQuota;
 import org.apache.james.mailbox.cassandra.table.CassandraGlobalMaxQuota;
 import org.apache.james.mailbox.cassandra.table.CassandraMaxQuota;
+import org.apache.james.mailbox.cassandra.table.CassandraQuotaCurrentValueTable;
+import org.apache.james.mailbox.cassandra.table.CassandraQuotaLimitTable;
 
 public interface CassandraQuotaModule {
     CassandraModule MODULE = CassandraModule.builder()
@@ -68,5 +70,26 @@ public interface CassandraQuotaModule {
             .withPartitionKey(CassandraGlobalMaxQuota.KEY, TEXT)
             .withColumn(CassandraGlobalMaxQuota.STORAGE, BIGINT)
             .withColumn(CassandraGlobalMaxQuota.MESSAGE, BIGINT))
+
+        .table(CassandraQuotaLimitTable.TABLE_NAME)
+        .comment("Holds quota limits.")
+        .options(options -> options
+            .withCaching(true, rows(CassandraConstants.DEFAULT_CACHED_ROW_PER_PARTITION)))
+        .statement(statement -> types -> statement
+            .withPartitionKey(CassandraQuotaLimitTable.QUOTA_SCOPE, TEXT)
+            .withPartitionKey(CassandraQuotaLimitTable.IDENTIFIER, TEXT)
+            .withClusteringColumn(CassandraQuotaLimitTable.QUOTA_COMPONENT, TEXT)
+            .withClusteringColumn(CassandraQuotaLimitTable.QUOTA_TYPE, TEXT)
+            .withColumn(CassandraQuotaLimitTable.QUOTA_LIMIT, BIGINT))
+
+        .table(CassandraQuotaCurrentValueTable.TABLE_NAME)
+        .comment("Holds quota current values.")
+        .options(options -> options
+            .withCaching(true, rows(CassandraConstants.DEFAULT_CACHED_ROW_PER_PARTITION)))
+        .statement(statement -> types -> statement
+            .withPartitionKey(CassandraQuotaCurrentValueTable.IDENTIFIER, TEXT)
+            .withClusteringColumn(CassandraQuotaCurrentValueTable.QUOTA_COMPONENT, TEXT)
+            .withClusteringColumn(CassandraQuotaCurrentValueTable.QUOTA_TYPE, TEXT)
+            .withColumn(CassandraQuotaCurrentValueTable.CURRENT_VALUE, COUNTER))
         .build();
 }
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaCurrentValueDao.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaCurrentValueDao.java
new file mode 100644
index 0000000000..4a5546a8cc
--- /dev/null
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaCurrentValueDao.java
@@ -0,0 +1,205 @@
+/****************************************************************
+ * 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 static com.datastax.oss.driver.api.querybuilder.QueryBuilder.bindMarker;
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.deleteFrom;
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.selectFrom;
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.update;
+import static com.datastax.oss.driver.api.querybuilder.relation.Relation.column;
+import static org.apache.james.mailbox.cassandra.table.CassandraQuotaCurrentValueTable.CURRENT_VALUE;
+import static org.apache.james.mailbox.cassandra.table.CassandraQuotaCurrentValueTable.IDENTIFIER;
+import static org.apache.james.mailbox.cassandra.table.CassandraQuotaCurrentValueTable.QUOTA_COMPONENT;
+import static org.apache.james.mailbox.cassandra.table.CassandraQuotaCurrentValueTable.QUOTA_TYPE;
+import static org.apache.james.mailbox.cassandra.table.CassandraQuotaCurrentValueTable.TABLE_NAME;
+
+import java.util.Objects;
+
+import javax.inject.Inject;
+
+import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
+import org.apache.james.core.quota.QuotaComponent;
+import org.apache.james.core.quota.QuotaCurrentValue;
+import org.apache.james.core.quota.QuotaType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.datastax.oss.driver.api.core.CqlSession;
+import com.datastax.oss.driver.api.core.cql.PreparedStatement;
+import com.datastax.oss.driver.api.core.cql.Row;
+import com.datastax.oss.driver.api.querybuilder.delete.Delete;
+import com.datastax.oss.driver.api.querybuilder.select.Select;
+import com.datastax.oss.driver.api.querybuilder.update.Update;
+import com.google.common.base.MoreObjects;
+
+import reactor.core.publisher.Mono;
+
+public class CassandraQuotaCurrentValueDao {
+
+    public static class QuotaKey {
+
+        public static QuotaKey of(QuotaComponent component, String identifier, QuotaType quotaType) {
+            return new QuotaKey(component, identifier, quotaType);
+        }
+
+        private final QuotaComponent quotaComponent;
+        private final String identifier;
+        private final QuotaType quotaType;
+
+        public QuotaComponent getQuotaComponent() {
+            return quotaComponent;
+        }
+
+        public String getIdentifier() {
+            return identifier;
+        }
+
+        public QuotaType getQuotaType() {
+            return quotaType;
+        }
+
+        private QuotaKey(QuotaComponent quotaComponent, String identifier, QuotaType quotaType) {
+            this.quotaComponent = quotaComponent;
+            this.identifier = identifier;
+            this.quotaType = quotaType;
+        }
+
+        @Override
+        public final int hashCode() {
+            return Objects.hash(quotaComponent, identifier, quotaType);
+        }
+
+        @Override
+        public final boolean equals(Object o) {
+            if (o instanceof QuotaKey) {
+                QuotaKey other = (QuotaKey) o;
+                return Objects.equals(quotaComponent, other.quotaComponent)
+                    && Objects.equals(identifier, other.identifier)
+                    && Objects.equals(quotaType, other.quotaType);
+            }
+            return false;
+        }
+
+        public String toString() {
+            return MoreObjects.toStringHelper(this)
+                .add("quotaComponent", quotaComponent)
+                .add("identifier", identifier)
+                .add("quotaType", quotaType)
+                .toString();
+        }
+    }
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(CassandraQuotaCurrentValueDao.class);
+
+    private final CassandraAsyncExecutor queryExecutor;
+    private final PreparedStatement increaseStatement;
+    private final PreparedStatement decreaseStatement;
+    private final PreparedStatement getQuotaCurrentValueStatement;
+    private final PreparedStatement deleteQuotaCurrentValueStatement;
+
+    @Inject
+    public CassandraQuotaCurrentValueDao(CqlSession session) {
+        this.queryExecutor = new CassandraAsyncExecutor(session);
+        this.increaseStatement = session.prepare(increaseStatement().build());
+        this.decreaseStatement = session.prepare(decreaseStatement().build());
+        this.getQuotaCurrentValueStatement = session.prepare(getQuotaCurrentValueStatement().build());
+        this.deleteQuotaCurrentValueStatement = session.prepare(deleteQuotaCurrentValueStatement().build());
+    }
+
+    public Mono<Void> increase(QuotaKey quotaKey, long amount) {
+        return queryExecutor.executeVoid(increaseStatement.bind()
+            .setString(QUOTA_COMPONENT, quotaKey.getQuotaComponent().getValue())
+            .setString(IDENTIFIER, quotaKey.getIdentifier())
+            .setString(QUOTA_TYPE, quotaKey.getQuotaType().getValue())
+            .setLong(CURRENT_VALUE, amount))
+            .onErrorResume(ex -> {
+                LOGGER.warn("Failure when increasing {} {} quota for {}. Quota current value is thus not updated and needs recomputation",
+                    quotaKey.getQuotaComponent().getValue(), quotaKey.getQuotaType().getValue(), quotaKey.getIdentifier(), ex);
+                return Mono.empty();
+            });
+    }
+
+    public Mono<Void> decrease(QuotaKey quotaKey, long amount) {
+        return queryExecutor.executeVoid(decreaseStatement.bind()
+            .setString(QUOTA_COMPONENT, quotaKey.getQuotaComponent().getValue())
+            .setString(IDENTIFIER, quotaKey.getIdentifier())
+            .setString(QUOTA_TYPE, quotaKey.getQuotaType().getValue())
+            .setLong(CURRENT_VALUE, amount))
+            .onErrorResume(ex -> {
+                LOGGER.warn("Failure when decreasing {} {} quota for {}. Quota current value is thus not updated and needs recomputation",
+                    quotaKey.getQuotaComponent().getValue(), quotaKey.getQuotaType().getValue(), quotaKey.getIdentifier(), ex);
+                return Mono.empty();
+            });
+    }
+
+    public Mono<QuotaCurrentValue> getQuotaCurrentValue(QuotaKey quotaKey) {
+        return queryExecutor.executeSingleRow(getQuotaCurrentValueStatement.bind()
+            .setString(QUOTA_COMPONENT, quotaKey.getQuotaComponent().getValue())
+            .setString(IDENTIFIER, quotaKey.getIdentifier())
+            .setString(QUOTA_TYPE, quotaKey.getQuotaType().getValue()))
+            .map(row -> convertRowToModel(row));
+    }
+
+    public Mono<Void> deleteQuotaCurrentValue(QuotaKey quotaKey) {
+        return queryExecutor.executeVoid(deleteQuotaCurrentValueStatement.bind()
+            .setString(QUOTA_COMPONENT, quotaKey.getQuotaComponent().getValue())
+            .setString(IDENTIFIER, quotaKey.getIdentifier())
+            .setString(QUOTA_TYPE, quotaKey.getQuotaType().getValue()));
+    }
+
+    private Update increaseStatement() {
+        return update(TABLE_NAME)
+            .increment(CURRENT_VALUE, bindMarker(CURRENT_VALUE))
+            .where(column(IDENTIFIER).isEqualTo(bindMarker(IDENTIFIER)),
+                column(QUOTA_COMPONENT).isEqualTo(bindMarker(QUOTA_COMPONENT)),
+                column(QUOTA_TYPE).isEqualTo(bindMarker(QUOTA_TYPE)));
+    }
+
+    private Update decreaseStatement() {
+        return update(TABLE_NAME)
+            .decrement(CURRENT_VALUE, bindMarker(CURRENT_VALUE))
+            .where(column(IDENTIFIER).isEqualTo(bindMarker(IDENTIFIER)),
+                column(QUOTA_COMPONENT).isEqualTo(bindMarker(QUOTA_COMPONENT)),
+                column(QUOTA_TYPE).isEqualTo(bindMarker(QUOTA_TYPE)));
+    }
+
+    private Select getQuotaCurrentValueStatement() {
+        return selectFrom(TABLE_NAME)
+            .all()
+            .where(column(IDENTIFIER).isEqualTo(bindMarker(IDENTIFIER)),
+                column(QUOTA_COMPONENT).isEqualTo(bindMarker(QUOTA_COMPONENT)),
+                column(QUOTA_TYPE).isEqualTo(bindMarker(QUOTA_TYPE)));
+    }
+
+    private Delete deleteQuotaCurrentValueStatement() {
+        return deleteFrom(TABLE_NAME)
+            .where(column(IDENTIFIER).isEqualTo(bindMarker(IDENTIFIER)),
+                column(QUOTA_COMPONENT).isEqualTo(bindMarker(QUOTA_COMPONENT)),
+                column(QUOTA_TYPE).isEqualTo(bindMarker(QUOTA_TYPE)));
+    }
+
+    private QuotaCurrentValue convertRowToModel(Row row) {
+        return QuotaCurrentValue.builder().quotaComponent(QuotaComponent.of(row.get(QUOTA_COMPONENT, String.class)))
+            .identifier(row.get(IDENTIFIER, String.class))
+            .quotaType(QuotaType.of(row.get(QUOTA_TYPE, String.class)))
+            .currentValue(row.get(CURRENT_VALUE, Long.class)).build();
+    }
+
+}
\ No newline at end of file
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaLimitDao.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaLimitDao.java
new file mode 100644
index 0000000000..6062eebb6f
--- /dev/null
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaLimitDao.java
@@ -0,0 +1,209 @@
+/****************************************************************
+ * 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 static com.datastax.oss.driver.api.querybuilder.QueryBuilder.bindMarker;
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.deleteFrom;
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.selectFrom;
+import static com.datastax.oss.driver.api.querybuilder.relation.Relation.column;
+import static org.apache.james.mailbox.cassandra.table.CassandraQuotaLimitTable.IDENTIFIER;
+import static org.apache.james.mailbox.cassandra.table.CassandraQuotaLimitTable.QUOTA_COMPONENT;
+import static org.apache.james.mailbox.cassandra.table.CassandraQuotaLimitTable.QUOTA_LIMIT;
+import static org.apache.james.mailbox.cassandra.table.CassandraQuotaLimitTable.QUOTA_SCOPE;
+import static org.apache.james.mailbox.cassandra.table.CassandraQuotaLimitTable.QUOTA_TYPE;
+import static org.apache.james.mailbox.cassandra.table.CassandraQuotaLimitTable.TABLE_NAME;
+
+import java.util.Objects;
+
+import javax.inject.Inject;
+
+import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
+import org.apache.james.core.quota.QuotaComponent;
+import org.apache.james.core.quota.QuotaLimit;
+import org.apache.james.core.quota.QuotaScope;
+import org.apache.james.core.quota.QuotaType;
+
+import com.datastax.oss.driver.api.core.CqlSession;
+import com.datastax.oss.driver.api.core.cql.PreparedStatement;
+import com.datastax.oss.driver.api.core.cql.Row;
+import com.datastax.oss.driver.api.querybuilder.delete.Delete;
+import com.datastax.oss.driver.api.querybuilder.insert.Insert;
+import com.datastax.oss.driver.api.querybuilder.select.Select;
+import com.google.common.base.MoreObjects;
+
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+public class CassandraQuotaLimitDao {
+
+    public static class QuotaLimitKey {
+
+        public static QuotaLimitKey of(QuotaComponent component, QuotaScope scope, String identifier, QuotaType quotaType) {
+            return new QuotaLimitKey(component, scope, identifier, quotaType);
+        }
+
+        private final QuotaComponent quotaComponent;
+        private final QuotaScope quotaScope;
+        private final String identifier;
+        private final QuotaType quotaType;
+
+        public QuotaComponent getQuotaComponent() {
+            return quotaComponent;
+        }
+
+        public QuotaScope getQuotaScope() {
+            return quotaScope;
+        }
+
+        public String getIdentifier() {
+            return identifier;
+        }
+
+        public QuotaType getQuotaType() {
+            return quotaType;
+        }
+
+        private QuotaLimitKey(QuotaComponent quotaComponent, QuotaScope quotaScope, String identifier, QuotaType quotaType) {
+            this.quotaComponent = quotaComponent;
+            this.quotaScope = quotaScope;
+            this.identifier = identifier;
+            this.quotaType = quotaType;
+        }
+
+        @Override
+        public final int hashCode() {
+            return Objects.hash(quotaComponent, quotaScope, identifier, quotaType);
+        }
+
+        @Override
+        public final boolean equals(Object o) {
+            if (o instanceof QuotaLimitKey) {
+                QuotaLimitKey other = (QuotaLimitKey) o;
+                return Objects.equals(quotaComponent, other.quotaComponent)
+                    && Objects.equals(quotaScope, other.quotaScope)
+                    && Objects.equals(identifier, other.identifier)
+                    && Objects.equals(quotaType, other.quotaType);
+            }
+            return false;
+        }
+
+        public String toString() {
+            return MoreObjects.toStringHelper(this)
+                .add("quotaComponent", quotaComponent)
+                .add("quotaScope", quotaScope)
+                .add("identifier", identifier)
+                .add("quotaType", quotaType)
+                .toString();
+        }
+    }
+
+    private final CassandraAsyncExecutor queryExecutor;
+    private final PreparedStatement getQuotaLimitStatement;
+    private final PreparedStatement getQuotaLimitsStatement;
+    private final PreparedStatement setQuotaLimitStatement;
+    private final PreparedStatement deleteQuotaLimitStatement;
+
+    @Inject
+    public CassandraQuotaLimitDao(CqlSession session) {
+        this.queryExecutor = new CassandraAsyncExecutor(session);
+        this.getQuotaLimitStatement = session.prepare(getQuotaLimitStatement().build());
+        this.getQuotaLimitsStatement = session.prepare(getQuotaLimitsStatement().build());
+        this.setQuotaLimitStatement = session.prepare(setQuotaLimitStatement().build());
+        this.deleteQuotaLimitStatement = session.prepare((deleteQuotaLimitStatement().build()));
+    }
+
+    public Mono<QuotaLimit> getQuotaLimit(QuotaLimitKey quotaKey) {
+        return queryExecutor.executeSingleRow(getQuotaLimitStatement.bind()
+            .setString(QUOTA_COMPONENT, quotaKey.getQuotaComponent().getValue())
+            .setString(QUOTA_SCOPE, quotaKey.getQuotaScope().getValue())
+            .setString(IDENTIFIER, quotaKey.getIdentifier())
+            .setString(QUOTA_TYPE, quotaKey.getQuotaType().getValue()))
+            .map(row -> convertRowToModel(row));
+    }
+
+    public Flux<QuotaLimit> getQuotaLimits(QuotaComponent quotaComponent, QuotaScope quotaScope, String identifier) {
+        return queryExecutor.executeRows(getQuotaLimitsStatement.bind()
+            .setString(QUOTA_COMPONENT, quotaComponent.getValue())
+            .setString(QUOTA_SCOPE, quotaScope.getValue())
+            .setString(IDENTIFIER, identifier))
+            .map(row -> convertRowToModel(row));
+    }
+
+    public Mono<Void> setQuotaLimit(QuotaLimit quotaLimit) {
+        return queryExecutor.executeVoid(setQuotaLimitStatement.bind()
+            .setString(QUOTA_COMPONENT, quotaLimit.getQuotaComponent().getValue())
+            .setString(QUOTA_SCOPE, quotaLimit.getQuotaScope().getValue())
+            .setString(IDENTIFIER, quotaLimit.getIdentifier())
+            .setString(QUOTA_TYPE, quotaLimit.getQuotaType().getValue())
+            .setLong(QUOTA_LIMIT, quotaLimit.getQuotaLimit().orElse(null)));
+    }
+
+    public Mono<Void> deleteQuotaLimit(QuotaLimitKey quotaKey) {
+        return queryExecutor.executeVoid(deleteQuotaLimitStatement.bind()
+            .setString(QUOTA_COMPONENT, quotaKey.getQuotaComponent().getValue())
+            .setString(QUOTA_SCOPE, quotaKey.getQuotaScope().getValue())
+            .setString(IDENTIFIER, quotaKey.getIdentifier())
+            .setString(QUOTA_TYPE, quotaKey.getQuotaType().getValue()));
+    }
+
+    private Select getQuotaLimitStatement() {
+        return selectFrom(TABLE_NAME)
+            .all()
+            .where(column(IDENTIFIER).isEqualTo(bindMarker(IDENTIFIER)),
+                column(QUOTA_COMPONENT).isEqualTo(bindMarker(QUOTA_COMPONENT)),
+                column(QUOTA_TYPE).isEqualTo(bindMarker(QUOTA_TYPE)),
+                column(QUOTA_SCOPE).isEqualTo(bindMarker(QUOTA_SCOPE)));
+    }
+
+    private Select getQuotaLimitsStatement() {
+        return selectFrom(TABLE_NAME)
+            .all()
+            .where(column(IDENTIFIER).isEqualTo(bindMarker(IDENTIFIER)),
+                column(QUOTA_COMPONENT).isEqualTo(bindMarker(QUOTA_COMPONENT)),
+                column(QUOTA_SCOPE).isEqualTo(bindMarker(QUOTA_SCOPE)));
+    }
+
+    private Insert setQuotaLimitStatement() {
+        return insertInto(TABLE_NAME)
+            .value(IDENTIFIER, bindMarker(IDENTIFIER))
+            .value(QUOTA_COMPONENT, bindMarker(QUOTA_COMPONENT))
+            .value(QUOTA_TYPE, bindMarker(QUOTA_TYPE))
+            .value(QUOTA_SCOPE, bindMarker(QUOTA_SCOPE))
+            .value(QUOTA_LIMIT, bindMarker(QUOTA_LIMIT));
+    }
+
+    private Delete deleteQuotaLimitStatement() {
+        return deleteFrom(TABLE_NAME)
+            .where(column(IDENTIFIER).isEqualTo(bindMarker(IDENTIFIER)),
+                column(QUOTA_COMPONENT).isEqualTo(bindMarker(QUOTA_COMPONENT)),
+                column(QUOTA_TYPE).isEqualTo(bindMarker(QUOTA_TYPE)),
+                column(QUOTA_SCOPE).isEqualTo(bindMarker(QUOTA_SCOPE)));
+    }
+
+    private QuotaLimit convertRowToModel(Row row) {
+        return QuotaLimit.builder().quotaComponent(QuotaComponent.of(row.get(QUOTA_COMPONENT, String.class)))
+            .quotaScope(QuotaScope.of(row.get(QUOTA_SCOPE, String.class)))
+            .identifier(row.get(IDENTIFIER, String.class))
+            .quotaType(QuotaType.of(row.get(QUOTA_TYPE, String.class)))
+            .quotaLimit(row.get(QUOTA_LIMIT, Long.class)).build();
+    }
+
+}
\ No newline at end of file
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraQuotaCurrentValueTable.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraQuotaCurrentValueTable.java
new file mode 100644
index 0000000000..5d3c088761
--- /dev/null
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraQuotaCurrentValueTable.java
@@ -0,0 +1,31 @@
+/****************************************************************
+ * 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.table;
+
+import com.datastax.oss.driver.api.core.CqlIdentifier;
+
+public interface CassandraQuotaCurrentValueTable {
+    String TABLE_NAME = "quotaCurrentValue";
+
+    CqlIdentifier IDENTIFIER = CqlIdentifier.fromCql("identifier");
+    CqlIdentifier QUOTA_COMPONENT = CqlIdentifier.fromCql("quotaComponent");
+    CqlIdentifier QUOTA_TYPE = CqlIdentifier.fromCql("quotaType");
+    CqlIdentifier CURRENT_VALUE = CqlIdentifier.fromCql("currentValue");
+}
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraQuotaLimitTable.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraQuotaLimitTable.java
new file mode 100644
index 0000000000..b9215e3d31
--- /dev/null
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraQuotaLimitTable.java
@@ -0,0 +1,32 @@
+/****************************************************************
+ * 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.table;
+
+import com.datastax.oss.driver.api.core.CqlIdentifier;
+
+public interface CassandraQuotaLimitTable {
+    String TABLE_NAME = "quotaLimit";
+
+    CqlIdentifier IDENTIFIER = CqlIdentifier.fromCql("identifier");
+    CqlIdentifier QUOTA_COMPONENT = CqlIdentifier.fromCql("quotaComponent");
+    CqlIdentifier QUOTA_TYPE = CqlIdentifier.fromCql("quotaType");
+    CqlIdentifier QUOTA_SCOPE = CqlIdentifier.fromCql("quotaScope");
+    CqlIdentifier QUOTA_LIMIT = CqlIdentifier.fromCql("quotaLimit");
+}
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaCurrentValueDaoTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaCurrentValueDaoTest.java
new file mode 100644
index 0000000000..447cca50c0
--- /dev/null
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaCurrentValueDaoTest.java
@@ -0,0 +1,136 @@
+/****************************************************************
+ * 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 static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatRuntimeException;
+
+import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.core.Username;
+import org.apache.james.core.quota.QuotaComponent;
+import org.apache.james.core.quota.QuotaCurrentValue;
+import org.apache.james.core.quota.QuotaType;
+import org.apache.james.mailbox.cassandra.mail.utils.GuiceUtils;
+import org.apache.james.mailbox.cassandra.modules.CassandraQuotaModule;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+public class CassandraQuotaCurrentValueDaoTest {
+
+    private static final CassandraQuotaCurrentValueDao.QuotaKey QUOTA_KEY
+        = CassandraQuotaCurrentValueDao.QuotaKey.of(QuotaComponent.MAILBOX, "james@abc.com", QuotaType.SIZE);
+
+    private CassandraQuotaCurrentValueDao cassandraQuotaCurrentValueDao;
+
+    @RegisterExtension
+    static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(CassandraModule.aggregateModules(CassandraQuotaModule.MODULE));
+
+    @BeforeEach
+    private void setup() {
+        cassandraQuotaCurrentValueDao = GuiceUtils.testInjector(cassandraCluster.getCassandraCluster()).getInstance(CassandraQuotaCurrentValueDao.class);
+        resetCounterToZero();
+    }
+
+    private void resetCounterToZero() {
+        cassandraQuotaCurrentValueDao.increase(QUOTA_KEY, 0).block();
+        QuotaCurrentValue quotaCurrentValue = cassandraQuotaCurrentValueDao.getQuotaCurrentValue(QUOTA_KEY).block();
+        cassandraQuotaCurrentValueDao.decrease(QUOTA_KEY, quotaCurrentValue.getCurrentValue()).block();
+        QuotaCurrentValue actual = cassandraQuotaCurrentValueDao.getQuotaCurrentValue(QUOTA_KEY).block();
+        assertThat(actual.getCurrentValue()).isEqualTo(0l);
+    }
+
+    @Test
+    void increaseQuotaCurrentValueShouldCreateNewRowSuccessfully() {
+        QuotaCurrentValue expected = QuotaCurrentValue.builder().quotaComponent(QUOTA_KEY.getQuotaComponent())
+            .identifier(QUOTA_KEY.getIdentifier()).quotaType(QUOTA_KEY.getQuotaType()).currentValue(100l).build();
+        cassandraQuotaCurrentValueDao.increase(QUOTA_KEY, 100l).block();
+
+        QuotaCurrentValue actual = cassandraQuotaCurrentValueDao.getQuotaCurrentValue(QUOTA_KEY).block();
+        assertThat(actual).isEqualTo(expected);
+    }
+
+    @Test
+    void increaseQuotaCurrentValueShouldCreateNewRowSuccessfullyWhenIncreaseAmountIsZero() {
+        QuotaCurrentValue expected = QuotaCurrentValue.builder().quotaComponent(QUOTA_KEY.getQuotaComponent())
+            .identifier(QUOTA_KEY.getIdentifier()).quotaType(QUOTA_KEY.getQuotaType()).currentValue(0l).build();
+        cassandraQuotaCurrentValueDao.increase(QUOTA_KEY, 0l).block();
+
+        QuotaCurrentValue actual = cassandraQuotaCurrentValueDao.getQuotaCurrentValue(QUOTA_KEY).block();
+        assertThat(actual).isEqualTo(expected);
+    }
+
+    @Test
+    void increaseQuotaCurrentValueShouldIncreaseValueSuccessfully() {
+        QuotaCurrentValue expected = QuotaCurrentValue.builder().quotaComponent(QUOTA_KEY.getQuotaComponent())
+            .identifier(QUOTA_KEY.getIdentifier()).quotaType(QUOTA_KEY.getQuotaType()).currentValue(200l).build();
+        cassandraQuotaCurrentValueDao.increase(QUOTA_KEY, 100l).block();
+        cassandraQuotaCurrentValueDao.increase(QUOTA_KEY, 100l).block();
+
+        QuotaCurrentValue actual = cassandraQuotaCurrentValueDao.getQuotaCurrentValue(QUOTA_KEY).block();
+        assertThat(actual).isEqualTo(expected);
+    }
+
+    @Test
+    void increaseQuotaCurrentValueShouldDecreaseValueSuccessfullyWhenIncreaseAmountIsNegative() {
+        QuotaCurrentValue expected = QuotaCurrentValue.builder().quotaComponent(QUOTA_KEY.getQuotaComponent())
+            .identifier(QUOTA_KEY.getIdentifier()).quotaType(QUOTA_KEY.getQuotaType()).currentValue(100l).build();
+        cassandraQuotaCurrentValueDao.increase(QUOTA_KEY, 200l).block();
+        cassandraQuotaCurrentValueDao.increase(QUOTA_KEY, -100l).block();
+
+        QuotaCurrentValue actual = cassandraQuotaCurrentValueDao.getQuotaCurrentValue(QUOTA_KEY).block();
+        assertThat(actual).isEqualTo(expected);
+    }
+
+    @Test
+    void decreaseQuotaCurrentValueShouldDecreaseValueSuccessfully() {
+        QuotaCurrentValue expected = QuotaCurrentValue.builder().quotaComponent(QUOTA_KEY.getQuotaComponent())
+            .identifier(QUOTA_KEY.getIdentifier()).quotaType(QUOTA_KEY.getQuotaType()).currentValue(100l).build();
+        cassandraQuotaCurrentValueDao.increase(QUOTA_KEY, 200l).block();
+        cassandraQuotaCurrentValueDao.decrease(QUOTA_KEY, 100l).block();
+
+        QuotaCurrentValue actual = cassandraQuotaCurrentValueDao.getQuotaCurrentValue(QUOTA_KEY).block();
+        assertThat(actual).isEqualTo(expected);
+    }
+
+    @Test
+    void deleteQuotaCurrentValueShouldDeleteSuccessfully() {
+        cassandraQuotaCurrentValueDao.increase(QUOTA_KEY, 100l).block();
+        cassandraQuotaCurrentValueDao.deleteQuotaCurrentValue(QUOTA_KEY).block();
+
+        QuotaCurrentValue actual = cassandraQuotaCurrentValueDao.getQuotaCurrentValue(QUOTA_KEY).block();
+        assertThat(actual).isNull();
+    }
+
+    @Test
+    void increaseQuotaCurrentValueShouldNotThrowExceptionWhenQueryExecutorThrowException() {
+        cassandraCluster.pause();
+        cassandraQuotaCurrentValueDao.increase(QUOTA_KEY, 100l).block();
+        cassandraCluster.unpause();
+    }
+
+    @Test
+    void decreaseQuotaCurrentValueShouldNotThrowExceptionWhenQueryExecutorThrowException() {
+        cassandraCluster.pause();
+        cassandraQuotaCurrentValueDao.decrease(QUOTA_KEY, 100l).block();
+        cassandraCluster.unpause();
+    }
+}
\ No newline at end of file
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaLimitDaoTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaLimitDaoTest.java
new file mode 100644
index 0000000000..15c9f9cdae
--- /dev/null
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/CassandraQuotaLimitDaoTest.java
@@ -0,0 +1,91 @@
+/****************************************************************
+ * 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 static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.blob.cassandra.CassandraBlobModule;
+import org.apache.james.core.quota.QuotaComponent;
+import org.apache.james.core.quota.QuotaLimit;
+import org.apache.james.core.quota.QuotaScope;
+import org.apache.james.core.quota.QuotaType;
+import org.apache.james.mailbox.cassandra.mail.utils.GuiceUtils;
+import org.apache.james.mailbox.cassandra.modules.CassandraQuotaModule;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+public class CassandraQuotaLimitDaoTest {
+
+    private CassandraQuotaLimitDao cassandraQuotaLimitDao;
+
+    @RegisterExtension
+    static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(CassandraModule.aggregateModules(CassandraQuotaModule.MODULE));
+
+    @BeforeEach
+    private void setup() {
+        cassandraQuotaLimitDao = GuiceUtils.testInjector(cassandraCluster.getCassandraCluster()).getInstance(CassandraQuotaLimitDao.class);
+    }
+
+    @Test
+    void getQuotaLimitsShouldGetSomeQuotaLimitsSuccessfully() {
+        QuotaLimit expectedOne = QuotaLimit.builder().quotaComponent(QuotaComponent.MAILBOX).quotaScope(QuotaScope.DOMAIN).identifier("A").quotaType(QuotaType.COUNT).quotaLimit(200l).build();
+        QuotaLimit expectedTwo = QuotaLimit.builder().quotaComponent(QuotaComponent.MAILBOX).quotaScope(QuotaScope.DOMAIN).identifier("A").quotaType(QuotaType.SIZE).quotaLimit(100l).build();
+        cassandraQuotaLimitDao.setQuotaLimit(expectedOne).block();
+        cassandraQuotaLimitDao.setQuotaLimit(expectedTwo).block();
+
+        assertThat(cassandraQuotaLimitDao.getQuotaLimits(QuotaComponent.MAILBOX, QuotaScope.DOMAIN, "A").collectList().block())
+            .containsExactlyInAnyOrder(expectedOne, expectedTwo);
+    }
+
+    @Test
+    void setQuotaLimitShouldSaveObjectSuccessfully() {
+        QuotaLimit expected = QuotaLimit.builder().quotaComponent(QuotaComponent.MAILBOX).quotaScope(QuotaScope.DOMAIN).identifier("A").quotaType(QuotaType.COUNT).quotaLimit(100l).build();
+        cassandraQuotaLimitDao.setQuotaLimit(expected).block();
+
+        assertThat(cassandraQuotaLimitDao.getQuotaLimit(CassandraQuotaLimitDao.QuotaLimitKey.of(QuotaComponent.MAILBOX, QuotaScope.DOMAIN, "A", QuotaType.COUNT)).block())
+            .isEqualTo(expected);
+    }
+
+    @Test
+    void setQuotaLimitShouldSaveObjectSuccessfullyWhenLimitIsMinusOne() {
+        QuotaLimit expected = QuotaLimit.builder().quotaComponent(QuotaComponent.MAILBOX).quotaScope(QuotaScope.DOMAIN).identifier("A").quotaType(QuotaType.COUNT).quotaLimit(-1l).build();
+        cassandraQuotaLimitDao.setQuotaLimit(expected).block();
+
+        assertThat(cassandraQuotaLimitDao.getQuotaLimit(CassandraQuotaLimitDao.QuotaLimitKey.of(QuotaComponent.MAILBOX, QuotaScope.DOMAIN, "A", QuotaType.COUNT)).block())
+            .isEqualTo(expected);
+    }
+
+    @Test
+    void deleteQuotaLimitShouldDeleteObjectSuccessfully() {
+        QuotaLimit quotaLimit = QuotaLimit.builder().quotaComponent(QuotaComponent.MAILBOX).quotaScope(QuotaScope.DOMAIN).identifier("A").quotaType(QuotaType.COUNT).quotaLimit(100l).build();
+        cassandraQuotaLimitDao.setQuotaLimit(quotaLimit).block();
+        cassandraQuotaLimitDao.deleteQuotaLimit(CassandraQuotaLimitDao.QuotaLimitKey.of(QuotaComponent.MAILBOX, QuotaScope.DOMAIN, "A", QuotaType.COUNT)).block();
+
+        assertThat(cassandraQuotaLimitDao.getQuotaLimit(CassandraQuotaLimitDao.QuotaLimitKey.of(QuotaComponent.MAILBOX, QuotaScope.DOMAIN, "A", QuotaType.COUNT)).block())
+            .isNull();
+    }
+
+}
\ No newline at end of file
diff --git a/server/container/guice/cassandra/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaModule.java b/server/container/guice/cassandra/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaModule.java
index a8eb5351ff..f79fc9d1d6 100644
--- a/server/container/guice/cassandra/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaModule.java
+++ b/server/container/guice/cassandra/src/main/java/org/apache/james/modules/mailbox/CassandraQuotaModule.java
@@ -26,6 +26,8 @@ import org.apache.james.mailbox.cassandra.quota.CassandraGlobalMaxQuotaDao;
 import org.apache.james.mailbox.cassandra.quota.CassandraPerDomainMaxQuotaDao;
 import org.apache.james.mailbox.cassandra.quota.CassandraPerUserMaxQuotaDao;
 import org.apache.james.mailbox.cassandra.quota.CassandraPerUserMaxQuotaManager;
+import org.apache.james.mailbox.cassandra.quota.CassandraQuotaCurrentValueDao;
+import org.apache.james.mailbox.cassandra.quota.CassandraQuotaLimitDao;
 import org.apache.james.mailbox.quota.CurrentQuotaManager;
 import org.apache.james.mailbox.quota.MaxQuotaManager;
 import org.apache.james.mailbox.quota.QuotaManager;
@@ -46,6 +48,8 @@ public class CassandraQuotaModule extends AbstractModule {
     @Override
     protected void configure() {
         bind(CassandraCurrentQuotaManager.class).in(Scopes.SINGLETON);
+        bind(CassandraQuotaLimitDao.class).in(Scopes.SINGLETON);
+        bind(CassandraQuotaCurrentValueDao.class).in(Scopes.SINGLETON);
         bind(CassandraGlobalMaxQuotaDao.class).in(Scopes.SINGLETON);
         bind(CassandraPerDomainMaxQuotaDao.class).in(Scopes.SINGLETON);
         bind(CassandraPerUserMaxQuotaDao.class).in(Scopes.SINGLETON);


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org