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 c5bd9ab41f JAMES-2586 Implement PostgresPerUserMaxQuotaManager (#1839)
c5bd9ab41f is described below

commit c5bd9ab41f9e521af78bf82b25ad35a7c24f710f
Author: hungphan227 <45198168+hungphan...@users.noreply.github.com>
AuthorDate: Wed Dec 6 11:16:38 2023 +0700

    JAMES-2586 Implement PostgresPerUserMaxQuotaManager (#1839)
---
 .../org/apache/james/mailbox}/quota/Limits.java    |   2 +-
 .../apache/james/mailbox}/quota/QuotaCodec.java    |   8 +-
 .../quota/CassandraGlobalMaxQuotaDao.java          |   2 +
 .../quota/CassandraPerDomainMaxQuotaDao.java       |   2 +
 .../quota/CassandraPerUserMaxQuotaDao.java         |   2 +
 .../quota/CassandraPerUserMaxQuotaManagerV1.java   |   1 +
 .../quota/CassandraPerUserMaxQuotaManagerV2.java   |   2 +
 mailbox/postgres/pom.xml                           |  21 --
 .../postgres/quota/JPAPerUserMaxQuotaDAO.java      | 238 -----------------
 .../postgres/quota/JPAPerUserMaxQuotaManager.java  | 292 ---------------------
 .../quota/PostgresPerUserMaxQuotaManager.java}     | 141 +++++-----
 .../quota/model/MaxDomainMessageCount.java         |  54 ----
 .../postgres/quota/model/MaxDomainStorage.java     |  55 ----
 .../quota/model/MaxGlobalMessageCount.java         |  54 ----
 .../postgres/quota/model/MaxGlobalStorage.java     |  54 ----
 .../postgres/quota/model/MaxUserMessageCount.java  |  52 ----
 .../postgres/quota/model/MaxUserStorage.java       |  53 ----
 .../james/mailbox/postgres/JPAMailboxFixture.java  |  51 ----
 ...ava => PostgresPerUserMaxQuotaManagerTest.java} |  22 +-
 .../postgres/src/test/resources/persistence.xml    |  42 ---
 .../postgres/host/PostgresHostSystem.java          |  26 +-
 .../src/main/resources/META-INF/persistence.xml    |   9 -
 .../james/modules/mailbox/PostgresQuotaModule.java |  10 +-
 23 files changed, 104 insertions(+), 1089 deletions(-)

diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/Limits.java
 b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/Limits.java
similarity index 97%
rename from 
mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/Limits.java
rename to mailbox/api/src/main/java/org/apache/james/mailbox/quota/Limits.java
index 3ef7aec097..f278d03ed7 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/Limits.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/Limits.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.cassandra.quota;
+package org.apache.james.mailbox.quota;
 
 import java.util.Optional;
 
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/QuotaCodec.java
 b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaCodec.java
similarity index 90%
rename from 
mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/QuotaCodec.java
rename to 
mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaCodec.java
index 87b6cdcef7..d3d9b5cd67 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/QuotaCodec.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaCodec.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations      *
  * under the License.                                           *
  ****************************************************************/
-package org.apache.james.mailbox.cassandra.quota;
+package org.apache.james.mailbox.quota;
 
 import java.util.Optional;
 import java.util.function.Function;
@@ -30,18 +30,18 @@ public class QuotaCodec {
     private static final long INFINITE = -1;
     private static final long NO_RIGHT = 0L;
 
-    static Long quotaValueToLong(QuotaLimitValue<?> value) {
+    public static Long quotaValueToLong(QuotaLimitValue<?> value) {
         if (value.isUnlimited()) {
             return INFINITE;
         }
         return value.asLong();
     }
 
-    static Optional<QuotaSizeLimit> longToQuotaSize(Long value) {
+    public static Optional<QuotaSizeLimit> longToQuotaSize(Long value) {
         return longToQuotaValue(value, QuotaSizeLimit.unlimited(), 
QuotaSizeLimit::size);
     }
 
-    static Optional<QuotaCountLimit> longToQuotaCount(Long value) {
+    public static Optional<QuotaCountLimit> longToQuotaCount(Long value) {
         return longToQuotaValue(value, QuotaCountLimit.unlimited(), 
QuotaCountLimit::count);
     }
 
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraGlobalMaxQuotaDao.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraGlobalMaxQuotaDao.java
index 426f069e88..35c9e15822 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraGlobalMaxQuotaDao.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraGlobalMaxQuotaDao.java
@@ -39,6 +39,8 @@ import javax.inject.Inject;
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
 import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaSizeLimit;
+import org.apache.james.mailbox.quota.Limits;
+import org.apache.james.mailbox.quota.QuotaCodec;
 
 import com.datastax.oss.driver.api.core.CqlSession;
 import com.datastax.oss.driver.api.core.cql.PreparedStatement;
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerDomainMaxQuotaDao.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerDomainMaxQuotaDao.java
index 1efe48219e..3c882978f6 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerDomainMaxQuotaDao.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerDomainMaxQuotaDao.java
@@ -35,6 +35,8 @@ import org.apache.james.core.Domain;
 import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.mailbox.cassandra.table.CassandraDomainMaxQuota;
+import org.apache.james.mailbox.quota.Limits;
+import org.apache.james.mailbox.quota.QuotaCodec;
 
 import com.datastax.oss.driver.api.core.CqlSession;
 import com.datastax.oss.driver.api.core.cql.PreparedStatement;
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaDao.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaDao.java
index e66328fceb..19ed0d5f12 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaDao.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaDao.java
@@ -35,6 +35,8 @@ import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.mailbox.cassandra.table.CassandraMaxQuota;
 import org.apache.james.mailbox.model.QuotaRoot;
+import org.apache.james.mailbox.quota.Limits;
+import org.apache.james.mailbox.quota.QuotaCodec;
 
 import com.datastax.oss.driver.api.core.CqlSession;
 import com.datastax.oss.driver.api.core.cql.PreparedStatement;
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManagerV1.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManagerV1.java
index 28ad30a4b8..778b2e2c72 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManagerV1.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManagerV1.java
@@ -32,6 +32,7 @@ import org.apache.james.core.quota.QuotaCountLimit;
 import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.model.QuotaRoot;
+import org.apache.james.mailbox.quota.Limits;
 import org.apache.james.mailbox.quota.MaxQuotaManager;
 
 import com.google.common.collect.ImmutableMap;
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 6697a9843a..a1d3347a7e 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
@@ -40,7 +40,9 @@ import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaType;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.model.QuotaRoot;
+import org.apache.james.mailbox.quota.Limits;
 import org.apache.james.mailbox.quota.MaxQuotaManager;
+import org.apache.james.mailbox.quota.QuotaCodec;
 
 import com.google.common.collect.ImmutableMap;
 
diff --git a/mailbox/postgres/pom.xml b/mailbox/postgres/pom.xml
index edc6bfac4b..e2f2d9bcd7 100644
--- a/mailbox/postgres/pom.xml
+++ b/mailbox/postgres/pom.xml
@@ -195,27 +195,6 @@
                         -Xms512m -Xmx1024m 
-Dopenjpa.Multithreaded=true</argLine>
                 </configuration>
             </plugin>
-            <plugin>
-                <groupId>org.apache.openjpa</groupId>
-                <artifactId>openjpa-maven-plugin</artifactId>
-                <version>${apache.openjpa.version}</version>
-                <configuration>
-                    
<includes>org/apache/james/mailbox/jpa/*/model/**/*.class</includes>
-                    
<excludes>org/apache/james/mailbox/jpa/mail/model/openjpa/EncryptDecryptHelper.class</excludes>
-                    <addDefaultConstructor>true</addDefaultConstructor>
-                    
<enforcePropertyRestrictions>true</enforcePropertyRestrictions>
-                    
<persistenceXmlFile>${basedir}/src/test/resources/persistence.xml</persistenceXmlFile>
-                </configuration>
-                <executions>
-                    <execution>
-                        <id>enhancer</id>
-                        <goals>
-                            <goal>enhance</goal>
-                        </goals>
-                        <phase>process-classes</phase>
-                    </execution>
-                </executions>
-            </plugin>
         </plugins>
     </build>
 </project>
diff --git 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/JPAPerUserMaxQuotaDAO.java
 
b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/JPAPerUserMaxQuotaDAO.java
deleted file mode 100644
index 31630798d3..0000000000
--- 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/JPAPerUserMaxQuotaDAO.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/****************************************************************
- * 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.postgres.quota;
-
-import java.util.Optional;
-import java.util.function.Function;
-
-import javax.inject.Inject;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-
-import org.apache.james.backends.jpa.TransactionRunner;
-import org.apache.james.core.Domain;
-import org.apache.james.core.quota.QuotaCountLimit;
-import org.apache.james.core.quota.QuotaLimitValue;
-import org.apache.james.core.quota.QuotaSizeLimit;
-import org.apache.james.mailbox.model.QuotaRoot;
-import org.apache.james.mailbox.postgres.quota.model.MaxDomainMessageCount;
-import org.apache.james.mailbox.postgres.quota.model.MaxDomainStorage;
-import org.apache.james.mailbox.postgres.quota.model.MaxGlobalMessageCount;
-import org.apache.james.mailbox.postgres.quota.model.MaxGlobalStorage;
-import org.apache.james.mailbox.postgres.quota.model.MaxUserMessageCount;
-import org.apache.james.mailbox.postgres.quota.model.MaxUserStorage;
-
-public class JPAPerUserMaxQuotaDAO {
-
-    private static final long INFINITE = -1;
-    private final TransactionRunner transactionRunner;
-
-    @Inject
-    public JPAPerUserMaxQuotaDAO(EntityManagerFactory entityManagerFactory) {
-        this.transactionRunner = new TransactionRunner(entityManagerFactory);
-    }
-
-    public void setMaxStorage(QuotaRoot quotaRoot, Optional<QuotaSizeLimit> 
maxStorageQuota) {
-        transactionRunner.run(
-            entityManager -> {
-                MaxUserStorage storedValue = 
getMaxUserStorageEntity(entityManager, quotaRoot, maxStorageQuota);
-                entityManager.persist(storedValue);
-            });
-    }
-
-    private MaxUserStorage getMaxUserStorageEntity(EntityManager 
entityManager, QuotaRoot quotaRoot, Optional<QuotaSizeLimit> maxStorageQuota) {
-        MaxUserStorage storedValue = entityManager.find(MaxUserStorage.class, 
quotaRoot.getValue());
-        Long value = quotaValueToLong(maxStorageQuota);
-        if (storedValue == null) {
-            return new MaxUserStorage(quotaRoot.getValue(), value);
-        }
-        storedValue.setValue(value);
-        return storedValue;
-    }
-
-    public void setMaxMessage(QuotaRoot quotaRoot, Optional<QuotaCountLimit> 
maxMessageCount) {
-        transactionRunner.run(
-            entityManager -> {
-                MaxUserMessageCount storedValue = 
getMaxUserMessageEntity(entityManager, quotaRoot, maxMessageCount);
-                entityManager.persist(storedValue);
-            });
-    }
-
-    private MaxUserMessageCount getMaxUserMessageEntity(EntityManager 
entityManager, QuotaRoot quotaRoot, Optional<QuotaCountLimit> maxMessageQuota) {
-        MaxUserMessageCount storedValue = 
entityManager.find(MaxUserMessageCount.class, quotaRoot.getValue());
-        Long value = quotaValueToLong(maxMessageQuota);
-        if (storedValue == null) {
-            return new MaxUserMessageCount(quotaRoot.getValue(), value);
-        }
-        storedValue.setValue(value);
-        return storedValue;
-    }
-
-    public void setDomainMaxMessage(Domain domain, Optional<QuotaCountLimit> 
count) {
-        transactionRunner.run(
-            entityManager -> {
-                MaxDomainMessageCount storedValue = 
getMaxDomainMessageEntity(entityManager, domain, count);
-                entityManager.persist(storedValue);
-            });
-    }
-
-
-    public void setDomainMaxStorage(Domain domain, Optional<QuotaSizeLimit> 
size) {
-        transactionRunner.run(
-            entityManager -> {
-                MaxDomainStorage storedValue = 
getMaxDomainStorageEntity(entityManager, domain, size);
-                entityManager.persist(storedValue);
-            });
-    }
-
-    private MaxDomainMessageCount getMaxDomainMessageEntity(EntityManager 
entityManager, Domain domain, Optional<QuotaCountLimit> maxMessageQuota) {
-        MaxDomainMessageCount storedValue = 
entityManager.find(MaxDomainMessageCount.class, domain.asString());
-        Long value = quotaValueToLong(maxMessageQuota);
-        if (storedValue == null) {
-            return new MaxDomainMessageCount(domain, value);
-        }
-        storedValue.setValue(value);
-        return storedValue;
-    }
-
-    private MaxDomainStorage getMaxDomainStorageEntity(EntityManager 
entityManager, Domain domain, Optional<QuotaSizeLimit> maxStorageQuota) {
-        MaxDomainStorage storedValue = 
entityManager.find(MaxDomainStorage.class, domain.asString());
-        Long value = quotaValueToLong(maxStorageQuota);
-        if (storedValue == null) {
-            return new MaxDomainStorage(domain, value);
-        }
-        storedValue.setValue(value);
-        return storedValue;
-    }
-
-
-    public void setGlobalMaxStorage(Optional<QuotaSizeLimit> globalMaxStorage) 
{
-        transactionRunner.run(
-            entityManager -> {
-                MaxGlobalStorage globalMaxStorageEntity = 
getGlobalMaxStorageEntity(entityManager, globalMaxStorage);
-                entityManager.persist(globalMaxStorageEntity);
-            });
-    }
-
-    private MaxGlobalStorage getGlobalMaxStorageEntity(EntityManager 
entityManager, Optional<QuotaSizeLimit> maxSizeQuota) {
-        MaxGlobalStorage storedValue = 
entityManager.find(MaxGlobalStorage.class, MaxGlobalStorage.DEFAULT_KEY);
-        Long value = quotaValueToLong(maxSizeQuota);
-        if (storedValue == null) {
-            return new MaxGlobalStorage(value);
-        }
-        storedValue.setValue(value);
-        return storedValue;
-    }
-
-    public void setGlobalMaxMessage(Optional<QuotaCountLimit> 
globalMaxMessageCount) {
-        transactionRunner.run(
-            entityManager -> {
-                MaxGlobalMessageCount globalMaxMessageEntity = 
getGlobalMaxMessageEntity(entityManager, globalMaxMessageCount);
-                entityManager.persist(globalMaxMessageEntity);
-            });
-    }
-
-    private MaxGlobalMessageCount getGlobalMaxMessageEntity(EntityManager 
entityManager, Optional<QuotaCountLimit> maxMessageQuota) {
-        MaxGlobalMessageCount storedValue = 
entityManager.find(MaxGlobalMessageCount.class, 
MaxGlobalMessageCount.DEFAULT_KEY);
-        Long value = quotaValueToLong(maxMessageQuota);
-        if (storedValue == null) {
-            return new MaxGlobalMessageCount(value);
-        }
-        storedValue.setValue(value);
-        return storedValue;
-    }
-
-    public Optional<QuotaSizeLimit> getGlobalMaxStorage(EntityManager 
entityManager) {
-        MaxGlobalStorage storedValue = 
entityManager.find(MaxGlobalStorage.class, MaxGlobalStorage.DEFAULT_KEY);
-        if (storedValue == null) {
-            return Optional.empty();
-        }
-        return longToQuotaSize(storedValue.getValue());
-    }
-
-    public Optional<QuotaCountLimit> getGlobalMaxMessage(EntityManager 
entityManager) {
-        MaxGlobalMessageCount storedValue = 
entityManager.find(MaxGlobalMessageCount.class, 
MaxGlobalMessageCount.DEFAULT_KEY);
-        if (storedValue == null) {
-            return Optional.empty();
-        }
-        return longToQuotaCount(storedValue.getValue());
-    }
-
-    public Optional<QuotaSizeLimit> getMaxStorage(EntityManager entityManager, 
QuotaRoot quotaRoot) {
-        MaxUserStorage storedValue = entityManager.find(MaxUserStorage.class, 
quotaRoot.getValue());
-        if (storedValue == null) {
-            return Optional.empty();
-        }
-        return longToQuotaSize(storedValue.getValue());
-    }
-
-    public Optional<QuotaCountLimit> getMaxMessage(EntityManager 
entityManager, QuotaRoot quotaRoot) {
-        MaxUserMessageCount storedValue = 
entityManager.find(MaxUserMessageCount.class, quotaRoot.getValue());
-        if (storedValue == null) {
-            return Optional.empty();
-        }
-        return longToQuotaCount(storedValue.getValue());
-    }
-
-    public Optional<QuotaCountLimit> getDomainMaxMessage(EntityManager 
entityManager, Domain domain) {
-            MaxDomainMessageCount storedValue = 
entityManager.find(MaxDomainMessageCount.class, domain.asString());
-            if (storedValue == null) {
-                return Optional.empty();
-            }
-            return longToQuotaCount(storedValue.getValue());
-    }
-
-    public Optional<QuotaSizeLimit> getDomainMaxStorage(EntityManager 
entityManager, Domain domain) {
-        MaxDomainStorage storedValue = 
entityManager.find(MaxDomainStorage.class, domain.asString());
-        if (storedValue == null) {
-            return Optional.empty();
-        }
-        return longToQuotaSize(storedValue.getValue());
-    }
-
-
-    private Long quotaValueToLong(Optional<? extends QuotaLimitValue<?>> 
maxStorageQuota) {
-        return maxStorageQuota.map(value -> {
-            if (value.isUnlimited()) {
-                return INFINITE;
-            }
-            return value.asLong();
-        }).orElse(null);
-    }
-
-    private Optional<QuotaSizeLimit> longToQuotaSize(Long value) {
-        return longToQuotaValue(value, QuotaSizeLimit.unlimited(), 
QuotaSizeLimit::size);
-    }
-
-    private Optional<QuotaCountLimit> longToQuotaCount(Long value) {
-        return longToQuotaValue(value, QuotaCountLimit.unlimited(), 
QuotaCountLimit::count);
-    }
-
-    private <T extends QuotaLimitValue<T>> Optional<T> longToQuotaValue(Long 
value, T infiniteValue, Function<Long, T> quotaFactory) {
-        if (value == null) {
-            return Optional.empty();
-        }
-        if (value == INFINITE) {
-            return Optional.of(infiniteValue);
-        }
-        return Optional.of(quotaFactory.apply(value));
-    }
-
-}
diff --git 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/JPAPerUserMaxQuotaManager.java
 
b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/JPAPerUserMaxQuotaManager.java
deleted file mode 100644
index 6572b71ea5..0000000000
--- 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/JPAPerUserMaxQuotaManager.java
+++ /dev/null
@@ -1,292 +0,0 @@
-/****************************************************************
- * 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.postgres.quota;
-
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Function;
-import java.util.stream.Stream;
-
-import javax.inject.Inject;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.james.backends.jpa.EntityManagerUtils;
-import org.apache.james.core.Domain;
-import org.apache.james.core.quota.QuotaCountLimit;
-import org.apache.james.core.quota.QuotaSizeLimit;
-import org.apache.james.mailbox.model.Quota;
-import org.apache.james.mailbox.model.QuotaRoot;
-import org.apache.james.mailbox.quota.MaxQuotaManager;
-import org.reactivestreams.Publisher;
-
-import com.github.fge.lambdas.Throwing;
-import com.google.common.collect.ImmutableMap;
-
-import reactor.core.publisher.Mono;
-import reactor.core.scheduler.Schedulers;
-
-public class JPAPerUserMaxQuotaManager implements MaxQuotaManager {
-    private final EntityManagerFactory entityManagerFactory;
-    private final JPAPerUserMaxQuotaDAO dao;
-
-    @Inject
-    public JPAPerUserMaxQuotaManager(EntityManagerFactory 
entityManagerFactory, JPAPerUserMaxQuotaDAO dao) {
-        this.entityManagerFactory = entityManagerFactory;
-        this.dao = dao;
-    }
-
-    @Override
-    public void setMaxStorage(QuotaRoot quotaRoot, QuotaSizeLimit 
maxStorageQuota) {
-        dao.setMaxStorage(quotaRoot, Optional.of(maxStorageQuota));
-    }
-
-    @Override
-    public Publisher<Void> setMaxStorageReactive(QuotaRoot quotaRoot, 
QuotaSizeLimit maxStorageQuota) {
-        return Mono.fromRunnable(() -> setMaxStorage(quotaRoot, 
maxStorageQuota));
-    }
-
-    @Override
-    public void setMaxMessage(QuotaRoot quotaRoot, QuotaCountLimit 
maxMessageCount) {
-        dao.setMaxMessage(quotaRoot, Optional.of(maxMessageCount));
-    }
-
-    @Override
-    public Publisher<Void> setMaxMessageReactive(QuotaRoot quotaRoot, 
QuotaCountLimit maxMessageCount) {
-        return Mono.fromRunnable(() -> setMaxMessage(quotaRoot, 
maxMessageCount));
-    }
-
-    @Override
-    public void setDomainMaxMessage(Domain domain, QuotaCountLimit count) {
-        dao.setDomainMaxMessage(domain, Optional.of(count));
-    }
-
-    @Override
-    public Publisher<Void> setDomainMaxMessageReactive(Domain domain, 
QuotaCountLimit count) {
-        return Mono.fromRunnable(() -> setDomainMaxMessage(domain, count));
-    }
-
-    @Override
-    public void setDomainMaxStorage(Domain domain, QuotaSizeLimit size) {
-        dao.setDomainMaxStorage(domain, Optional.of(size));
-    }
-
-    @Override
-    public Publisher<Void> setDomainMaxStorageReactive(Domain domain, 
QuotaSizeLimit size) {
-        return Mono.fromRunnable(() -> setDomainMaxStorage(domain, size));
-    }
-
-    @Override
-    public void removeDomainMaxMessage(Domain domain) {
-        dao.setDomainMaxMessage(domain, Optional.empty());
-    }
-
-    @Override
-    public Publisher<Void> removeDomainMaxMessageReactive(Domain domain) {
-        return Mono.fromRunnable(() -> removeDomainMaxMessage(domain));
-    }
-
-    @Override
-    public void removeDomainMaxStorage(Domain domain) {
-        dao.setDomainMaxStorage(domain, Optional.empty());
-    }
-
-    @Override
-    public Publisher<Void> removeDomainMaxStorageReactive(Domain domain) {
-        return Mono.fromRunnable(() -> removeDomainMaxStorage(domain));
-    }
-
-    @Override
-    public Optional<QuotaCountLimit> getDomainMaxMessage(Domain domain) {
-        EntityManager entityManager = 
entityManagerFactory.createEntityManager();
-        try {
-            return dao.getDomainMaxMessage(entityManager, domain);
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
-        }
-    }
-
-    @Override
-    public Publisher<QuotaCountLimit> getDomainMaxMessageReactive(Domain 
domain) {
-        return Mono.fromSupplier(() -> getDomainMaxMessage(domain))
-            .flatMap(Mono::justOrEmpty);
-    }
-
-    @Override
-    public Optional<QuotaSizeLimit> getDomainMaxStorage(Domain domain) {
-        EntityManager entityManager = 
entityManagerFactory.createEntityManager();
-        try {
-            return dao.getDomainMaxStorage(entityManager, domain);
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
-        }
-    }
-
-    @Override
-    public Publisher<QuotaSizeLimit> getDomainMaxStorageReactive(Domain 
domain) {
-        return Mono.fromSupplier(() -> getDomainMaxStorage(domain))
-            .flatMap(Mono::justOrEmpty);
-    }
-
-    @Override
-    public void removeMaxMessage(QuotaRoot quotaRoot) {
-        dao.setMaxMessage(quotaRoot, Optional.empty());
-    }
-
-    @Override
-    public Publisher<Void> removeMaxMessageReactive(QuotaRoot quotaRoot) {
-        return Mono.fromRunnable(() -> removeMaxMessage(quotaRoot));
-    }
-
-    @Override
-    public void setGlobalMaxStorage(QuotaSizeLimit globalMaxStorage) {
-        dao.setGlobalMaxStorage(Optional.of(globalMaxStorage));
-    }
-
-    @Override
-    public Publisher<Void> setGlobalMaxStorageReactive(QuotaSizeLimit 
globalMaxStorage) {
-        return Mono.fromRunnable(() -> setGlobalMaxStorage(globalMaxStorage));
-    }
-
-    @Override
-    public void removeGlobalMaxMessage() {
-        dao.setGlobalMaxMessage(Optional.empty());
-    }
-
-    @Override
-    public Publisher<Void> removeGlobalMaxMessageReactive() {
-        return Mono.fromRunnable(this::removeGlobalMaxMessage);
-    }
-
-    @Override
-    public void setGlobalMaxMessage(QuotaCountLimit globalMaxMessageCount) {
-        dao.setGlobalMaxMessage(Optional.of(globalMaxMessageCount));
-    }
-
-    @Override
-    public Publisher<Void> setGlobalMaxMessageReactive(QuotaCountLimit 
globalMaxMessageCount) {
-        return Mono.fromRunnable(() -> 
setGlobalMaxMessage(globalMaxMessageCount));
-    }
-
-    @Override
-    public Optional<QuotaSizeLimit> getGlobalMaxStorage() {
-        EntityManager entityManager = 
entityManagerFactory.createEntityManager();
-        try {
-            return dao.getGlobalMaxStorage(entityManager);
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
-        }
-    }
-
-    @Override
-    public Publisher<QuotaSizeLimit> getGlobalMaxStorageReactive() {
-        return Mono.fromSupplier(this::getGlobalMaxStorage)
-            .flatMap(Mono::justOrEmpty);
-    }
-
-    @Override
-    public Optional<QuotaCountLimit> getGlobalMaxMessage() {
-        EntityManager entityManager = 
entityManagerFactory.createEntityManager();
-        try {
-            return dao.getGlobalMaxMessage(entityManager);
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
-        }
-    }
-
-    @Override
-    public Publisher<QuotaCountLimit> getGlobalMaxMessageReactive() {
-        return Mono.fromSupplier(this::getGlobalMaxMessage)
-            .flatMap(Mono::justOrEmpty);
-    }
-
-    @Override
-    public Publisher<QuotaDetails> quotaDetailsReactive(QuotaRoot quotaRoot) {
-        EntityManager entityManager = 
entityManagerFactory.createEntityManager();
-        return Mono.zip(
-                Mono.fromCallable(() -> listMaxMessagesDetails(quotaRoot, 
entityManager)),
-                Mono.fromCallable(() -> listMaxStorageDetails(quotaRoot, 
entityManager)))
-            .map(tuple -> new QuotaDetails(tuple.getT1(), tuple.getT2()))
-            .subscribeOn(Schedulers.boundedElastic())
-            .doFinally(any -> EntityManagerUtils.safelyClose(entityManager));
-    }
-
-    @Override
-    public Map<Quota.Scope, QuotaCountLimit> listMaxMessagesDetails(QuotaRoot 
quotaRoot) {
-        EntityManager entityManager = 
entityManagerFactory.createEntityManager();
-        try {
-            return listMaxMessagesDetails(quotaRoot, entityManager);
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
-        }
-    }
-
-    private ImmutableMap<Quota.Scope, QuotaCountLimit> 
listMaxMessagesDetails(QuotaRoot quotaRoot, EntityManager entityManager) {
-        Function<Domain, Optional<QuotaCountLimit>> domainQuotaFunction = 
Throwing.function(domain -> dao.getDomainMaxMessage(entityManager, domain));
-        return Stream.of(
-                Pair.of(Quota.Scope.User, dao.getMaxMessage(entityManager, 
quotaRoot)),
-                Pair.of(Quota.Scope.Domain, 
quotaRoot.getDomain().flatMap(domainQuotaFunction)),
-                Pair.of(Quota.Scope.Global, 
dao.getGlobalMaxMessage(entityManager)))
-            .filter(pair -> pair.getValue().isPresent())
-            .collect(ImmutableMap.toImmutableMap(Pair::getKey, value -> 
value.getValue().get()));
-    }
-
-    @Override
-    public Map<Quota.Scope, QuotaSizeLimit> listMaxStorageDetails(QuotaRoot 
quotaRoot) {
-        EntityManager entityManager = 
entityManagerFactory.createEntityManager();
-        try {
-            return listMaxStorageDetails(quotaRoot, entityManager);
-        } finally {
-            EntityManagerUtils.safelyClose(entityManager);
-        }
-    }
-
-    private ImmutableMap<Quota.Scope, QuotaSizeLimit> 
listMaxStorageDetails(QuotaRoot quotaRoot, EntityManager entityManager) {
-        Function<Domain, Optional<QuotaSizeLimit>> domainQuotaFunction = 
Throwing.function(domain -> dao.getDomainMaxStorage(entityManager, domain));
-        return Stream.of(
-                Pair.of(Quota.Scope.User, dao.getMaxStorage(entityManager, 
quotaRoot)),
-                Pair.of(Quota.Scope.Domain, 
quotaRoot.getDomain().flatMap(domainQuotaFunction)),
-                Pair.of(Quota.Scope.Global, 
dao.getGlobalMaxStorage(entityManager)))
-            .filter(pair -> pair.getValue().isPresent())
-            .collect(ImmutableMap.toImmutableMap(Pair::getKey, value -> 
value.getValue().get()));
-    }
-
-    @Override
-    public void removeMaxStorage(QuotaRoot quotaRoot) {
-        dao.setMaxStorage(quotaRoot, Optional.empty());
-    }
-
-    @Override
-    public Publisher<Void> removeMaxStorageReactive(QuotaRoot quotaRoot) {
-        return Mono.fromRunnable(() -> removeMaxStorage(quotaRoot));
-    }
-
-    @Override
-    public void removeGlobalMaxStorage() {
-        dao.setGlobalMaxStorage(Optional.empty());
-    }
-
-    @Override
-    public Publisher<Void> removeGlobalMaxStorageReactive() {
-        return Mono.fromRunnable(this::removeGlobalMaxStorage);
-    }
-
-}
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManagerV2.java
 
b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/PostgresPerUserMaxQuotaManager.java
similarity index 67%
copy from 
mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManagerV2.java
copy to 
mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/PostgresPerUserMaxQuotaManager.java
index 6697a9843a..e39ff808e1 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/CassandraPerUserMaxQuotaManagerV2.java
+++ 
b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/PostgresPerUserMaxQuotaManager.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.mailbox.cassandra.quota;
+package org.apache.james.mailbox.postgres.quota;
 
 import static org.apache.james.util.ReactorUtils.publishIfPresent;
 
@@ -30,7 +30,7 @@ import java.util.stream.Stream;
 import javax.inject.Inject;
 
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.james.backends.cassandra.components.CassandraQuotaLimitDao;
+import org.apache.james.backends.postgres.quota.PostgresQuotaLimitDAO;
 import org.apache.james.core.Domain;
 import org.apache.james.core.quota.QuotaComponent;
 import org.apache.james.core.quota.QuotaCountLimit;
@@ -40,22 +40,23 @@ import org.apache.james.core.quota.QuotaSizeLimit;
 import org.apache.james.core.quota.QuotaType;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.model.QuotaRoot;
+import org.apache.james.mailbox.quota.Limits;
 import org.apache.james.mailbox.quota.MaxQuotaManager;
+import org.apache.james.mailbox.quota.QuotaCodec;
 
 import com.google.common.collect.ImmutableMap;
 
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 
-public class CassandraPerUserMaxQuotaManagerV2 implements MaxQuotaManager {
-
+public class PostgresPerUserMaxQuotaManager implements MaxQuotaManager {
     private static final String GLOBAL_IDENTIFIER = "global";
 
-    private final CassandraQuotaLimitDao cassandraQuotaLimitDao;
+    private final PostgresQuotaLimitDAO postgresQuotaLimitDAO;
 
     @Inject
-    public CassandraPerUserMaxQuotaManagerV2(CassandraQuotaLimitDao 
cassandraQuotaLimitDao) {
-        this.cassandraQuotaLimitDao = cassandraQuotaLimitDao;
+    public PostgresPerUserMaxQuotaManager(PostgresQuotaLimitDAO 
postgresQuotaLimitDAO) {
+        this.postgresQuotaLimitDAO = postgresQuotaLimitDAO;
     }
 
     @Override
@@ -65,13 +66,13 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> setMaxStorageReactive(QuotaRoot quotaRoot, 
QuotaSizeLimit maxStorageQuota) {
-        return cassandraQuotaLimitDao.setQuotaLimit(QuotaLimit.builder()
-                .quotaScope(QuotaScope.USER)
-                .identifier(quotaRoot.getValue())
-                .quotaComponent(QuotaComponent.MAILBOX)
-                .quotaType(QuotaType.SIZE)
-                .quotaLimit(QuotaCodec.quotaValueToLong(maxStorageQuota))
-                .build());
+        return postgresQuotaLimitDAO.setQuotaLimit(QuotaLimit.builder()
+            .quotaScope(QuotaScope.USER)
+            .identifier(quotaRoot.getValue())
+            .quotaComponent(QuotaComponent.MAILBOX)
+            .quotaType(QuotaType.SIZE)
+            .quotaLimit(QuotaCodec.quotaValueToLong(maxStorageQuota))
+            .build());
     }
 
     @Override
@@ -81,13 +82,13 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> setMaxMessageReactive(QuotaRoot quotaRoot, 
QuotaCountLimit maxMessageCount) {
-        return cassandraQuotaLimitDao.setQuotaLimit(QuotaLimit.builder()
-                .quotaScope(QuotaScope.USER)
-                .identifier(quotaRoot.getValue())
-                .quotaComponent(QuotaComponent.MAILBOX)
-                .quotaType(QuotaType.COUNT)
-                .quotaLimit(QuotaCodec.quotaValueToLong(maxMessageCount))
-                .build());
+        return postgresQuotaLimitDAO.setQuotaLimit(QuotaLimit.builder()
+            .quotaScope(QuotaScope.USER)
+            .identifier(quotaRoot.getValue())
+            .quotaComponent(QuotaComponent.MAILBOX)
+            .quotaType(QuotaType.COUNT)
+            .quotaLimit(QuotaCodec.quotaValueToLong(maxMessageCount))
+            .build());
     }
 
     @Override
@@ -97,13 +98,13 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> setDomainMaxMessageReactive(Domain domain, 
QuotaCountLimit count) {
-        return cassandraQuotaLimitDao.setQuotaLimit(QuotaLimit.builder()
-                .quotaScope(QuotaScope.DOMAIN)
-                .identifier(domain.asString())
-                .quotaComponent(QuotaComponent.MAILBOX)
-                .quotaType(QuotaType.COUNT)
-                .quotaLimit(QuotaCodec.quotaValueToLong(count))
-                .build());
+        return postgresQuotaLimitDAO.setQuotaLimit(QuotaLimit.builder()
+            .quotaScope(QuotaScope.DOMAIN)
+            .identifier(domain.asString())
+            .quotaComponent(QuotaComponent.MAILBOX)
+            .quotaType(QuotaType.COUNT)
+            .quotaLimit(QuotaCodec.quotaValueToLong(count))
+            .build());
     }
 
     @Override
@@ -113,13 +114,13 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> setDomainMaxStorageReactive(Domain domain, 
QuotaSizeLimit size) {
-        return cassandraQuotaLimitDao.setQuotaLimit(QuotaLimit.builder()
-                .quotaScope(QuotaScope.DOMAIN)
-                .identifier(domain.asString())
-                .quotaComponent(QuotaComponent.MAILBOX)
-                .quotaType(QuotaType.SIZE)
-                .quotaLimit(QuotaCodec.quotaValueToLong(size))
-                .build());
+        return postgresQuotaLimitDAO.setQuotaLimit(QuotaLimit.builder()
+            .quotaScope(QuotaScope.DOMAIN)
+            .identifier(domain.asString())
+            .quotaComponent(QuotaComponent.MAILBOX)
+            .quotaType(QuotaType.SIZE)
+            .quotaLimit(QuotaCodec.quotaValueToLong(size))
+            .build());
     }
 
     @Override
@@ -129,7 +130,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> removeDomainMaxMessageReactive(Domain domain) {
-        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, domain.asString(), QuotaType.COUNT));
+        return 
postgresQuotaLimitDAO.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, domain.asString(), QuotaType.COUNT));
     }
 
     @Override
@@ -139,7 +140,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> removeDomainMaxStorageReactive(Domain domain) {
-        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, domain.asString(), QuotaType.SIZE));
+        return 
postgresQuotaLimitDAO.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.DOMAIN, domain.asString(), QuotaType.SIZE));
     }
 
     @Override
@@ -169,7 +170,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> removeMaxMessageReactive(QuotaRoot quotaRoot) {
-        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.USER, quotaRoot.getValue(), QuotaType.COUNT));
+        return 
postgresQuotaLimitDAO.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.USER, quotaRoot.getValue(), QuotaType.COUNT));
     }
 
     @Override
@@ -179,7 +180,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> removeMaxStorageReactive(QuotaRoot quotaRoot) {
-        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.USER, quotaRoot.getValue(), QuotaType.SIZE));
+        return 
postgresQuotaLimitDAO.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.USER, quotaRoot.getValue(), QuotaType.SIZE));
     }
 
     @Override
@@ -189,12 +190,12 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> setGlobalMaxStorageReactive(QuotaSizeLimit 
globalMaxStorage) {
-        return cassandraQuotaLimitDao.setQuotaLimit(QuotaLimit.builder()
-                .quotaScope(QuotaScope.GLOBAL).identifier(GLOBAL_IDENTIFIER)
-                .quotaComponent(QuotaComponent.MAILBOX)
-                .quotaType(QuotaType.SIZE)
-                .quotaLimit(QuotaCodec.quotaValueToLong(globalMaxStorage))
-                .build());
+        return postgresQuotaLimitDAO.setQuotaLimit(QuotaLimit.builder()
+            .quotaScope(QuotaScope.GLOBAL).identifier(GLOBAL_IDENTIFIER)
+            .quotaComponent(QuotaComponent.MAILBOX)
+            .quotaType(QuotaType.SIZE)
+            .quotaLimit(QuotaCodec.quotaValueToLong(globalMaxStorage))
+            .build());
     }
 
     @Override
@@ -204,7 +205,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> removeGlobalMaxStorageReactive() {
-        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.GLOBAL, GLOBAL_IDENTIFIER, QuotaType.SIZE));
+        return 
postgresQuotaLimitDAO.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.GLOBAL, GLOBAL_IDENTIFIER, QuotaType.SIZE));
     }
 
     @Override
@@ -214,12 +215,12 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> setGlobalMaxMessageReactive(QuotaCountLimit 
globalMaxMessageCount) {
-        return cassandraQuotaLimitDao.setQuotaLimit(QuotaLimit.builder()
-                .quotaScope(QuotaScope.GLOBAL).identifier(GLOBAL_IDENTIFIER)
-                .quotaComponent(QuotaComponent.MAILBOX)
-                .quotaType(QuotaType.COUNT)
-                .quotaLimit(QuotaCodec.quotaValueToLong(globalMaxMessageCount))
-                .build());
+        return postgresQuotaLimitDAO.setQuotaLimit(QuotaLimit.builder()
+            .quotaScope(QuotaScope.GLOBAL).identifier(GLOBAL_IDENTIFIER)
+            .quotaComponent(QuotaComponent.MAILBOX)
+            .quotaType(QuotaType.COUNT)
+            .quotaLimit(QuotaCodec.quotaValueToLong(globalMaxMessageCount))
+            .build());
     }
 
     @Override
@@ -229,7 +230,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     @Override
     public Mono<Void> removeGlobalMaxMessageReactive() {
-        return 
cassandraQuotaLimitDao.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.GLOBAL, GLOBAL_IDENTIFIER, QuotaType.COUNT));
+        return 
postgresQuotaLimitDAO.deleteQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 QuotaScope.GLOBAL, GLOBAL_IDENTIFIER, QuotaType.COUNT));
     }
 
     @Override
@@ -262,11 +263,11 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
         return Flux.merge(
             getMaxMessageReactive(QuotaScope.USER, quotaRoot.getValue())
                 .map(limit -> Pair.of(Quota.Scope.User, limit)),
-            Mono.justOrEmpty(quotaRoot.getDomain())
-                .flatMap(domain -> getMaxMessageReactive(QuotaScope.DOMAIN, 
domain.asString()))
-                .map(limit -> Pair.of(Quota.Scope.Domain, limit)),
-            getGlobalMaxMessageReactive()
-                .map(limit -> Pair.of(Quota.Scope.Global, limit)))
+                Mono.justOrEmpty(quotaRoot.getDomain())
+                    .flatMap(domain -> 
getMaxMessageReactive(QuotaScope.DOMAIN, domain.asString()))
+                    .map(limit -> Pair.of(Quota.Scope.Domain, limit)),
+                getGlobalMaxMessageReactive()
+                    .map(limit -> Pair.of(Quota.Scope.Global, limit)))
             .collect(ImmutableMap.toImmutableMap(
                 Pair::getKey,
                 Pair::getValue));
@@ -282,11 +283,11 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
         return Flux.merge(
             getMaxStorageReactive(QuotaScope.USER, quotaRoot.getValue())
                 .map(limit -> Pair.of(Quota.Scope.User, limit)),
-            Mono.justOrEmpty(quotaRoot.getDomain())
-                .flatMap(domain -> getMaxStorageReactive(QuotaScope.DOMAIN, 
domain.asString()))
-                .map(limit -> Pair.of(Quota.Scope.Domain, limit)),
-            getGlobalMaxStorageReactive()
-                .map(limit -> Pair.of(Quota.Scope.Global, limit)))
+                Mono.justOrEmpty(quotaRoot.getDomain())
+                    .flatMap(domain -> 
getMaxStorageReactive(QuotaScope.DOMAIN, domain.asString()))
+                    .map(limit -> Pair.of(Quota.Scope.Domain, limit)),
+                getGlobalMaxStorageReactive()
+                    .map(limit -> Pair.of(Quota.Scope.Global, limit)))
             .collect(ImmutableMap.toImmutableMap(
                 Pair::getKey,
                 Pair::getValue));
@@ -302,15 +303,15 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
     public Mono<QuotaDetails> quotaDetailsReactive(QuotaRoot quotaRoot) {
         return Mono.zip(
             getLimits(QuotaScope.USER, quotaRoot.getValue()),
-            Mono.justOrEmpty(quotaRoot.getDomain()).flatMap(domain -> 
getLimits(QuotaScope.DOMAIN, 
domain.asString())).switchIfEmpty(Mono.just(Limits.empty())),
-            getLimits(QuotaScope.GLOBAL, GLOBAL_IDENTIFIER))
+                Mono.justOrEmpty(quotaRoot.getDomain()).flatMap(domain -> 
getLimits(QuotaScope.DOMAIN, 
domain.asString())).switchIfEmpty(Mono.just(Limits.empty())),
+                getLimits(QuotaScope.GLOBAL, GLOBAL_IDENTIFIER))
             .map(tuple -> new QuotaDetails(
                 countDetails(tuple.getT1(), tuple.getT2(), 
tuple.getT3().getCountLimit()),
                 sizeDetails(tuple.getT1(), tuple.getT2(), 
tuple.getT3().getSizeLimit())));
     }
 
     private Mono<Limits> getLimits(QuotaScope quotaScope, String identifier) {
-        return cassandraQuotaLimitDao.getQuotaLimits(QuotaComponent.MAILBOX, 
quotaScope, identifier)
+        return postgresQuotaLimitDAO.getQuotaLimits(QuotaComponent.MAILBOX, 
quotaScope, identifier)
             .collectList()
             .map(list -> {
                 Map<QuotaType, Optional<Long>> map = 
list.stream().collect(Collectors.toMap(QuotaLimit::getQuotaType, 
QuotaLimit::getQuotaLimit));
@@ -321,7 +322,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
     }
 
     private Mono<QuotaCountLimit> getMaxMessageReactive(QuotaScope quotaScope, 
String identifier) {
-        return 
cassandraQuotaLimitDao.getQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 quotaScope, identifier, QuotaType.COUNT))
+        return 
postgresQuotaLimitDAO.getQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 quotaScope, identifier, QuotaType.COUNT))
             .map(QuotaLimit::getQuotaLimit)
             .handle(publishIfPresent())
             .map(QuotaCodec::longToQuotaCount)
@@ -329,7 +330,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
     }
 
     public Mono<QuotaSizeLimit> getMaxStorageReactive(QuotaScope quotaScope, 
String identifier) {
-        return 
cassandraQuotaLimitDao.getQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 quotaScope, identifier, QuotaType.SIZE))
+        return 
postgresQuotaLimitDAO.getQuotaLimit(QuotaLimit.QuotaLimitKey.of(QuotaComponent.MAILBOX,
 quotaScope, identifier, QuotaType.SIZE))
             .map(QuotaLimit::getQuotaLimit)
             .handle(publishIfPresent())
             .map(QuotaCodec::longToQuotaSize)
@@ -338,7 +339,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     private Map<Quota.Scope, QuotaSizeLimit> sizeDetails(Limits userLimits, 
Limits domainLimits, Optional<QuotaSizeLimit> globalLimits) {
         return Stream.of(
-                userLimits.getSizeLimit().stream().map(limit -> 
Pair.of(Quota.Scope.User, limit)),
+            userLimits.getSizeLimit().stream().map(limit -> 
Pair.of(Quota.Scope.User, limit)),
                 domainLimits.getSizeLimit().stream().map(limit -> 
Pair.of(Quota.Scope.Domain, limit)),
                 globalLimits.stream().map(limit -> Pair.of(Quota.Scope.Global, 
limit)))
             .flatMap(Function.identity())
@@ -349,7 +350,7 @@ public class CassandraPerUserMaxQuotaManagerV2 implements 
MaxQuotaManager {
 
     private Map<Quota.Scope, QuotaCountLimit> countDetails(Limits userLimits, 
Limits domainLimits, Optional<QuotaCountLimit> globalLimits) {
         return Stream.of(
-                userLimits.getCountLimit().stream().map(limit -> 
Pair.of(Quota.Scope.User, limit)),
+            userLimits.getCountLimit().stream().map(limit -> 
Pair.of(Quota.Scope.User, limit)),
                 domainLimits.getCountLimit().stream().map(limit -> 
Pair.of(Quota.Scope.Domain, limit)),
                 globalLimits.stream().map(limit -> Pair.of(Quota.Scope.Global, 
limit)))
             .flatMap(Function.identity())
diff --git 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxDomainMessageCount.java
 
b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxDomainMessageCount.java
deleted file mode 100644
index be4cf2a30a..0000000000
--- 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxDomainMessageCount.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************
- * 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.postgres.quota.model;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-import org.apache.james.core.Domain;
-
-@Entity(name = "MaxDomainMessageCount")
-@Table(name = "JAMES_MAX_DOMAIN_MESSAGE_COUNT")
-public class MaxDomainMessageCount {
-    @Id
-    @Column(name = "DOMAIN")
-    private String domain;
-
-    @Column(name = "VALUE", nullable = true)
-    private Long value;
-
-    public MaxDomainMessageCount(Domain domain, Long value) {
-        this.domain = domain.asString();
-        this.value = value;
-    }
-
-    public MaxDomainMessageCount() {
-    }
-
-    public Long getValue() {
-        return value;
-    }
-
-    public void setValue(Long value) {
-        this.value = value;
-    }
-}
diff --git 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxDomainStorage.java
 
b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxDomainStorage.java
deleted file mode 100644
index ec668421dc..0000000000
--- 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxDomainStorage.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/****************************************************************
- * 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.postgres.quota.model;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-import org.apache.james.core.Domain;
-
-@Entity(name = "MaxDomainStorage")
-@Table(name = "JAMES_MAX_DOMAIN_STORAGE")
-public class MaxDomainStorage {
-
-    @Id
-    @Column(name = "DOMAIN")
-    private String domain;
-
-    @Column(name = "VALUE", nullable = true)
-    private Long value;
-
-    public MaxDomainStorage(Domain domain, Long value) {
-        this.domain = domain.asString();
-        this.value = value;
-    }
-
-    public MaxDomainStorage() {
-    }
-
-    public Long getValue() {
-        return value;
-    }
-
-    public void setValue(Long value) {
-        this.value = value;
-    }
-}
diff --git 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxGlobalMessageCount.java
 
b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxGlobalMessageCount.java
deleted file mode 100644
index 1041e75533..0000000000
--- 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxGlobalMessageCount.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************
- * 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.postgres.quota.model;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity(name = "MaxGlobalMessageCount")
-@Table(name = "JAMES_MAX_GLOBAL_MESSAGE_COUNT")
-public class MaxGlobalMessageCount {
-    public static final String DEFAULT_KEY = "default_key";
-    
-    @Id
-    @Column(name = "QUOTAROOT_ID")
-    private String quotaRoot = DEFAULT_KEY;
-
-    @Column(name = "VALUE", nullable = true)
-    private Long value;
-
-    public MaxGlobalMessageCount(Long value) {
-        this.quotaRoot = DEFAULT_KEY;
-        this.value = value;
-    }
-
-    public MaxGlobalMessageCount() {
-    }
-
-    public Long getValue() {
-        return value;
-    }
-
-    public void setValue(Long value) {
-        this.value = value;
-    }
-}
diff --git 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxGlobalStorage.java
 
b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxGlobalStorage.java
deleted file mode 100644
index 59b9a1601c..0000000000
--- 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxGlobalStorage.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************
- * 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.postgres.quota.model;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity(name = "MaxGlobalStorage")
-@Table(name = "JAMES_MAX_Global_STORAGE")
-public class MaxGlobalStorage {
-    public static final String DEFAULT_KEY = "default_key";
-   
-    @Id
-    @Column(name = "QUOTAROOT_ID")
-    private String quotaRoot = DEFAULT_KEY;
-
-    @Column(name = "VALUE", nullable = true)
-    private Long value;
-
-    public MaxGlobalStorage(Long value) {
-        this.quotaRoot = DEFAULT_KEY;
-        this.value = value;
-    }
-
-    public MaxGlobalStorage() {
-    }
-
-    public Long getValue() {
-        return value;
-    }
-
-    public void setValue(Long value) {
-        this.value = value;
-    }
-}
diff --git 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxUserMessageCount.java
 
b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxUserMessageCount.java
deleted file mode 100644
index 9f31a8ef5e..0000000000
--- 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxUserMessageCount.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/****************************************************************
- * 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.postgres.quota.model;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity(name = "MaxUserMessageCount")
-@Table(name = "JAMES_MAX_USER_MESSAGE_COUNT")
-public class MaxUserMessageCount {
-    @Id
-    @Column(name = "QUOTAROOT_ID")
-    private String quotaRoot;
-
-    @Column(name = "VALUE", nullable = true)
-    private Long value;
-
-    public MaxUserMessageCount(String quotaRoot, Long value) {
-        this.quotaRoot = quotaRoot;
-        this.value = value;
-    }
-
-    public MaxUserMessageCount() {
-    }
-
-    public Long getValue() {
-        return value;
-    }
-
-    public void setValue(Long value) {
-        this.value = value;
-    }
-}
diff --git 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxUserStorage.java
 
b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxUserStorage.java
deleted file mode 100644
index a4633380d0..0000000000
--- 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/quota/model/MaxUserStorage.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/****************************************************************
- * 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.postgres.quota.model;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity(name = "MaxUserStorage")
-@Table(name = "JAMES_MAX_USER_STORAGE")
-public class MaxUserStorage {
-
-    @Id
-    @Column(name = "QUOTAROOT_ID")
-    private String quotaRoot;
-
-    @Column(name = "VALUE", nullable = true)
-    private Long value;
-
-    public MaxUserStorage(String quotaRoot, Long value) {
-        this.quotaRoot = quotaRoot;
-        this.value = value;
-    }
-
-    public MaxUserStorage() {
-    }
-
-    public Long getValue() {
-        return value;
-    }
-
-    public void setValue(Long value) {
-        this.value = value;
-    }
-}
diff --git 
a/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/JPAMailboxFixture.java
 
b/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/JPAMailboxFixture.java
deleted file mode 100644
index 6c34d837d7..0000000000
--- 
a/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/JPAMailboxFixture.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/****************************************************************
- * 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.postgres;
-
-import java.util.List;
-
-import org.apache.james.mailbox.postgres.quota.model.MaxDomainMessageCount;
-import org.apache.james.mailbox.postgres.quota.model.MaxDomainStorage;
-import org.apache.james.mailbox.postgres.quota.model.MaxGlobalMessageCount;
-import org.apache.james.mailbox.postgres.quota.model.MaxGlobalStorage;
-import org.apache.james.mailbox.postgres.quota.model.MaxUserMessageCount;
-import org.apache.james.mailbox.postgres.quota.model.MaxUserStorage;
-
-import com.google.common.collect.ImmutableList;
-
-public interface JPAMailboxFixture {
-
-    List<Class<?>> QUOTA_PERSISTANCE_CLASSES = ImmutableList.of(
-        MaxGlobalMessageCount.class,
-        MaxGlobalStorage.class,
-        MaxDomainStorage.class,
-        MaxDomainMessageCount.class,
-        MaxUserMessageCount.class,
-        MaxUserStorage.class);
-
-    List<String> QUOTA_TABLES_NAMES = ImmutableList.of(
-        "JAMES_MAX_GLOBAL_MESSAGE_COUNT",
-        "JAMES_MAX_GLOBAL_STORAGE",
-        "JAMES_MAX_USER_MESSAGE_COUNT",
-        "JAMES_MAX_USER_STORAGE",
-        "JAMES_MAX_DOMAIN_MESSAGE_COUNT",
-        "JAMES_MAX_DOMAIN_STORAGE"
-    );
-}
diff --git 
a/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/quota/JPAPerUserMaxQuotaTest.java
 
b/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/quota/PostgresPerUserMaxQuotaManagerTest.java
similarity index 65%
rename from 
mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/quota/JPAPerUserMaxQuotaTest.java
rename to 
mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/quota/PostgresPerUserMaxQuotaManagerTest.java
index 6b14d6f83c..56da9f2378 100644
--- 
a/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/quota/JPAPerUserMaxQuotaTest.java
+++ 
b/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/quota/PostgresPerUserMaxQuotaManagerTest.java
@@ -19,25 +19,19 @@
 
 package org.apache.james.mailbox.postgres.quota;
 
-import org.apache.james.backends.jpa.JpaTestCluster;
-import org.apache.james.mailbox.postgres.JPAMailboxFixture;
-import org.apache.james.mailbox.postgres.quota.JPAPerUserMaxQuotaDAO;
-import org.apache.james.mailbox.postgres.quota.JPAPerUserMaxQuotaManager;
+import org.apache.james.backends.postgres.PostgresExtension;
+import org.apache.james.backends.postgres.quota.PostgresQuotaLimitDAO;
+import org.apache.james.backends.postgres.quota.PostgresQuotaModule;
 import org.apache.james.mailbox.quota.MaxQuotaManager;
 import org.apache.james.mailbox.store.quota.GenericMaxQuotaManagerTest;
-import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.extension.RegisterExtension;
 
-class JPAPerUserMaxQuotaTest extends GenericMaxQuotaManagerTest {
-
-    static final JpaTestCluster JPA_TEST_CLUSTER = 
JpaTestCluster.create(JPAMailboxFixture.QUOTA_PERSISTANCE_CLASSES);
+public class PostgresPerUserMaxQuotaManagerTest extends 
GenericMaxQuotaManagerTest {
+    @RegisterExtension
+    static PostgresExtension postgresExtension = 
PostgresExtension.withoutRowLevelSecurity(PostgresQuotaModule.MODULE);
 
     @Override
     protected MaxQuotaManager provideMaxQuotaManager() {
-        return new 
JPAPerUserMaxQuotaManager(JPA_TEST_CLUSTER.getEntityManagerFactory(), new 
JPAPerUserMaxQuotaDAO(JPA_TEST_CLUSTER.getEntityManagerFactory()));
-    }
-
-    @AfterEach
-    void cleanUp() {
-        JPA_TEST_CLUSTER.clear(JPAMailboxFixture.QUOTA_TABLES_NAMES);
+        return new PostgresPerUserMaxQuotaManager(new 
PostgresQuotaLimitDAO(postgresExtension.getPostgresExecutor()));
     }
 }
diff --git a/mailbox/postgres/src/test/resources/persistence.xml 
b/mailbox/postgres/src/test/resources/persistence.xml
deleted file mode 100644
index 21199cfdd4..0000000000
--- a/mailbox/postgres/src/test/resources/persistence.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.    
--->
-
-<persistence xmlns="http://java.sun.com/xml/ns/persistence";
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
-    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd";
-    version="2.0">
-
-    <persistence-unit name="James" transaction-type="RESOURCE_LOCAL">
-        
<class>org.apache.james.mailbox.postgres.quota.model.MaxDomainMessageCount</class>
-        
<class>org.apache.james.mailbox.postgres.quota.model.MaxDomainStorage</class>
-        
<class>org.apache.james.mailbox.postgres.quota.model.MaxGlobalMessageCount</class>
-        
<class>org.apache.james.mailbox.postgres.quota.model.MaxGlobalStorage</class>
-        
<class>org.apache.james.mailbox.postgres.quota.model.MaxUserMessageCount</class>
-        
<class>org.apache.james.mailbox.postgres.quota.model.MaxUserStorage</class>
-        <properties>
-            <property name="openjpa.jdbc.SynchronizeMappings" 
value="buildSchema(ForeignKeys=true)"/>
-            <property name="openjpa.jdbc.MappingDefaults" 
value="ForeignKeyDeleteAction=cascade, JoinForeignKeyDeleteAction=cascade"/>
-            <property name="openjpa.jdbc.SchemaFactory" 
value="native(ForeignKeys=true)"/>
-            <property name="openjpa.jdbc.QuerySQLCache" value="false"/>
-        </properties>
-
-    </persistence-unit>
-
-</persistence>
diff --git 
a/mpt/impl/imap-mailbox/postgres/src/test/java/org/apache/james/mpt/imapmailbox/postgres/host/PostgresHostSystem.java
 
b/mpt/impl/imap-mailbox/postgres/src/test/java/org/apache/james/mpt/imapmailbox/postgres/host/PostgresHostSystem.java
index 5c5ab7e688..0e2a041730 100644
--- 
a/mpt/impl/imap-mailbox/postgres/src/test/java/org/apache/james/mpt/imapmailbox/postgres/host/PostgresHostSystem.java
+++ 
b/mpt/impl/imap-mailbox/postgres/src/test/java/org/apache/james/mpt/imapmailbox/postgres/host/PostgresHostSystem.java
@@ -22,11 +22,9 @@ package org.apache.james.mpt.imapmailbox.postgres.host;
 import java.time.Clock;
 import java.time.Instant;
 
-import javax.persistence.EntityManagerFactory;
-
-import org.apache.james.backends.jpa.JpaTestCluster;
 import org.apache.james.backends.postgres.PostgresExtension;
 import org.apache.james.backends.postgres.quota.PostgresQuotaCurrentValueDAO;
+import org.apache.james.backends.postgres.quota.PostgresQuotaLimitDAO;
 import org.apache.james.blob.api.BlobId;
 import org.apache.james.blob.api.BucketName;
 import org.apache.james.blob.api.HashBlobId;
@@ -46,13 +44,11 @@ import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.SubscriptionManager;
 import org.apache.james.mailbox.acl.MailboxACLResolver;
 import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
-import org.apache.james.mailbox.postgres.JPAMailboxFixture;
 import org.apache.james.mailbox.postgres.PostgresMailboxSessionMapperFactory;
 import org.apache.james.mailbox.postgres.PostgresMessageId;
 import org.apache.james.mailbox.postgres.mail.PostgresMailboxManager;
-import org.apache.james.mailbox.postgres.quota.JPAPerUserMaxQuotaDAO;
-import org.apache.james.mailbox.postgres.quota.JPAPerUserMaxQuotaManager;
 import org.apache.james.mailbox.postgres.quota.PostgresCurrentQuotaManager;
+import org.apache.james.mailbox.postgres.quota.PostgresPerUserMaxQuotaManager;
 import org.apache.james.mailbox.quota.CurrentQuotaManager;
 import org.apache.james.mailbox.store.SessionProviderImpl;
 import org.apache.james.mailbox.store.StoreMailboxAnnotationManager;
@@ -77,15 +73,9 @@ import 
org.apache.james.server.blob.deduplication.DeDuplicationBlobStore;
 import org.apache.james.utils.UpdatableTickingClock;
 
 import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
 
 public class PostgresHostSystem extends JamesImapHostSystem {
 
-    private static final JpaTestCluster JPA_TEST_CLUSTER = 
JpaTestCluster.create(
-        ImmutableList.<Class<?>>builder()
-            .addAll(JPAMailboxFixture.QUOTA_PERSISTANCE_CLASSES)
-            .build());
-
     private static final ImapFeatures SUPPORTED_FEATURES = 
ImapFeatures.of(Feature.NAMESPACE_SUPPORT,
         Feature.USER_FLAGS_SUPPORT,
         Feature.ANNOTATION_SUPPORT,
@@ -98,7 +88,7 @@ public class PostgresHostSystem extends JamesImapHostSystem {
         return new PostgresHostSystem(postgresExtension);
     }
 
-    private JPAPerUserMaxQuotaManager maxQuotaManager;
+    private PostgresPerUserMaxQuotaManager maxQuotaManager;
     private PostgresMailboxManager mailboxManager;
     private final PostgresExtension postgresExtension;
 
@@ -113,7 +103,6 @@ public class PostgresHostSystem extends JamesImapHostSystem 
{
     @Override
     public void beforeTest() throws Exception {
         super.beforeTest();
-        EntityManagerFactory entityManagerFactory = 
JPA_TEST_CLUSTER.getEntityManagerFactory();
 
         BlobId.Factory blobIdFactory = new HashBlobId.Factory();
         DeDuplicationBlobStore blobStore = new DeDuplicationBlobStore(new 
MemoryBlobStoreDAO(), BucketName.DEFAULT, blobIdFactory);
@@ -130,7 +119,7 @@ public class PostgresHostSystem extends JamesImapHostSystem 
{
         SessionProviderImpl sessionProvider = new 
SessionProviderImpl(authenticator, authorizator);
         DefaultUserQuotaRootResolver quotaRootResolver = new 
DefaultUserQuotaRootResolver(sessionProvider, mapperFactory);
         CurrentQuotaManager currentQuotaManager = new 
PostgresCurrentQuotaManager(new 
PostgresQuotaCurrentValueDAO(postgresExtension.getPostgresExecutor()));
-        maxQuotaManager = new JPAPerUserMaxQuotaManager(entityManagerFactory, 
new JPAPerUserMaxQuotaDAO(entityManagerFactory));
+        maxQuotaManager = new PostgresPerUserMaxQuotaManager(new 
PostgresQuotaLimitDAO(postgresExtension.getPostgresExecutor()));
         StoreQuotaManager storeQuotaManager = new 
StoreQuotaManager(currentQuotaManager, maxQuotaManager);
         ListeningCurrentQuotaUpdater quotaUpdater = new 
ListeningCurrentQuotaUpdater(currentQuotaManager, quotaRootResolver, eventBus, 
storeQuotaManager);
         QuotaComponents quotaComponents = new QuotaComponents(maxQuotaManager, 
storeQuotaManager, quotaRootResolver);
@@ -160,13 +149,6 @@ public class PostgresHostSystem extends 
JamesImapHostSystem {
             defaultImapProcessorFactory);
     }
 
-    @Override
-    public void afterTest() {
-        JPA_TEST_CLUSTER.clear(ImmutableList.<String>builder()
-            .addAll(JPAMailboxFixture.QUOTA_TABLES_NAMES)
-            .build());
-    }
-
     @Override
     protected MailboxManager getMailboxManager() {
         return mailboxManager;
diff --git 
a/server/apps/postgres-app/src/main/resources/META-INF/persistence.xml 
b/server/apps/postgres-app/src/main/resources/META-INF/persistence.xml
index e223792513..d074a13385 100644
--- a/server/apps/postgres-app/src/main/resources/META-INF/persistence.xml
+++ b/server/apps/postgres-app/src/main/resources/META-INF/persistence.xml
@@ -29,15 +29,6 @@
         <class>org.apache.james.rrt.jpa.model.JPARecipientRewrite</class>
         <class>org.apache.james.sieve.postgres.model.JPASieveScript</class>
 
-        
<class>org.apache.james.mailbox.postgres.quota.model.MaxDomainMessageCount</class>
-        
<class>org.apache.james.mailbox.postgres.quota.model.MaxDomainStorage</class>
-        
<class>org.apache.james.mailbox.postgres.quota.model.MaxGlobalMessageCount</class>
-        
<class>org.apache.james.mailbox.postgres.quota.model.MaxGlobalStorage</class>
-        
<class>org.apache.james.mailbox.postgres.quota.model.MaxUserMessageCount</class>
-        
<class>org.apache.james.mailbox.postgres.quota.model.MaxUserStorage</class>
-        
<class>org.apache.james.mailbox.postgres.quota.model.MaxDomainStorage</class>
-        
<class>org.apache.james.mailbox.postgres.quota.model.MaxDomainMessageCount</class>
-
         <properties>
             <property name="openjpa.jdbc.SynchronizeMappings" 
value="buildSchema(ForeignKeys=true)"/>
             <property name="openjpa.jdbc.MappingDefaults" 
value="ForeignKeyDeleteAction=cascade, JoinForeignKeyDeleteAction=cascade"/>
diff --git 
a/server/container/guice/mailbox-postgres/src/main/java/org/apache/james/modules/mailbox/PostgresQuotaModule.java
 
b/server/container/guice/mailbox-postgres/src/main/java/org/apache/james/modules/mailbox/PostgresQuotaModule.java
index 8815b27812..19894e74af 100644
--- 
a/server/container/guice/mailbox-postgres/src/main/java/org/apache/james/modules/mailbox/PostgresQuotaModule.java
+++ 
b/server/container/guice/mailbox-postgres/src/main/java/org/apache/james/modules/mailbox/PostgresQuotaModule.java
@@ -19,9 +19,10 @@
 
 package org.apache.james.modules.mailbox;
 
+import org.apache.james.backends.postgres.PostgresModule;
 import org.apache.james.events.EventListener;
-import org.apache.james.mailbox.postgres.quota.JPAPerUserMaxQuotaManager;
 import org.apache.james.mailbox.postgres.quota.PostgresCurrentQuotaManager;
+import org.apache.james.mailbox.postgres.quota.PostgresPerUserMaxQuotaManager;
 import org.apache.james.mailbox.quota.CurrentQuotaManager;
 import org.apache.james.mailbox.quota.MaxQuotaManager;
 import org.apache.james.mailbox.quota.QuotaManager;
@@ -41,15 +42,18 @@ public class PostgresQuotaModule extends AbstractModule {
 
     @Override
     protected void configure() {
+        Multibinder<PostgresModule> postgresDataDefinitions = 
Multibinder.newSetBinder(binder(), PostgresModule.class);
+        
postgresDataDefinitions.addBinding().toInstance(org.apache.james.backends.postgres.quota.PostgresQuotaModule.MODULE);
+
         bind(DefaultUserQuotaRootResolver.class).in(Scopes.SINGLETON);
-        bind(JPAPerUserMaxQuotaManager.class).in(Scopes.SINGLETON);
+        bind(PostgresPerUserMaxQuotaManager.class).in(Scopes.SINGLETON);
         bind(StoreQuotaManager.class).in(Scopes.SINGLETON);
         bind(PostgresCurrentQuotaManager.class).in(Scopes.SINGLETON);
 
         
bind(UserQuotaRootResolver.class).to(DefaultUserQuotaRootResolver.class);
         bind(QuotaRootResolver.class).to(DefaultUserQuotaRootResolver.class);
         
bind(QuotaRootDeserializer.class).to(DefaultUserQuotaRootResolver.class);
-        bind(MaxQuotaManager.class).to(JPAPerUserMaxQuotaManager.class);
+        bind(MaxQuotaManager.class).to(PostgresPerUserMaxQuotaManager.class);
         bind(QuotaManager.class).to(StoreQuotaManager.class);
         bind(CurrentQuotaManager.class).to(PostgresCurrentQuotaManager.class);
 


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

Reply via email to