MAILBOX-291 Allow to store max quotas in JPA using Spring
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/fcdfc80f Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/fcdfc80f Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/fcdfc80f Branch: refs/heads/master Commit: fcdfc80f37f070fd762d97fb5507c4f9c99ff76a Parents: 8fabac5 Author: benwa <btell...@linagora.com> Authored: Wed Mar 29 14:17:43 2017 +0700 Committer: benwa <btell...@linagora.com> Committed: Fri Mar 31 08:46:12 2017 +0700 ---------------------------------------------------------------------- .../destination/conf/META-INF/persistence.xml | 4 ++ .../jpa/quota/JPAPerUserMaxQuotaManager.java | 2 + .../resources/META-INF/spring/mailbox-jpa.xml | 1 + .../src/main/resources/META-INF/persistence.xml | 4 ++ .../app/src/main/resources/quota-template.xml | 41 +++++++++++--------- .../QuotaBeanFactoryPostProcessor.java | 3 ++ server/src/site/xdoc/config-quota.xml | 5 ++- 7 files changed, 39 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/fcdfc80f/dockerfiles/run/spring/destination/conf/META-INF/persistence.xml ---------------------------------------------------------------------- diff --git a/dockerfiles/run/spring/destination/conf/META-INF/persistence.xml b/dockerfiles/run/spring/destination/conf/META-INF/persistence.xml index 33a9d6a..1459879 100644 --- a/dockerfiles/run/spring/destination/conf/META-INF/persistence.xml +++ b/dockerfiles/run/spring/destination/conf/META-INF/persistence.xml @@ -35,6 +35,10 @@ <class>org.apache.james.domainlist.jpa.model.JPADomain</class> <class>org.apache.james.user.jpa.model.JPAUser</class> <class>org.apache.james.rrt.jpa.model.JPARecipientRewrite</class> + <class>org.apache.james.mailbox.jpa.quota.model.MaxDefaultMessageCount</class> + <class>org.apache.james.mailbox.jpa.quota.model.MaxDefaultStorage</class> + <class>org.apache.james.mailbox.jpa.quota.model.MaxUserMessageCount</class> + <class>org.apache.james.mailbox.jpa.quota.model.MaxUserStorage</class> <properties> <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/> http://git-wip-us.apache.org/repos/asf/james-project/blob/fcdfc80f/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaManager.java ---------------------------------------------------------------------- diff --git a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaManager.java b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaManager.java index d93e0d6..e21ab4a 100644 --- a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaManager.java +++ b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/quota/JPAPerUserMaxQuotaManager.java @@ -19,6 +19,7 @@ package org.apache.james.mailbox.jpa.quota; +import javax.inject.Inject; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; @@ -38,6 +39,7 @@ public class JPAPerUserMaxQuotaManager implements MaxQuotaManager { private final EntityManager entityManager; + @Inject public JPAPerUserMaxQuotaManager(EntityManagerFactory entityManagerFactory) { entityManager = entityManagerFactory.createEntityManager(); } http://git-wip-us.apache.org/repos/asf/james-project/blob/fcdfc80f/mailbox/jpa/src/main/resources/META-INF/spring/mailbox-jpa.xml ---------------------------------------------------------------------- diff --git a/mailbox/jpa/src/main/resources/META-INF/spring/mailbox-jpa.xml b/mailbox/jpa/src/main/resources/META-INF/spring/mailbox-jpa.xml index 6fc298d..7572873 100644 --- a/mailbox/jpa/src/main/resources/META-INF/spring/mailbox-jpa.xml +++ b/mailbox/jpa/src/main/resources/META-INF/spring/mailbox-jpa.xml @@ -90,4 +90,5 @@ <bean id="jpa-mailbox-id-deserializer" class="org.apache.james.mailbox.jpa.JPAMailboxIdDeserializer"/> + <bean id="jpaMaxQuotaManager" class="org.apache.james.mailbox.jpa.quota.JPAPerUserMaxQuotaManager"/> </beans> http://git-wip-us.apache.org/repos/asf/james-project/blob/fcdfc80f/server/app/src/main/resources/META-INF/persistence.xml ---------------------------------------------------------------------- diff --git a/server/app/src/main/resources/META-INF/persistence.xml b/server/app/src/main/resources/META-INF/persistence.xml index 2ccb6fa..0bf3a18 100644 --- a/server/app/src/main/resources/META-INF/persistence.xml +++ b/server/app/src/main/resources/META-INF/persistence.xml @@ -35,6 +35,10 @@ <class>org.apache.james.domainlist.jpa.model.JPADomain</class> <class>org.apache.james.user.jpa.model.JPAUser</class> <class>org.apache.james.rrt.jpa.model.JPARecipientRewrite</class> + <class>org.apache.james.mailbox.jpa.quota.model.MaxDefaultMessageCount</class> + <class>org.apache.james.mailbox.jpa.quota.model.MaxDefaultStorage</class> + <class>org.apache.james.mailbox.jpa.quota.model.MaxUserMessageCount</class> + <class>org.apache.james.mailbox.jpa.quota.model.MaxUserStorage</class> <properties> <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/> http://git-wip-us.apache.org/repos/asf/james-project/blob/fcdfc80f/server/app/src/main/resources/quota-template.xml ---------------------------------------------------------------------- diff --git a/server/app/src/main/resources/quota-template.xml b/server/app/src/main/resources/quota-template.xml index 0635e46..e2c4340 100644 --- a/server/app/src/main/resources/quota-template.xml +++ b/server/app/src/main/resources/quota-template.xml @@ -36,32 +36,32 @@ <quota> <!-- - Quota implementation is based on several components : - - QuotaRootResolver : In regard of quota management, mailboxes forms abstract groups called QUOTA ROOT. This + Quota implementation is based on several components: + - QuotaRootResolver: In regard of quota management, mailboxes forms abstract groups called QUOTA ROOT. This component finds to which QUOTA ROOT a mailbox belongs - - Current quota manager : Counters for current values : how many messages belongs to this quota root ? Which + - Current quota manager: Counters for current values: how many messages belongs to this quota root ? Which size ? - - Max Quota manager : Sets a maximum value QUOTA ROOT resources can not exceed. - - QuotaManager : assemble Current quota manager and Max quota manager. - - Listening quota updater : Event system based quota update. On each APPED / COPY /EXPUNGE command, current + - Max Quota manager: Sets a maximum value QUOTA ROOT resources can not exceed. + - QuotaManager: assemble Current quota manager and Max quota manager. + - Listening quota updater: Event system based quota update. On each APPED / COPY /EXPUNGE command, current quotas gets updated. --> <quotaRootResolver> <!-- - Possible value : + Possible value: - default --> <provider>default</provider> </quotaRootResolver> <currentQuotaManager> <!-- - Possible value for provider : - - none : when you use fake as a value for quotaManager's provider + Possible value for provider: + - none: when you use fake as a value for quotaManager's provider - inmemory - cassandra - The inmemory implementation : + The inmemory implementation: - Does not work in a distributed context Note that quota need to be (lazy) re-calculated after each starts @@ -75,12 +75,15 @@ <!-- This component is exposed to the CLI for quota administration tasks. - Possible value are : - - fake : will always return UNLIMITED. Throws on modifications. - - fixed : all QUOTA ROOT get the same upper bound for their quotas. - - inmemory : allows you to define QUOTA ROOT specific limits, backed with a fixed policy. It does not + Possible value are: + - fake: will always return UNLIMITED. Throws on modifications. + - fixed: all QUOTA ROOT get the same upper bound for their quotas. + - inmemory: allows you to define QUOTA ROOT specific limits, backed with a fixed policy. It does not work in a distributed context. - - cassandra : Same thing than inmemory but backed on cassandra. Works on a distributed context. Note that using + - cassandra: Same thing than inmemory but backed on cassandra. Works on a distributed context. Note that using + the default* configuration options and the CLI to set default options is dangerous as server startup might override + CLI values. + - jpa: Same thing than inmemory but backed on jpa. Works on a distributed context. Note that using the default* configuration options and the CLI to set default options is dangerous as server startup might override CLI values. --> @@ -110,16 +113,16 @@ <!-- The QuotaManager you use. - Possible values are : - - fake : returns only UNKNOWN/UNLIMITED quotas - - store : returns quotas using a CurrentQuotaManager and a MaxQuotaManager + Possible values are: + - fake: returns only UNKNOWN/UNLIMITED quotas + - store: returns quotas using a CurrentQuotaManager and a MaxQuotaManager --> <provider>fake</provider> </quotaManager> <updates> <!-- This defines the way your quotas gets updated. - Possible values are : + Possible values are: - fake - event --> http://git-wip-us.apache.org/repos/asf/james-project/blob/fcdfc80f/server/container/spring/src/main/java/org/apache/james/container/spring/bean/factorypostprocessor/QuotaBeanFactoryPostProcessor.java ---------------------------------------------------------------------- diff --git a/server/container/spring/src/main/java/org/apache/james/container/spring/bean/factorypostprocessor/QuotaBeanFactoryPostProcessor.java b/server/container/spring/src/main/java/org/apache/james/container/spring/bean/factorypostprocessor/QuotaBeanFactoryPostProcessor.java index 70b08c9..46f8e9a 100644 --- a/server/container/spring/src/main/java/org/apache/james/container/spring/bean/factorypostprocessor/QuotaBeanFactoryPostProcessor.java +++ b/server/container/spring/src/main/java/org/apache/james/container/spring/bean/factorypostprocessor/QuotaBeanFactoryPostProcessor.java @@ -42,6 +42,7 @@ public class QuotaBeanFactoryPostProcessor implements BeanFactoryPostProcessor { private static final String UPDATES = "updates"; private static final String QUOTA_ROOT_RESOLVER = "quotaRootResolver"; private static final String EVENT = "event"; + public static final String JPA = "jpa"; @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { @@ -94,6 +95,8 @@ public class QuotaBeanFactoryPostProcessor implements BeanFactoryPostProcessor { registry.registerAlias("inMemoryMaxQuotaManager", MAX_QUOTA_MANAGER); } else if (maxQuotaManager.equalsIgnoreCase(CASSANDRA)) { registry.registerAlias("cassandraMaxQuotaManager", MAX_QUOTA_MANAGER); + } else if (maxQuotaManager.equalsIgnoreCase(JPA)) { + registry.registerAlias("jpaMaxQuotaManager", MAX_QUOTA_MANAGER); } else { throw new FatalBeanException("Unreadable value for Max Quota Manager : " + maxQuotaManager); } http://git-wip-us.apache.org/repos/asf/james-project/blob/fcdfc80f/server/src/site/xdoc/config-quota.xml ---------------------------------------------------------------------- diff --git a/server/src/site/xdoc/config-quota.xml b/server/src/site/xdoc/config-quota.xml index 1605f7f..676eca5 100644 --- a/server/src/site/xdoc/config-quota.xml +++ b/server/src/site/xdoc/config-quota.xml @@ -51,10 +51,11 @@ <li>Quota Manager : This component retrieves quota associated with a QUOTA ROOT. A store implementation is available and relies on other components. A fake implementation is available in order to add no overhead.</li> <li>Max Quota Manager : This component retrieves maximum values associated with quotas and gives a way to potentially - (depending on the implementation) update these per QUOTA ROOT maximum values. Three implementation are available for now. A NoQuotaManager implementation + (depending on the implementation) update these per QUOTA ROOT maximum values. Four implementations are available for now. A NoQuotaManager implementation is read only and returns UNLIMITED maximum values. FixedMaxQuotaManager returns one and only one value for all user. You can configure these maximum values threw the configuration files. A InMemoryPerUserMaxQuotaManager allows you to configure quota for each QUOTA ROOT. Note that it needs to be done threw - configuration to be persistent. And finally a Cassandra implementation allows to store maximum quota values in Cassandra.</li> + configuration to be persistent. We provide some other implementation: A Cassandra implementation allows to store maximum quota values in Cassandra, + and a JPA implementation.</li> <li>Current Quota Manager : This component can be omitted if you are running a fake QUOTA manager. inmemory implementation is an event updated cache on top of a Quota calculator (that fetches every e-mail metadata of every mailboxes belonging to the QUOTA ROOT: it is expensive). A cassandra implementation is also available.</li> --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org