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

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


The following commit(s) were added to refs/heads/postgresql by this push:
     new 71f383cf31 JAMES-2586 Implement PostgresQuotaLimitDAO
71f383cf31 is described below

commit 71f383cf31f437dfe0ba28fb203c04ea6d6a6f2b
Author: hung phan <[email protected]>
AuthorDate: Fri Nov 24 10:52:29 2023 +0700

    JAMES-2586 Implement PostgresQuotaLimitDAO
---
 .../components/CassandraQuotaLimitDao.java         | 72 +---------------
 .../quota/CassandraQuotaLimitDaoTest.java          |  8 +-
 .../postgres/quota/PostgresQuotaLimitDAO.java      | 98 ++++++++++++++++++++++
 .../postgres/quota/PostgresQuotaModule.java        | 25 +++++-
 .../postgres/quota/PostgresQuotaLimitDaoTest.java} | 39 ++++-----
 .../org/apache/james/core/quota/QuotaLimit.java    | 59 +++++++++++++
 .../quota/CassandraPerUserMaxQuotaManagerV2.java   | 17 ++--
 .../sieve/cassandra/CassandraSieveQuotaDAOV2.java  |  4 +-
 8 files changed, 217 insertions(+), 105 deletions(-)

diff --git 
a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraQuotaLimitDao.java
 
b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraQuotaLimitDao.java
index 4a6844b0db..daeceb0f11 100644
--- 
a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraQuotaLimitDao.java
+++ 
b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/components/CassandraQuotaLimitDao.java
@@ -31,8 +31,6 @@ import static 
org.apache.james.backends.cassandra.components.CassandraQuotaLimit
 import static 
org.apache.james.backends.cassandra.components.CassandraQuotaLimitTable.QUOTA_TYPE;
 import static 
org.apache.james.backends.cassandra.components.CassandraQuotaLimitTable.TABLE_NAME;
 
-import java.util.Objects;
-
 import javax.inject.Inject;
 
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
@@ -47,74 +45,11 @@ 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;
@@ -130,7 +65,7 @@ public class CassandraQuotaLimitDao {
         this.deleteQuotaLimitStatement = 
session.prepare((deleteQuotaLimitStatement().build()));
     }
 
-    public Mono<QuotaLimit> getQuotaLimit(QuotaLimitKey quotaKey) {
+    public Mono<QuotaLimit> getQuotaLimit(QuotaLimit.QuotaLimitKey quotaKey) {
         return queryExecutor.executeSingleRow(getQuotaLimitStatement.bind()
             .setString(QUOTA_COMPONENT, 
quotaKey.getQuotaComponent().getValue())
             .setString(QUOTA_SCOPE, quotaKey.getQuotaScope().getValue())
@@ -156,7 +91,7 @@ public class CassandraQuotaLimitDao {
             .setLong(QUOTA_LIMIT, quotaLimit.getQuotaLimit().orElse(null)));
     }
 
-    public Mono<Void> deleteQuotaLimit(QuotaLimitKey quotaKey) {
+    public Mono<Void> deleteQuotaLimit(QuotaLimit.QuotaLimitKey quotaKey) {
         return queryExecutor.executeVoid(deleteQuotaLimitStatement.bind()
             .setString(QUOTA_COMPONENT, 
quotaKey.getQuotaComponent().getValue())
             .setString(QUOTA_SCOPE, quotaKey.getQuotaScope().getValue())
@@ -203,7 +138,8 @@ public class CassandraQuotaLimitDao {
             .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();
+            .quotaLimit(row.get(QUOTA_LIMIT, Long.class))
+            .build();
     }
 
 }
\ No newline at end of file
diff --git 
a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/quota/CassandraQuotaLimitDaoTest.java
 
b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/quota/CassandraQuotaLimitDaoTest.java
index 2c260d6e05..e654e0ba30 100644
--- 
a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/quota/CassandraQuotaLimitDaoTest.java
+++ 
b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/quota/CassandraQuotaLimitDaoTest.java
@@ -61,7 +61,7 @@ public class CassandraQuotaLimitDaoTest {
         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())
+        
assertThat(cassandraQuotaLimitDao.getQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, "A", QuotaType.COUNT)).block())
             .isEqualTo(expected);
     }
 
@@ -70,7 +70,7 @@ public class CassandraQuotaLimitDaoTest {
         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())
+        
assertThat(cassandraQuotaLimitDao.getQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, "A", QuotaType.COUNT)).block())
             .isEqualTo(expected);
     }
 
@@ -78,9 +78,9 @@ public class CassandraQuotaLimitDaoTest {
     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();
+        
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, "A", QuotaType.COUNT)).block();
 
-        
assertThat(cassandraQuotaLimitDao.getQuotaLimit(CassandraQuotaLimitDao.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, "A", QuotaType.COUNT)).block())
+        
assertThat(cassandraQuotaLimitDao.getQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, "A", QuotaType.COUNT)).block())
             .isNull();
     }
 
diff --git 
a/backends-common/postgres/src/main/java/org/apache/james/backends/postgres/quota/PostgresQuotaLimitDAO.java
 
b/backends-common/postgres/src/main/java/org/apache/james/backends/postgres/quota/PostgresQuotaLimitDAO.java
new file mode 100644
index 0000000000..ff17e94841
--- /dev/null
+++ 
b/backends-common/postgres/src/main/java/org/apache/james/backends/postgres/quota/PostgresQuotaLimitDAO.java
@@ -0,0 +1,98 @@
+/****************************************************************
+ * 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.backends.postgres.quota;
+
+import static 
org.apache.james.backends.postgres.quota.PostgresQuotaModule.PostgresQuotaLimitTable.IDENTIFIER;
+import static 
org.apache.james.backends.postgres.quota.PostgresQuotaModule.PostgresQuotaLimitTable.PK_CONSTRAINT_NAME;
+import static 
org.apache.james.backends.postgres.quota.PostgresQuotaModule.PostgresQuotaLimitTable.QUOTA_COMPONENT;
+import static 
org.apache.james.backends.postgres.quota.PostgresQuotaModule.PostgresQuotaLimitTable.QUOTA_LIMIT;
+import static 
org.apache.james.backends.postgres.quota.PostgresQuotaModule.PostgresQuotaLimitTable.QUOTA_SCOPE;
+import static 
org.apache.james.backends.postgres.quota.PostgresQuotaModule.PostgresQuotaLimitTable.QUOTA_TYPE;
+import static 
org.apache.james.backends.postgres.quota.PostgresQuotaModule.PostgresQuotaLimitTable.TABLE_NAME;
+
+import javax.inject.Inject;
+
+import org.apache.james.backends.postgres.utils.PostgresExecutor;
+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.jooq.Record;
+
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+public class PostgresQuotaLimitDAO {
+    private static final Long EMPTY_QUOTA_LIMIT = null;
+
+    private final PostgresExecutor postgresExecutor;
+
+    @Inject
+    public PostgresQuotaLimitDAO(PostgresExecutor postgresExecutor) {
+        this.postgresExecutor = postgresExecutor;
+    }
+
+    public Mono<QuotaLimit> getQuotaLimit(QuotaLimit.QuotaLimitKey quotaKey) {
+        return postgresExecutor.executeRow(dsl -> 
Mono.from(dsl.selectFrom(TABLE_NAME)
+                
.where(QUOTA_COMPONENT.eq(quotaKey.getQuotaComponent().getValue()))
+                .and(QUOTA_SCOPE.eq(quotaKey.getQuotaScope().getValue()))
+                .and(IDENTIFIER.eq(quotaKey.getIdentifier()))
+                .and(QUOTA_TYPE.eq(quotaKey.getQuotaType().getValue()))))
+            .map(this::asQuotaLimit);
+    }
+
+    public Flux<QuotaLimit> getQuotaLimits(QuotaComponent quotaComponent, 
QuotaScope quotaScope, String identifier) {
+        return postgresExecutor.executeRows(dsl -> 
Flux.from(dsl.selectFrom(TABLE_NAME)
+                .where(QUOTA_COMPONENT.eq(quotaComponent.getValue()))
+                .and(QUOTA_SCOPE.eq(quotaScope.getValue()))
+                .and(IDENTIFIER.eq(identifier))))
+            .map(this::asQuotaLimit);
+    }
+
+    public Mono<Void> setQuotaLimit(QuotaLimit quotaLimit) {
+        return postgresExecutor.executeVoid(dslContext ->
+            Mono.from(dslContext.insertInto(TABLE_NAME, QUOTA_SCOPE, 
IDENTIFIER, QUOTA_COMPONENT, QUOTA_TYPE, QUOTA_LIMIT)
+                .values(quotaLimit.getQuotaScope().getValue(),
+                    quotaLimit.getIdentifier(),
+                    quotaLimit.getQuotaComponent().getValue(),
+                    quotaLimit.getQuotaType().getValue(),
+                    quotaLimit.getQuotaLimit().orElse(EMPTY_QUOTA_LIMIT))
+                .onConflictOnConstraint(PK_CONSTRAINT_NAME)
+                .doUpdate()
+                .set(QUOTA_LIMIT, 
quotaLimit.getQuotaLimit().orElse(EMPTY_QUOTA_LIMIT))));
+    }
+
+    public Mono<Void> deleteQuotaLimit(QuotaLimit.QuotaLimitKey quotaKey) {
+        return postgresExecutor.executeVoid(dsl -> 
Mono.from(dsl.deleteFrom(TABLE_NAME)
+            .where(QUOTA_COMPONENT.eq(quotaKey.getQuotaComponent().getValue()))
+            .and(QUOTA_SCOPE.eq(quotaKey.getQuotaScope().getValue()))
+            .and(IDENTIFIER.eq(quotaKey.getIdentifier()))
+            .and(QUOTA_TYPE.eq(quotaKey.getQuotaType().getValue()))));
+    }
+
+    private QuotaLimit asQuotaLimit(Record record) {
+        return 
QuotaLimit.builder().quotaComponent(QuotaComponent.of(record.get(QUOTA_COMPONENT)))
+            .quotaScope(QuotaScope.of(record.get(QUOTA_SCOPE)))
+            .identifier(record.get(IDENTIFIER))
+            .quotaType(QuotaType.of(record.get(QUOTA_TYPE)))
+            .quotaLimit(record.get(QUOTA_LIMIT))
+            .build();
+    }
+}
diff --git 
a/backends-common/postgres/src/main/java/org/apache/james/backends/postgres/quota/PostgresQuotaModule.java
 
b/backends-common/postgres/src/main/java/org/apache/james/backends/postgres/quota/PostgresQuotaModule.java
index dad84108d0..a3ffe8597a 100644
--- 
a/backends-common/postgres/src/main/java/org/apache/james/backends/postgres/quota/PostgresQuotaModule.java
+++ 
b/backends-common/postgres/src/main/java/org/apache/james/backends/postgres/quota/PostgresQuotaModule.java
@@ -53,7 +53,30 @@ public interface PostgresQuotaModule {
             .disableRowLevelSecurity();
     }
 
+    interface PostgresQuotaLimitTable {
+        Table<Record> TABLE_NAME = DSL.table("quota_limit");
+
+        Field<String> QUOTA_SCOPE = DSL.field("quota_scope", 
SQLDataType.VARCHAR.notNull());
+        Field<String> IDENTIFIER = DSL.field("identifier", 
SQLDataType.VARCHAR.notNull());
+        Field<String> QUOTA_COMPONENT = DSL.field("quota_component", 
SQLDataType.VARCHAR.notNull());
+        Field<String> QUOTA_TYPE = DSL.field("quota_type", 
SQLDataType.VARCHAR.notNull());
+        Field<Long> QUOTA_LIMIT = DSL.field("quota_limit", SQLDataType.BIGINT);
+
+        Name PK_CONSTRAINT_NAME = DSL.name("quota_limit_pkey");
+
+        PostgresTable TABLE = PostgresTable.name(TABLE_NAME.getName())
+            .createTableStep(((dsl, tableName) -> dsl.createTable(tableName)
+                .column(QUOTA_SCOPE)
+                .column(IDENTIFIER)
+                .column(QUOTA_COMPONENT)
+                .column(QUOTA_TYPE)
+                .column(QUOTA_LIMIT)
+                
.constraint(DSL.constraint(PK_CONSTRAINT_NAME).primaryKey(QUOTA_SCOPE, 
IDENTIFIER, QUOTA_COMPONENT, QUOTA_TYPE))))
+            .supportsRowLevelSecurity();
+    }
+
     PostgresModule MODULE = PostgresModule.builder()
         .addTable(PostgresQuotaCurrentValueTable.TABLE)
+        .addTable(PostgresQuotaLimitTable.TABLE)
         .build();
-}
+}
\ No newline at end of file
diff --git 
a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/quota/CassandraQuotaLimitDaoTest.java
 
b/backends-common/postgres/src/test/java/org/apache/james/backends/postgres/quota/PostgresQuotaLimitDaoTest.java
similarity index 62%
copy from 
backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/quota/CassandraQuotaLimitDaoTest.java
copy to 
backends-common/postgres/src/test/java/org/apache/james/backends/postgres/quota/PostgresQuotaLimitDaoTest.java
index 2c260d6e05..4e382ef3d3 100644
--- 
a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/quota/CassandraQuotaLimitDaoTest.java
+++ 
b/backends-common/postgres/src/test/java/org/apache/james/backends/postgres/quota/PostgresQuotaLimitDaoTest.java
@@ -17,14 +17,9 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.backends.cassandra.quota;
+package org.apache.james.backends.postgres.quota;
 
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.apache.james.backends.cassandra.CassandraClusterExtension;
-import org.apache.james.backends.cassandra.components.CassandraModule;
-import 
org.apache.james.backends.cassandra.components.CassandraMutualizedQuotaModule;
-import org.apache.james.backends.cassandra.components.CassandraQuotaLimitDao;
+import org.apache.james.backends.postgres.PostgresExtension;
 import org.apache.james.core.quota.QuotaComponent;
 import org.apache.james.core.quota.QuotaLimit;
 import org.apache.james.core.quota.QuotaScope;
@@ -33,54 +28,56 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class CassandraQuotaLimitDaoTest {
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class PostgresQuotaLimitDaoTest {
 
-    private CassandraQuotaLimitDao cassandraQuotaLimitDao;
+    private PostgresQuotaLimitDAO postgresQuotaLimitDao;
 
     @RegisterExtension
-    static CassandraClusterExtension cassandraCluster = new 
CassandraClusterExtension(CassandraModule.aggregateModules(CassandraMutualizedQuotaModule.MODULE));
+    static PostgresExtension postgresExtension = 
PostgresExtension.withoutRowLevelSecurity(PostgresQuotaModule.MODULE);
 
     @BeforeEach
     void setup() {
-        cassandraQuotaLimitDao = new 
CassandraQuotaLimitDao(cassandraCluster.getCassandraCluster().getConf());
+        postgresQuotaLimitDao = new 
PostgresQuotaLimitDAO(postgresExtension.getPostgresExecutor());
     }
 
     @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();
+        postgresQuotaLimitDao.setQuotaLimit(expectedOne).block();
+        postgresQuotaLimitDao.setQuotaLimit(expectedTwo).block();
 
-        
assertThat(cassandraQuotaLimitDao.getQuotaLimits(QuotaComponent.MAILBOX, 
QuotaScope.DOMAIN, "A").collectList().block())
+        
assertThat(postgresQuotaLimitDao.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();
+        postgresQuotaLimitDao.setQuotaLimit(expected).block();
 
-        
assertThat(cassandraQuotaLimitDao.getQuotaLimit(CassandraQuotaLimitDao.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, "A", QuotaType.COUNT)).block())
+        
assertThat(postgresQuotaLimitDao.getQuotaLimit(QuotaLimit.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();
+        postgresQuotaLimitDao.setQuotaLimit(expected).block();
 
-        
assertThat(cassandraQuotaLimitDao.getQuotaLimit(CassandraQuotaLimitDao.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, "A", QuotaType.COUNT)).block())
+        
assertThat(postgresQuotaLimitDao.getQuotaLimit(QuotaLimit.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();
+        postgresQuotaLimitDao.setQuotaLimit(quotaLimit).block();
+        
postgresQuotaLimitDao.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, "A", QuotaType.COUNT)).block();
 
-        
assertThat(cassandraQuotaLimitDao.getQuotaLimit(CassandraQuotaLimitDao.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, "A", QuotaType.COUNT)).block())
+        
assertThat(postgresQuotaLimitDao.getQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, "A", QuotaType.COUNT)).block())
             .isNull();
     }
 
diff --git a/core/src/main/java/org/apache/james/core/quota/QuotaLimit.java 
b/core/src/main/java/org/apache/james/core/quota/QuotaLimit.java
index 5d49216be7..0f371a5d05 100644
--- a/core/src/main/java/org/apache/james/core/quota/QuotaLimit.java
+++ b/core/src/main/java/org/apache/james/core/quota/QuotaLimit.java
@@ -26,6 +26,65 @@ import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
 
 public class QuotaLimit {
+    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();
+        }
+    }
 
     public static class Builder {
         private QuotaComponent quotaComponent;
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManagerV2.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManagerV2.java
index b4a5043b29..6697a9843a 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManagerV2.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManagerV2.java
@@ -19,7 +19,6 @@
 
 package org.apache.james.mailbox.cassandra.quota;
 
-import static 
org.apache.james.backends.cassandra.components.CassandraQuotaLimitDao.QuotaLimitKey;
 import static org.apache.james.util.ReactorUtils.publishIfPresent;
 
 import java.util.Map;
@@ -130,7 +129,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> removeDomainMaxMessageReactive(Domain domain) {
-        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, domain.asString(), QuotaType.COUNT));
+        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, domain.asString(), QuotaType.COUNT));
     }
 
     @Override
@@ -140,7 +139,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> removeDomainMaxStorageReactive(Domain domain) {
-        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, domain.asString(), QuotaType.SIZE));
+        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, domain.asString(), QuotaType.SIZE));
     }
 
     @Override
@@ -170,7 +169,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> removeMaxMessageReactive(QuotaRoot quotaRoot) {
-        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.USER, quotaRoot.getValue(), QuotaType.COUNT));
+        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.USER, quotaRoot.getValue(), QuotaType.COUNT));
     }
 
     @Override
@@ -180,7 +179,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> removeMaxStorageReactive(QuotaRoot quotaRoot) {
-        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.USER, quotaRoot.getValue(), QuotaType.SIZE));
+        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.USER, quotaRoot.getValue(), QuotaType.SIZE));
     }
 
     @Override
@@ -205,7 +204,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> removeGlobalMaxStorageReactive() {
-        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.GLOBAL, GLOBAL_IDENTIFIER, QuotaType.SIZE));
+        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.GLOBAL, GLOBAL_IDENTIFIER, QuotaType.SIZE));
     }
 
     @Override
@@ -230,7 +229,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> removeGlobalMaxMessageReactive() {
-        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.GLOBAL, GLOBAL_IDENTIFIER, QuotaType.COUNT));
+        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.GLOBAL, GLOBAL_IDENTIFIER, QuotaType.COUNT));
     }
 
     @Override
@@ -322,7 +321,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
     }
 
     private Mono<QuotaCountLimit> getMaxMessageReactive(QuotaScope quotaScope, 
String identifier) {
-        return 
cassandraQuotaLimitDao.getQuotaLimit(QuotaLimitKey.of(QuotaComponent.MAILBOX, 
quotaScope, identifier, QuotaType.COUNT))
+        return 
cassandraQuotaLimitDao.getQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 quotaScope, identifier, QuotaType.COUNT))
             .map(QuotaLimit::getQuotaLimit)
             .handle(publishIfPresent())
             .map(QuotaCodec::longToQuotaCount)
@@ -330,7 +329,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
     }
 
     public Mono<QuotaSizeLimit> getMaxStorageReactive(QuotaScope quotaScope, 
String identifier) {
-        return 
cassandraQuotaLimitDao.getQuotaLimit(QuotaLimitKey.of(QuotaComponent.MAILBOX, 
quotaScope, identifier, QuotaType.SIZE))
+        return 
cassandraQuotaLimitDao.getQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 quotaScope, identifier, QuotaType.SIZE))
             .map(QuotaLimit::getQuotaLimit)
             .handle(publishIfPresent())
             .map(QuotaCodec::longToQuotaSize)
diff --git 
a/server/data/data-cassandra/src/main/java/org/apache/james/sieve/cassandra/CassandraSieveQuotaDAOV2.java
 
b/server/data/data-cassandra/src/main/java/org/apache/james/sieve/cassandra/CassandraSieveQuotaDAOV2.java
index d68165ef24..1af9b9593a 100644
--- 
a/server/data/data-cassandra/src/main/java/org/apache/james/sieve/cassandra/CassandraSieveQuotaDAOV2.java
+++ 
b/server/data/data-cassandra/src/main/java/org/apache/james/sieve/cassandra/CassandraSieveQuotaDAOV2.java
@@ -93,7 +93,7 @@ public class CassandraSieveQuotaDAOV2 implements 
CassandraSieveQuotaDAO {
 
     @Override
     public Mono<Void> removeQuota() {
-        return 
limitDao.deleteQuotaLimit(CassandraQuotaLimitDao.QuotaLimitKey.of(QUOTA_COMPONENT,
 QuotaScope.GLOBAL, GLOBAL, QuotaType.SIZE));
+        return 
limitDao.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QUOTA_COMPONENT, 
QuotaScope.GLOBAL, GLOBAL, QuotaType.SIZE));
     }
 
     @Override
@@ -117,7 +117,7 @@ public class CassandraSieveQuotaDAOV2 implements 
CassandraSieveQuotaDAO {
 
     @Override
     public Mono<Void> removeQuota(Username username) {
-        return 
limitDao.deleteQuotaLimit(CassandraQuotaLimitDao.QuotaLimitKey.of(
+        return limitDao.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(
             QUOTA_COMPONENT, QuotaScope.USER, username.asString(), 
QuotaType.SIZE));
     }
 


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

Reply via email to