You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2018/05/10 02:31:08 UTC

[01/15] james-project git commit: JAMES-2392 Stop linking MD5 in download page

Repository: james-project
Updated Branches:
  refs/heads/master 0e437d259 -> 5ee21fec0


JAMES-2392 Stop linking MD5 in download page


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/143b6f8f
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/143b6f8f
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/143b6f8f

Branch: refs/heads/master
Commit: 143b6f8f4be8f5e0f6ff0a16fb33ced239b71a99
Parents: 0e437d2
Author: benwa <bt...@linagora.com>
Authored: Wed May 9 11:14:22 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu May 10 09:12:24 2018 +0700

----------------------------------------------------------------------
 src/site/xdoc/download.xml | 40 ++++++----------------------------------
 1 file changed, 6 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/143b6f8f/src/site/xdoc/download.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/download.xml b/src/site/xdoc/download.xml
index 86350e5..c565d80 100644
--- a/src/site/xdoc/download.xml
+++ b/src/site/xdoc/download.xml
@@ -108,7 +108,7 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
       <subsection name="Verify the integrity of the files">
       
       <p>It is essential that you verify the integrity of the downloaded
-      files using the PGP or MD5 signatures.</p>
+      files using the PGP or SHA-1 signatures.</p>
       
       <p>The PGP signatures can be verified using PGP or GPG.  First
       download the <a href="https://www.apache.org/dist/james/KEYS">KEYS</a>
@@ -160,15 +160,14 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
       <ul>
         <li>Source code (ZIP Format):
           <a href="https://www.apache.org/dist/james/server/james-server-sources-3.0.1.zip">apache-james-3.0.1-app.zip</a>
-          [<a href="https://www.apache.org/dist/james/server/james-server-sources-3.0.1.zip.md5">MD5</a>]
           [<a href="https://www.apache.org/dist/james/server/james-server-sources-3.0.1.zip.sha1">SHA-1</a>]
           [<a href="https://www.apache.org/dist/james/server/james-server-sources-3.0.1.zip.asc">PGP</a>]</li>
 
-        <li>Binary (ZIP Format): <a
-                href="https://www.apache.org/dist/james/server/james-server-app-3.0.1-app.zip">apache-james-3.0.1-app.zip</a> [<a
-                href="https://www.apache.org/dist/james/server/james-server-app-3.0.1-app.zip.md5">MD5</a>] [<a
-                href="https://www.apache.org/dist/james/server/james-server-app-3.0.1-app.zip.sha1">SHA-1</a>] [<a
-                href="https://www.apache.org/dist/james/server/james-server-app-3.0.1-app.zip.sig">PGP</a>]</li>
+        <li>Binary (ZIP Format):
+          <a href="https://www.apache.org/dist/james/server/james-server-app-3.0.1-app.zip">apache-james-3.0.1-app.zip</a>
+          [<a href="https://www.apache.org/dist/james/server/james-server-app-3.0.1-app.zip.sha1">SHA-1</a>]
+          [<a href="https://www.apache.org/dist/james/server/james-server-app-3.0.1-app.zip.sig">PGP</a>]
+        </li>
 
       </ul>
 
@@ -201,25 +200,21 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
       <ul>
       
         <li>Binary (Unix TAR): <a href="[preferred]/james/server/james-binary-2.3.2.1.tar.gz">james-binary-2.3.2.1.tar.gz</a>
-          [<a href="https://www.apache.org/dist/james/server/james-binary-2.3.2.1.tar.gz.md5">MD5</a>]
           [<a href="https://www.apache.org/dist/james/server/james-binary-2.3.2.1.tar.gz.sha1">SHA-1</a>]
           [<a href="https://www.apache.org/dist/james/server/james-binary-2.3.2.1.tar.gz.asc">PGP</a>]
         </li>
       
         <li>Binary (ZIP Format): <a href="[preferred]/james/server/james-binary-2.3.2.1.zip">james-binary-2.3.2.1.zip</a>
-          [<a href="https://www.apache.org/dist/james/server/james-binary-2.3.2.1.zip.md5">MD5</a>]
           [<a href="https://www.apache.org/dist/james/server/james-binary-2.3.2.1.zip.sha1">SHA-1</a>]
           [<a href="https://www.apache.org/dist/james/server/james-binary-2.3.2.1.zip.asc">PGP</a>]
         </li>
       
         <li>Source (Unix TAR): <a href="[preferred]/james/server/james-2.3.2.1-src.tar.gz">james-2.3.2.1-src.tar.gz</a>
-          [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.tar.gz.md5">MD5</a>]
           [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.tar.gz.sha1">SHA-1</a>]
           [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.tar.gz.asc">PGP</a>]
         </li>
       
           <li>Source (ZIP Format): <a href="[preferred]/james/server/james-2.3.2.1-src.zip">james-2.3.2.1-src.zip</a>
-            [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.zip.md5">MD5</a>]
             [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.zip.sha1">SHA-1</a>]
             [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.zip.asc">PGP</a>]
           </li>
@@ -254,7 +249,6 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
 
     <p>Direct download link:
       <a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-core-0.8.2.jar">(Jar)</a>
-      [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-core-0.8.2.jar.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-core-0.8.2.jar.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-core-0.8.2.jar.asc">PGP</a>]
       </p>
@@ -273,7 +267,6 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
 
     <p>Direct download link:
       <a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-dom-0.8.2.jar">(Jar)</a>
-      [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-dom-0.8.2.jar.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-dom-0.8.2.jar.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-dom-0.8.2.jar.asc">PGP</a>]
     </p>
@@ -292,14 +285,12 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
 
     <p>Direct download link:
       <a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-0.8.2-bin.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-0.8.2-bin.zip.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-0.8.2-bin.zip.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-0.8.2-bin.zip.asc">PGP</a>]
     </p>
 
     <p>Sources:
       <a href="https://www.apache.org/dist/james/mime4j/0.8.2/james-mime4j-sources-0.8.2.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/james-mime4j-sources-0.8.2.zip.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/james-mime4j-sources-0.8.2.zip.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/james-mime4j-sources-0.8.2.zip.asc">PGP</a>]
     </p>
@@ -324,14 +315,12 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
 
     <p>Direct download link:
       <a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-1.0.1-bin.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-1.0.1-bin.zip.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-1.0.1-bin.zip.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-1.0.1-bin.zip.asc">PGP</a>]
     </p>
 
     <p>Sources:
       <a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-sources-1.0.1.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-sources-1.0.1.zip.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-sources-1.0.1.zip.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-sources-1.0.1.zip.asc">PGP</a>]
     </p>
@@ -356,14 +345,12 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
 
     <p>Direct download link:
       <a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-0.2-bin.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-0.2-bin.zip.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-0.2-bin.zip.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-0.2-bin.zip.asc">PGP</a>]
     </p>
 
     <p>Sources:
       <a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-project-0.2-source-release.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-project-0.2-source-release.zip.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-project-0.2-source-release.zip.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-project-0.2-source-release.zip.asc">PGP</a>]
     </p>
@@ -388,14 +375,12 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
 
     <p>Direct download link:
       <a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-core-0.7.jar">(Jar)</a>
-      [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-core-0.7.jar.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-core-0.7.jar.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-core-0.7.jar.asc">PGP</a>]
     </p>
 
     <p>Sources:
       <a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-sources-0.7.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-sources-0.7.zip.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-sources-0.7.zip.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-sources-0.7.zip.asc">PGP</a>]
     </p>
@@ -414,7 +399,6 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
 
     <p>Direct download link:
       <a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-0.7-all.tar.gz">(Tar Gz)</a>
-      [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-0.7-all.tar.gz.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-0.7-all.tar.gz.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-0.7-all.tar.gz.asc">PGP</a>]
     </p>
@@ -438,14 +422,12 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
 
     <p>Direct download link:
       <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-api-3.0.1.jar">(Jar)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-api-3.0.1.jar.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-api-3.0.1.jar.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-api-3.0.1.jar.asc">PGP</a>]
     </p>
 
     <p>Sources:
       <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-api-sources-3.0.1.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-api-sources-3.0.1.zip.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-api-sources-3.0.1.zip.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-api-sources-3.0.1.zip.asc">PGP</a>]
     </p>
@@ -468,14 +450,12 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
 
     <p>Direct download link:
       <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-base-3.0.1.jar">(Jar)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-base-3.0.1.jar.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-base-3.0.1.jar.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-base-3.0.1.jar.asc">PGP</a>]
     </p>
 
     <p>Sources:
       <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-base-sources-3.0.1.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-base-sources-3.0.1.zip.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-base-sources-3.0.1.zip.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-base-sources-3.0.1.zip.asc">PGP</a>]
     </p>
@@ -498,14 +478,12 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
 
     <p>Direct download link:
       <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-standard-3.0.1.jar">(Jar)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-standard-3.0.1.jar.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-standard-3.0.1.jar.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-standard-3.0.1.jar.asc">PGP</a>]
     </p>
 
     <p>Sources:
       <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-standard-sources-3.0.1.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-standard-sources-3.0.1.zip.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-standard-sources-3.0.1.zip.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-standard-sources-3.0.1.zip.asc">PGP</a>]
     </p>
@@ -544,14 +522,12 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
 
     <p>Direct download link:
       <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-crypto-3.0.1.jar">(Jar)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-crypto-3.0.1.jar.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-crypto-3.0.1.jar.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-crypto-3.0.1.jar.asc">PGP</a>]
     </p>
 
     <p>Sources:
       <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-crypto-sources-3.0.1.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-crypto-sources-3.0.1.zip.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-crypto-sources-3.0.1.zip.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-crypto-sources-3.0.1.zip.asc">PGP</a>]
     </p>
@@ -582,13 +558,11 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     
     <li>Source (Unix TAR):
       <a href="https://www.apache.org/dist/james/mpt/0.1/apache-james-mpt-0.1-src.tar.gz">apache-james-mpt-0.1-src.tar.gz</a>
-      [<a href="https://www.apache.org/dist/james/mpt/0.1/apache-james-mpt-0.1-src.tar.gz.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/mpt/0.1/apache-james-mpt-0.1-src.tar.gz.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mpt/0.1/apache-james-mpt-0.1-src.tar.gz.asc">PGP</a>]
     </li>
     
     <li>Source (ZIP Format): <a href="https://www.apache.org/dist/james/mpt/0.1/apache-james-mpt-0.1-src.zip">apache-james-mpt-0.1-src.zip</a>
-      [<a href="https://www.apache.org/dist/james/mpt/0.1/apache-james-mpt-0.1-src.zip.md5">MD5</a>]
       [<a href="https://www.apache.org/dist/james/mpt/0.1/apache-james-mpt-0.1-src.zip.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mpt/0.1/apache-james-mpt-0.1-src.zip.asc">PGP</a>]
     </li>
@@ -605,13 +579,11 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     <ul>
     
     <li>Binary (Java WAR): <a href="https://repo1.maven.org/maven2/org/apache/james/hupa/hupa/0.0.2/hupa-0.0.2.war">hupa-0.0.2.war</a>
-      [<a href="https://repo1.maven.org/maven2/org/apache/james/hupa/hupa/0.0.2/hupa-0.0.2.war.asc.md5">MD5</a>]
       [<a href="https://repo1.maven.org/maven2/org/apache/james/hupa/hupa/0.0.2/hupa-0.0.2.war.asc">PGP</a>]
     </li>
     
     <li>Source (ZIP Format): <a
     href="https://repo1.maven.org/maven2/org/apache/james/hupa/hupa-parent/0.0.2/hupa-parent-0.0.2-source-release.zip">hupa-parent-0.0.2-source-release.zip</a>
-      [<a href="https://repo1.maven.org/maven2/org/apache/james/hupa/hupa-parent/0.0.2/hupa-parent-0.0.2.pom.asc.md5">MD5</a>]
       [<a href="https://repo1.maven.org/maven2/org/apache/james/hupa/hupa-parent/0.0.2/hupa-parent-0.0.2-source-release.zip.asc">PGP</a>]
     </li>
     


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


[15/15] james-project git commit: MAILBOX-333 Add a test for subject rendering

Posted by bt...@apache.org.
MAILBOX-333 Add a test for subject rendering


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/5ee21fec
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/5ee21fec
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/5ee21fec

Branch: refs/heads/master
Commit: 5ee21fec00d5e9f2f2372e3b1f04330671137e8a
Parents: 08e7d4b
Author: benwa <bt...@linagora.com>
Authored: Wed May 9 10:33:25 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu May 10 09:24:28 2018 +0700

----------------------------------------------------------------------
 .../subscribers/QuotaThresholdNoticeTest.java        | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/5ee21fec/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java
index 20ccaaa..e47adc2 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java
@@ -242,4 +242,19 @@ class QuotaThresholdNoticeTest {
                 "You need to be aware that actions leading to exceeded quotas will be denied. This will result in a degraded service.\n" +
                 "To mitigate this issue you might reach your administrator in order to increase your configured quota. You might also delete some non important emails.");
     }
+
+    @Test
+    void generateSubjectShouldRenderMustacheTemplate() throws Exception {
+        QuotaThresholdChange countThresholdChange = new QuotaThresholdChange(_80, NOW);
+
+        assertThat(QuotaThresholdNotice.builder()
+            .withConfiguration(DEFAULT_CONFIGURATION)
+            .sizeQuota(Sizes._82_PERCENT)
+            .countQuota(Counts._UNLIMITED)
+            .countThreshold(HistoryEvolution.higherThresholdReached(countThresholdChange, NotAlreadyReachedDuringGracePeriod))
+            .build()
+            .get()
+            .generateSubject(fileSystem))
+            .isEqualTo("Warning: Your email usage just exceeded a configured threshold");
+    }
 }
\ No newline at end of file


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


[11/15] james-project git commit: MAILBOX-332 Enforce event deserialization stability

Posted by bt...@apache.org.
MAILBOX-332 Enforce event deserialization stability

Store JSON in files to prevent them to be changed by IDE refactorings


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/409792c2
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/409792c2
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/409792c2

Branch: refs/heads/master
Commit: 409792c2499fea1a792f4e23eb421e4e0e69cbb1
Parents: 0a393f6
Author: benwa <bt...@linagora.com>
Authored: Wed May 9 16:48:15 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu May 10 09:15:41 2018 +0700

----------------------------------------------------------------------
 .../mailbox/quota/cassandra/dto/DTOTest.java    | 111 ++++++++++++++-----
 .../src/test/resources/json/event.json          |  19 ++++
 .../src/test/resources/json/event2.json         |  20 ++++
 .../src/test/resources/json/event3.json         |  23 ++++
 .../src/test/resources/json/event4.json         |  23 ++++
 .../org/apache/james/util/ClassLoaderUtils.java |  16 ++-
 6 files changed, 180 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/409792c2/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
index a42725a..2f48a55 100644
--- a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
@@ -20,8 +20,12 @@
 package org.apache.james.mailbox.quota.cassandra.dto;
 
 import static net.javacrumbs.jsonunit.fluent.JsonFluentAssert.assertThatJson;
+import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture._75;
+import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture._80;
 import static org.assertj.core.api.Assertions.assertThat;
 
+import java.time.Instant;
+
 import org.apache.james.core.User;
 import org.apache.james.eventsourcing.EventId;
 import org.apache.james.eventsourcing.cassandra.JsonEventSerializer;
@@ -31,6 +35,8 @@ import org.apache.james.mailbox.quota.QuotaSize;
 import org.apache.james.mailbox.quota.mailing.aggregates.UserQuotaThresholds;
 import org.apache.james.mailbox.quota.mailing.events.QuotaThresholdChangedEvent;
 import org.apache.james.mailbox.quota.model.HistoryEvolution;
+import org.apache.james.mailbox.quota.model.QuotaThresholdChange;
+import org.apache.james.util.ClassLoaderUtils;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -42,6 +48,7 @@ class DTOTest {
 
     public static final Quota<QuotaSize> SIZE_QUOTA = Quota.<QuotaSize>builder().used(QuotaSize.size(23)).computedLimit(QuotaSize.size(33)).build();
     public static final Quota<QuotaCount> COUNT_QUOTA = Quota.<QuotaCount>builder().used(QuotaCount.count(12)).computedLimit(QuotaCount.count(45)).build();
+    public static final Instant INSTANT = Instant.ofEpochMilli(45554);
     public static final QuotaThresholdChangedEvent EVENT = new QuotaThresholdChangedEvent(
         EventId.first(),
         HistoryEvolution.noChanges(),
@@ -49,32 +56,34 @@ class DTOTest {
         SIZE_QUOTA,
         COUNT_QUOTA,
         UserQuotaThresholds.Id.from(User.fromUsername("foo@bar.com")));
+    public static final QuotaThresholdChangedEvent EVENT_2 = new QuotaThresholdChangedEvent(
+        EventId.first(),
+        HistoryEvolution.lowerThresholdReached(new QuotaThresholdChange(_75, INSTANT)),
+        HistoryEvolution.noChanges(),
+        SIZE_QUOTA,
+        Quota.<QuotaCount>builder().used(QuotaCount.count(12)).computedLimit(QuotaCount.unlimited()).build(),
+        UserQuotaThresholds.Id.from(User.fromUsername("foo@bar.com")));
+    public static final QuotaThresholdChangedEvent EVENT_3 = new QuotaThresholdChangedEvent(
+        EventId.first(),
+        HistoryEvolution.lowerThresholdReached(new QuotaThresholdChange(_75, INSTANT)),
+        HistoryEvolution.higherThresholdReached(new QuotaThresholdChange(_80, INSTANT),
+            HistoryEvolution.HighestThresholdRecentness.NotAlreadyReachedDuringGracePeriod),
+        SIZE_QUOTA,
+        Quota.<QuotaCount>builder().used(QuotaCount.count(12)).computedLimit(QuotaCount.unlimited()).build(),
+        UserQuotaThresholds.Id.from(User.fromUsername("foo@bar.com")));
+    public static final QuotaThresholdChangedEvent EVENT_4 = new QuotaThresholdChangedEvent(
+        EventId.first(),
+        HistoryEvolution.lowerThresholdReached(new QuotaThresholdChange(_75, INSTANT)),
+        HistoryEvolution.higherThresholdReached(new QuotaThresholdChange(_80, INSTANT),
+            HistoryEvolution.HighestThresholdRecentness.AlreadyReachedDuringGracePeriod),
+        SIZE_QUOTA,
+        Quota.<QuotaCount>builder().used(QuotaCount.count(12)).computedLimit(QuotaCount.unlimited()).build(),
+        UserQuotaThresholds.Id.from(User.fromUsername("foo@bar.com")));
 
-    public static final String EVENT_JSON = "{" +
-        " \"type\": \"quota-threshold-change\"," +
-        " \"eventId\": 0," +
-        " \"user\": \"foo@bar.com\"," +
-        " \"sizeQuota\": {" +
-        "   \"used\": 23," +
-        "   \"limit\": 33" +
-        " }," +
-        " \"countQuota\": {" +
-        "   \"used\": 12," +
-        "   \"limit\": 45" +
-        " }," +
-        " \"sizeEvolution\": {" +
-        "   \"change\": \"NoChange\"," +
-        "   \"threshold\": null," +
-        "   \"instant\": null," +
-        "   \"recentness\": null" +
-        " }," +
-        " \"countEvolution\": {" +
-        "   \"change\": \"NoChange\"," +
-        "   \"threshold\": null," +
-        "   \"instant\": null," +
-        "   \"recentness\": null" +
-        " }" +
-        "}";
+    public static final String EVENT_JSON = ClassLoaderUtils.getSystemResourceAsString("json/event.json");
+    public static final String EVENT_JSON_2 = ClassLoaderUtils.getSystemResourceAsString("json/event2.json");
+    public static final String EVENT_JSON_3 = ClassLoaderUtils.getSystemResourceAsString("json/event3.json");
+    public static final String EVENT_JSON_4 = ClassLoaderUtils.getSystemResourceAsString("json/event4.json");
 
     public static final String COUNT_QUOTA_JSON = "{" +
         "   \"used\": 12," +
@@ -129,9 +138,6 @@ class DTOTest {
 
     @Test
     void shouldDeserializeQuotaThresholdChangedEventDTO() throws Exception {
-        ObjectMapper objectMapper = new ObjectMapper();
-        objectMapper.registerModule(new Jdk8Module());
-
         assertThat(objectMapper.readValue(EVENT_JSON, QuotaThresholdChangedEventDTO.class)
             .toEvent())
             .isEqualTo(EVENT);
@@ -144,4 +150,53 @@ class DTOTest {
             .isEqualTo(EVENT_JSON);
     }
 
+    @Test
+    void shouldDeserializeQuotaThresholdChangedEvent() throws Exception {
+        assertThatJson(new JsonEventSerializer(new QuotaThresholdChangedEventDTOModule())
+            .deserialize(EVENT_JSON))
+            .isEqualTo(EVENT);
+    }
+
+    @Test
+    void shouldSerializeEvent2() throws Exception {
+        assertThatJson(new JsonEventSerializer(new QuotaThresholdChangedEventDTOModule())
+            .serialize(EVENT_2))
+            .isEqualTo(EVENT_JSON_2);
+    }
+
+    @Test
+    void shouldDeserializeEvent2() throws Exception {
+        assertThatJson(new JsonEventSerializer(new QuotaThresholdChangedEventDTOModule())
+            .deserialize(EVENT_JSON_2))
+            .isEqualTo(EVENT_2);
+    }
+
+    @Test
+    void shouldSerializeEvent3() throws Exception {
+        assertThatJson(new JsonEventSerializer(new QuotaThresholdChangedEventDTOModule())
+            .serialize(EVENT_3))
+            .isEqualTo(EVENT_JSON_3);
+    }
+
+    @Test
+    void shouldDeserializeEvent3() throws Exception {
+        assertThatJson(new JsonEventSerializer(new QuotaThresholdChangedEventDTOModule())
+            .deserialize(EVENT_JSON_3))
+            .isEqualTo(EVENT_3);
+    }
+
+    @Test
+    void shouldSerializeEvent4() throws Exception {
+        assertThatJson(new JsonEventSerializer(new QuotaThresholdChangedEventDTOModule())
+            .serialize(EVENT_4))
+            .isEqualTo(EVENT_JSON_4);
+    }
+
+    @Test
+    void shouldDeserializeEvent4() throws Exception {
+        assertThatJson(new JsonEventSerializer(new QuotaThresholdChangedEventDTOModule())
+            .deserialize(EVENT_JSON_4))
+            .isEqualTo(EVENT_4);
+    }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/409792c2/mailbox/plugin/quota-mailing-cassandra/src/test/resources/json/event.json
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/resources/json/event.json b/mailbox/plugin/quota-mailing-cassandra/src/test/resources/json/event.json
new file mode 100644
index 0000000..4449047
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/resources/json/event.json
@@ -0,0 +1,19 @@
+{
+ "type": "quota-threshold-change",
+ "eventId": 0,
+ "user": "foo@bar.com",
+ "sizeQuota": {
+   "used": 23,
+   "limit": 33
+ },
+ "countQuota": {
+   "used": 12,
+   "limit": 45
+ },
+ "sizeEvolution": {
+   "change": "NoChange"
+ },
+ "countEvolution": {
+   "change": "NoChange"
+ }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/409792c2/mailbox/plugin/quota-mailing-cassandra/src/test/resources/json/event2.json
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/resources/json/event2.json b/mailbox/plugin/quota-mailing-cassandra/src/test/resources/json/event2.json
new file mode 100644
index 0000000..b20cfab
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/resources/json/event2.json
@@ -0,0 +1,20 @@
+{
+  "type":"quota-threshold-change",
+  "eventId":0,
+  "user":"foo@bar.com",
+  "sizeQuota":{
+    "used":23,
+    "limit":33
+  },
+  "countQuota":{
+    "used":12
+  },
+  "sizeEvolution":{
+    "threshold":0.75,
+    "instant":45554,
+    "change":"LowerThresholdReached"
+  },
+  "countEvolution":{
+    "change":"NoChange"
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/409792c2/mailbox/plugin/quota-mailing-cassandra/src/test/resources/json/event3.json
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/resources/json/event3.json b/mailbox/plugin/quota-mailing-cassandra/src/test/resources/json/event3.json
new file mode 100644
index 0000000..4bda126
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/resources/json/event3.json
@@ -0,0 +1,23 @@
+{
+  "type":"quota-threshold-change",
+  "eventId":0,
+  "user":"foo@bar.com",
+  "sizeQuota":{
+    "used":23,
+    "limit":33
+  },
+  "countQuota":{
+    "used":12
+  },
+  "sizeEvolution":{
+    "threshold":0.75,
+    "instant":45554,
+    "change":"LowerThresholdReached"
+  },
+  "countEvolution":{
+    "recentness":"NotAlreadyReachedDuringGracePeriod",
+    "threshold":0.8,
+    "instant":45554,
+    "change":"HigherThresholdReached"
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/409792c2/mailbox/plugin/quota-mailing-cassandra/src/test/resources/json/event4.json
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/resources/json/event4.json b/mailbox/plugin/quota-mailing-cassandra/src/test/resources/json/event4.json
new file mode 100644
index 0000000..0852dc5
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/resources/json/event4.json
@@ -0,0 +1,23 @@
+{
+  "type":"quota-threshold-change",
+  "eventId":0,
+  "user":"foo@bar.com",
+  "sizeQuota":{
+    "used":23,
+    "limit":33
+  },
+  "countQuota":{
+    "used":12
+  },
+  "sizeEvolution":{
+    "threshold":0.75,
+    "instant":45554,
+    "change":"LowerThresholdReached"
+  },
+  "countEvolution":{
+    "recentness":"AlreadyReachedDuringGracePeriod",
+    "threshold":0.8,
+    "instant":45554,
+    "change":"HigherThresholdReached"
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/409792c2/server/container/util-java8/src/main/java/org/apache/james/util/ClassLoaderUtils.java
----------------------------------------------------------------------
diff --git a/server/container/util-java8/src/main/java/org/apache/james/util/ClassLoaderUtils.java b/server/container/util-java8/src/main/java/org/apache/james/util/ClassLoaderUtils.java
index d7df10a..89574b6 100644
--- a/server/container/util-java8/src/main/java/org/apache/james/util/ClassLoaderUtils.java
+++ b/server/container/util-java8/src/main/java/org/apache/james/util/ClassLoaderUtils.java
@@ -25,11 +25,19 @@ import java.nio.charset.StandardCharsets;
 import org.apache.commons.io.IOUtils;
 
 public class ClassLoaderUtils {
-    public static String getSystemResourceAsString(String filename) throws IOException {
-        return IOUtils.toString(ClassLoader.getSystemResourceAsStream(filename), StandardCharsets.US_ASCII);
+    public static String getSystemResourceAsString(String filename) {
+        try {
+            return IOUtils.toString(ClassLoader.getSystemResourceAsStream(filename), StandardCharsets.US_ASCII);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
     }
 
-    public static byte[] getSystemResourceAsByteArray(String filename) throws IOException {
-        return IOUtils.toByteArray(ClassLoader.getSystemResourceAsStream(filename));
+    public static byte[] getSystemResourceAsByteArray(String filename) {
+        try {
+            return IOUtils.toByteArray(ClassLoader.getSystemResourceAsStream(filename));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
     }
 }


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


[12/15] james-project git commit: MAILBOX-333 Demonstrate a bug upon unlimited quotas exceeding a threshold

Posted by bt...@apache.org.
MAILBOX-333 Demonstrate a bug upon unlimited quotas exceeding a threshold


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/d11d5d51
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/d11d5d51
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/d11d5d51

Branch: refs/heads/master
Commit: d11d5d517923258ddc2926955af7fa406701e350
Parents: ae9a8e6
Author: benwa <bt...@linagora.com>
Authored: Wed May 9 10:13:36 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu May 10 09:24:27 2018 +0700

----------------------------------------------------------------------
 .../subscribers/QuotaThresholdNoticeTest.java   | 22 ++++++++++++++++++++
 .../quota/model/QuotaThresholdFixture.java      |  5 +++++
 2 files changed, 27 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/d11d5d51/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java
index 03c2ea2..b656cf0 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java
@@ -34,6 +34,7 @@ import org.apache.james.mailbox.quota.model.HistoryEvolution;
 import org.apache.james.mailbox.quota.model.QuotaThresholdChange;
 import org.apache.james.mailbox.quota.model.QuotaThresholdFixture.Quotas.Counts;
 import org.apache.james.mailbox.quota.model.QuotaThresholdFixture.Quotas.Sizes;
+import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
@@ -199,4 +200,25 @@ class QuotaThresholdNoticeTest {
                 "You need to be aware that actions leading to exceeded quotas will be denied. This will result in a degraded service.\n" +
                 "To mitigate this issue you might reach your administrator in order to increase your configured quota. You might also delete some non important emails.");
     }
+
+    @Disabled
+    @Test
+    void generateReportShouldNotFailWhenUnlimitedQuotaExceedsAThreshold() {
+        QuotaThresholdChange countThresholdChange = new QuotaThresholdChange(_80, NOW);
+
+        assertThat(QuotaThresholdNotice.builder()
+            .sizeQuota(Sizes._82_PERCENT)
+            .countQuota(Counts._UNLIMITED)
+            .countThreshold(HistoryEvolution.higherThresholdReached(countThresholdChange, NotAlreadyReachedDuringGracePeriod))
+            .build()
+            .get()
+            .generateReport())
+            .isEqualTo("You receive this email because you recently exceeded a threshold related to the quotas of your email account.\n" +
+                "\n" +
+                "You currently occupy more than 80 % of the total message count allocated to you.\n" +
+                "You currently have 92 messages on a total of 100 allowed for you.\n" +
+                "\n" +
+                "You need to be aware that actions leading to exceeded quotas will be denied. This will result in a degraded service.\n" +
+                "To mitigate this issue you might reach your administrator in order to increase your configured quota. You might also delete some non important emails.");
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/d11d5d51/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdFixture.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdFixture.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdFixture.java
index 7445fb7..fc32afa 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdFixture.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdFixture.java
@@ -77,6 +77,11 @@ public interface QuotaThresholdFixture {
                 .used(QuotaCount.count(92))
                 .computedLimit(QuotaCount.count(100))
                 .build();
+
+            Quota<QuotaCount> _UNLIMITED = Quota.<QuotaCount>builder()
+                .used(QuotaCount.count(92))
+                .computedLimit(QuotaCount.unlimited())
+                .build();
         }
         interface Sizes {
             Quota<QuotaSize> _30_PERCENT = Quota.<QuotaSize>builder()


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


[05/15] james-project git commit: MAILBOX-332 upgrade cassandra driver

Posted by bt...@apache.org.
MAILBOX-332 upgrade cassandra driver


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/a686c2ba
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/a686c2ba
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/a686c2ba

Branch: refs/heads/master
Commit: a686c2baa9abea33a53ad98db46dec8ae11f75f6
Parents: 17ff45f
Author: Matthieu Baechler <ma...@apache.org>
Authored: Wed May 9 15:10:41 2018 +0200
Committer: benwa <bt...@linagora.com>
Committed: Thu May 10 09:15:22 2018 +0700

----------------------------------------------------------------------
 backends-common/cassandra/pom.xml | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/a686c2ba/backends-common/cassandra/pom.xml
----------------------------------------------------------------------
diff --git a/backends-common/cassandra/pom.xml b/backends-common/cassandra/pom.xml
index 748389b..6d58875 100644
--- a/backends-common/cassandra/pom.xml
+++ b/backends-common/cassandra/pom.xml
@@ -30,6 +30,10 @@
     <artifactId>apache-james-backends-cassandra</artifactId>
     <name>Apache James Cassandra backend</name>
 
+    <properties>
+        <cassandra.driver.version>3.5.0</cassandra.driver.version>
+    </properties>
+
     <dependencies>
         <dependency>
             <groupId>${project.groupId}</groupId>
@@ -56,7 +60,7 @@
         <dependency>
             <groupId>com.datastax.cassandra</groupId>
             <artifactId>cassandra-driver-core</artifactId>
-            <version>3.2.0</version>
+            <version>${cassandra.driver.version}</version>
             <classifier>shaded</classifier>
             <!-- Because the shaded JAR uses the original POM, you still need to
                 exclude this dependency explicitly: -->


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


[03/15] james-project git commit: JAMES-2392 The source download should be the primary link

Posted by bt...@apache.org.
JAMES-2392 The source download should be the primary link


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/96bdad6d
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/96bdad6d
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/96bdad6d

Branch: refs/heads/master
Commit: 96bdad6d6a5a8fc093321620e43770ce23cd9527
Parents: 143b6f8
Author: benwa <bt...@linagora.com>
Authored: Wed May 9 11:20:58 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu May 10 09:12:25 2018 +0700

----------------------------------------------------------------------
 src/site/xdoc/download.xml | 139 +++++++++++++++++++++-------------------
 1 file changed, 73 insertions(+), 66 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/96bdad6d/src/site/xdoc/download.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/download.xml b/src/site/xdoc/download.xml
index c565d80..e5c4e9c 100644
--- a/src/site/xdoc/download.xml
+++ b/src/site/xdoc/download.xml
@@ -198,6 +198,16 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
       </div>
               
       <ul>
+
+        <li>Source (Unix TAR): <a href="[preferred]/james/server/james-2.3.2.1-src.tar.gz">james-2.3.2.1-src.tar.gz</a>
+          [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.tar.gz.sha1">SHA-1</a>]
+          [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.tar.gz.asc">PGP</a>]
+        </li>
+
+        <li>Source (ZIP Format): <a href="[preferred]/james/server/james-2.3.2.1-src.zip">james-2.3.2.1-src.zip</a>
+          [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.zip.sha1">SHA-1</a>]
+          [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.zip.asc">PGP</a>]
+        </li>
       
         <li>Binary (Unix TAR): <a href="[preferred]/james/server/james-binary-2.3.2.1.tar.gz">james-binary-2.3.2.1.tar.gz</a>
           [<a href="https://www.apache.org/dist/james/server/james-binary-2.3.2.1.tar.gz.sha1">SHA-1</a>]
@@ -209,16 +219,6 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
           [<a href="https://www.apache.org/dist/james/server/james-binary-2.3.2.1.zip.asc">PGP</a>]
         </li>
       
-        <li>Source (Unix TAR): <a href="[preferred]/james/server/james-2.3.2.1-src.tar.gz">james-2.3.2.1-src.tar.gz</a>
-          [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.tar.gz.sha1">SHA-1</a>]
-          [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.tar.gz.asc">PGP</a>]
-        </li>
-      
-          <li>Source (ZIP Format): <a href="[preferred]/james/server/james-2.3.2.1-src.zip">james-2.3.2.1-src.zip</a>
-            [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.zip.sha1">SHA-1</a>]
-            [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.zip.asc">PGP</a>]
-          </li>
-      
       </ul>
     
     <subsection name="Earlier Releases">
@@ -235,6 +235,12 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
   
     <p>Apache Mime4J 0.8.2 is the latest stable version.</p>
 
+    <p>Sources:
+      <a href="https://www.apache.org/dist/james/mime4j/0.8.2/james-mime4j-sources-0.8.2.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/james-mime4j-sources-0.8.2.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/james-mime4j-sources-0.8.2.zip.asc">PGP</a>]
+    </p>
+
     <p>You can directly use the core library with maven:</p>
 
     <pre>
@@ -288,12 +294,6 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
       [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-0.8.2-bin.zip.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-0.8.2-bin.zip.asc">PGP</a>]
     </p>
-
-    <p>Sources:
-      <a href="https://www.apache.org/dist/james/mime4j/0.8.2/james-mime4j-sources-0.8.2.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/james-mime4j-sources-0.8.2.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/james-mime4j-sources-0.8.2.zip.asc">PGP</a>]
-    </p>
   
   </section>
 
@@ -301,6 +301,12 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
   
     <p>Apache James jSPF 1.0.1 is the latest jSPF stable version.</p>
 
+    <p>Sources:
+      <a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-sources-1.0.1.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-sources-1.0.1.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-sources-1.0.1.zip.asc">PGP</a>]
+    </p>
+
     <p>You can directly use it with maven:</p>
 
     <pre>
@@ -318,12 +324,6 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
       [<a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-1.0.1-bin.zip.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-1.0.1-bin.zip.asc">PGP</a>]
     </p>
-
-    <p>Sources:
-      <a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-sources-1.0.1.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-sources-1.0.1.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-sources-1.0.1.zip.asc">PGP</a>]
-    </p>
   
   </section>
   
@@ -331,6 +331,12 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
   
     <p>Apache James jDKIM 0.2 is the latest jDKIM stable version.</p>
 
+    <p>Sources:
+      <a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-project-0.2-source-release.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-project-0.2-source-release.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-project-0.2-source-release.zip.asc">PGP</a>]
+    </p>
+
     <p>You can directly use it with maven:</p>
 
     <pre>
@@ -348,12 +354,6 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
       [<a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-0.2-bin.zip.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-0.2-bin.zip.asc">PGP</a>]
     </p>
-
-    <p>Sources:
-      <a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-project-0.2-source-release.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-project-0.2-source-release.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-project-0.2-source-release.zip.asc">PGP</a>]
-    </p>
   
   </section>
   
@@ -361,6 +361,12 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
   
     <p>Apache JSieve 0.7 is the latest stable version.</p>
 
+    <p>Sources:
+      <a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-sources-0.7.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-sources-0.7.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-sources-0.7.zip.asc">PGP</a>]
+    </p>
+
     <p>You can directly use it with maven:</p>
 
     <pre>
@@ -379,12 +385,6 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
       [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-core-0.7.jar.asc">PGP</a>]
     </p>
 
-    <p>Sources:
-      <a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-sources-0.7.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-sources-0.7.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-sources-0.7.zip.asc">PGP</a>]
-    </p>
-
     <p>An aggregator project is also available:</p>
 
     <pre>
@@ -408,7 +408,16 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
 
   <section name="Apache Mailet">
   
-    <p>Apache Mailet 3.0.1 is the latest stable version. You can use the mailet API using this maven dependency:</p>
+    <p>Apache Mailet 3.0.1 is the latest stable version. </p>
+
+
+    <p>Sources:
+      <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-api-sources-3.0.1.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-api-sources-3.0.1.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-api-sources-3.0.1.zip.asc">PGP</a>]
+    </p>
+
+    <p>You can use the mailet API using this maven dependency:</p>
 
     <pre>
       <code>
@@ -425,18 +434,20 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-api-3.0.1.jar.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-api-3.0.1.jar.asc">PGP</a>]
     </p>
-
-    <p>Sources:
-      <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-api-sources-3.0.1.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-api-sources-3.0.1.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-api-sources-3.0.1.zip.asc">PGP</a>]
-    </p>
     
   </section>
 
   <section name="Apache Mailet Base">
 
-    <p>Apache Mailet Base 3.0.1 is the latest stable version. You can use Mailet Base content using this maven dependency:</p>
+    <p>Apache Mailet Base 3.0.1 is the latest stable version.</p>
+
+    <p>Sources:
+      <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-base-sources-3.0.1.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-base-sources-3.0.1.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-base-sources-3.0.1.zip.asc">PGP</a>]
+    </p>
+
+    <p>You can use the mailet API using this maven dependency:</p>
 
     <pre>
       <code>
@@ -454,17 +465,19 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-base-3.0.1.jar.asc">PGP</a>]
     </p>
 
-    <p>Sources:
-      <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-base-sources-3.0.1.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-base-sources-3.0.1.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-base-sources-3.0.1.zip.asc">PGP</a>]
-    </p>
-
   </section>
 
   <section name="Apache Mailet Standard">
 
-    <p>Apache Mailet Standard 3.0.1 is the latest stable version. You can use mailet Standard content using this maven dependency:</p>
+    <p>Apache Mailet Standard 3.0.1 is the latest stable version. </p>
+
+    <p>Sources:
+      <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-standard-sources-3.0.1.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-standard-sources-3.0.1.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-standard-sources-3.0.1.zip.asc">PGP</a>]
+    </p>
+
+    <p>You can use mailet Standard content using this maven dependency:</p>
 
     <pre>
       <code>
@@ -482,12 +495,6 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-standard-3.0.1.jar.asc">PGP</a>]
     </p>
 
-    <p>Sources:
-      <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-standard-sources-3.0.1.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-standard-sources-3.0.1.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-standard-sources-3.0.1.zip.asc">PGP</a>]
-    </p>
-
   </section>
 
   <section name="Apache Crypto Mailets">
@@ -508,6 +515,12 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     </div>
   </div>
 
+    <p>Sources:
+      <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-crypto-sources-3.0.1.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-crypto-sources-3.0.1.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-crypto-sources-3.0.1.zip.asc">PGP</a>]
+    </p>
+
     <p>You can use Mailet AI content using this maven dependency:</p>
 
     <pre>
@@ -525,12 +538,6 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-crypto-3.0.1.jar.sha1">SHA-1</a>]
       [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-crypto-3.0.1.jar.asc">PGP</a>]
     </p>
-
-    <p>Sources:
-      <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-crypto-sources-3.0.1.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-crypto-sources-3.0.1.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-crypto-sources-3.0.1.zip.asc">PGP</a>]
-    </p>
     
   </section>
 
@@ -577,16 +584,16 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
   
     <p>Apache HUPA 0.0.2 is the latest stable version:</p>
     <ul>
+
+      <li>Source (ZIP Format): <a
+              href="https://repo1.maven.org/maven2/org/apache/james/hupa/hupa-parent/0.0.2/hupa-parent-0.0.2-source-release.zip">hupa-parent-0.0.2-source-release.zip</a>
+        [<a href="https://repo1.maven.org/maven2/org/apache/james/hupa/hupa-parent/0.0.2/hupa-parent-0.0.2-source-release.zip.asc">PGP</a>]
+      </li>
     
     <li>Binary (Java WAR): <a href="https://repo1.maven.org/maven2/org/apache/james/hupa/hupa/0.0.2/hupa-0.0.2.war">hupa-0.0.2.war</a>
       [<a href="https://repo1.maven.org/maven2/org/apache/james/hupa/hupa/0.0.2/hupa-0.0.2.war.asc">PGP</a>]
     </li>
     
-    <li>Source (ZIP Format): <a
-    href="https://repo1.maven.org/maven2/org/apache/james/hupa/hupa-parent/0.0.2/hupa-parent-0.0.2-source-release.zip">hupa-parent-0.0.2-source-release.zip</a>
-      [<a href="https://repo1.maven.org/maven2/org/apache/james/hupa/hupa-parent/0.0.2/hupa-parent-0.0.2-source-release.zip.asc">PGP</a>]
-    </li>
-    
     <li>Jars (including source and javadocs) for the modules are distributed through the standard 
     <a href='https://maven.apache.org'>Maven</a> repositories on <a href="https://repo1.maven.org/maven2/org/apache/james/hupa">https://repo1.maven.org/maven2/org/apache/james/hupa</a>.</li>
     </ul>


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


[07/15] james-project git commit: MAILBOX-332 Cassandra implementation for Quota Threshold Crossing notification

Posted by bt...@apache.org.
http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/QuotaThresholdHistory.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/QuotaThresholdHistory.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/QuotaThresholdHistory.java
index b80a39f..2e3d551 100644
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/QuotaThresholdHistory.java
+++ b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/QuotaThresholdHistory.java
@@ -30,6 +30,7 @@ import java.util.Objects;
 import java.util.Optional;
 
 import com.github.steveash.guavate.Guavate;
+import com.google.common.base.MoreObjects;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 
@@ -106,4 +107,11 @@ public class QuotaThresholdHistory {
     public final int hashCode() {
         return Objects.hash(changes);
     }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+            .add("changes", changes)
+            .toString();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventSourcingSystemTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventSourcingSystemTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventSourcingSystemTest.java
index b2b26a3..f0feab2 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventSourcingSystemTest.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventSourcingSystemTest.java
@@ -36,8 +36,7 @@ import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 
-
-interface EventSourcingSystemTest {
+public interface EventSourcingSystemTest {
 
     String PAYLOAD_1 = "payload1";
     String PAYLOAD_2 = "payload2";

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventStoreTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventStoreTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventStoreTest.java
index c847f81..aad8daa 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventStoreTest.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/EventStoreTest.java
@@ -11,7 +11,7 @@ import com.google.common.collect.ImmutableList;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
 
-interface EventStoreTest {
+public interface EventStoreTest {
 
     TestAggregateId AGGREGATE_1 = testId(1);
     TestAggregateId AGGREGATE_2 = testId(2);

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/TestAggregateId.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/TestAggregateId.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/TestAggregateId.java
index 1d7c8af..b3ae78c 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/TestAggregateId.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/eventsourcing/TestAggregateId.java
@@ -40,6 +40,10 @@ public class TestAggregateId implements AggregateId  {
         return "TestAggregateId-" + id;
     }
 
+    public int getId() {
+        return id;
+    }
+
     @Override
     public final boolean equals(Object o) {
         if (o instanceof TestAggregateId) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/pom.xml
----------------------------------------------------------------------
diff --git a/mailbox/pom.xml b/mailbox/pom.xml
index 560d59b..4390469 100644
--- a/mailbox/pom.xml
+++ b/mailbox/pom.xml
@@ -54,6 +54,7 @@
         <module>zoo-seq-provider</module>
 
         <module>plugin/quota-mailing</module>
+        <module>plugin/quota-mailing-cassandra</module>
         <module>plugin/quota-mailing-memory</module>
         <module>plugin/spamassassin</module>
     </modules>


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


[10/15] james-project git commit: MAILBOX-332 Fix typo

Posted by bt...@apache.org.
MAILBOX-332 Fix typo


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/0a393f69
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/0a393f69
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/0a393f69

Branch: refs/heads/master
Commit: 0a393f693e47e15ee02c56f8b7115fd4a27f44e5
Parents: c76a4ec
Author: benwa <bt...@linagora.com>
Authored: Wed May 9 16:46:03 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu May 10 09:15:41 2018 +0700

----------------------------------------------------------------------
 .../org/apache/james/mailbox/quota/model/HistoryEvolution.java   | 2 +-
 .../apache/james/mailbox/quota/model/QuotaThresholdHistory.java  | 4 ++--
 .../quota/mailing/subscribers/QuotaThresholdNoticeTest.java      | 4 ++--
 .../apache/james/mailbox/quota/model/HistoryEvolutionTest.java   | 4 ++--
 .../james/mailbox/quota/model/QuotaThresholdHistoryTest.java     | 4 ++--
 5 files changed, 9 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/0a393f69/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/HistoryEvolution.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/HistoryEvolution.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/HistoryEvolution.java
index 7f71025..49db1ee 100644
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/HistoryEvolution.java
+++ b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/HistoryEvolution.java
@@ -51,7 +51,7 @@ public class HistoryEvolution {
     }
 
     public enum HighestThresholdRecentness {
-        AlreadyReachedDuringGracePriod,
+        AlreadyReachedDuringGracePeriod,
         NotAlreadyReachedDuringGracePeriod
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/0a393f69/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/QuotaThresholdHistory.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/QuotaThresholdHistory.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/QuotaThresholdHistory.java
index 2e3d551..6002591 100644
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/QuotaThresholdHistory.java
+++ b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/QuotaThresholdHistory.java
@@ -19,7 +19,7 @@
 
 package org.apache.james.mailbox.quota.model;
 
-import static org.apache.james.mailbox.quota.model.HistoryEvolution.HighestThresholdRecentness.AlreadyReachedDuringGracePriod;
+import static org.apache.james.mailbox.quota.model.HistoryEvolution.HighestThresholdRecentness.AlreadyReachedDuringGracePeriod;
 import static org.apache.james.mailbox.quota.model.HistoryEvolution.HighestThresholdRecentness.NotAlreadyReachedDuringGracePeriod;
 
 import java.time.Duration;
@@ -70,7 +70,7 @@ public class QuotaThresholdHistory {
             return HistoryEvolution.noChanges();
         }
         return recentlyExceededQuotaThreshold(thresholdChange, gracePeriod)
-                .map(any -> HistoryEvolution.higherThresholdReached(thresholdChange, AlreadyReachedDuringGracePriod))
+                .map(any -> HistoryEvolution.higherThresholdReached(thresholdChange, AlreadyReachedDuringGracePeriod))
                 .orElse(HistoryEvolution.higherThresholdReached(thresholdChange, NotAlreadyReachedDuringGracePeriod));
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/0a393f69/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java
index e652e0b..03c2ea2 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java
@@ -19,7 +19,7 @@
 
 package org.apache.james.mailbox.quota.mailing.subscribers;
 
-import static org.apache.james.mailbox.quota.model.HistoryEvolution.HighestThresholdRecentness.AlreadyReachedDuringGracePriod;
+import static org.apache.james.mailbox.quota.model.HistoryEvolution.HighestThresholdRecentness.AlreadyReachedDuringGracePeriod;
 import static org.apache.james.mailbox.quota.model.HistoryEvolution.HighestThresholdRecentness.NotAlreadyReachedDuringGracePeriod;
 import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture.TestConstants.NOW;
 import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture._80;
@@ -81,7 +81,7 @@ class QuotaThresholdNoticeTest {
         assertThat(QuotaThresholdNotice.builder()
             .sizeQuota(Sizes._82_PERCENT)
             .countQuota(Counts._82_PERCENT)
-            .sizeThreshold(HistoryEvolution.higherThresholdReached(new QuotaThresholdChange(_80, NOW), AlreadyReachedDuringGracePriod))
+            .sizeThreshold(HistoryEvolution.higherThresholdReached(new QuotaThresholdChange(_80, NOW), AlreadyReachedDuringGracePeriod))
             .build())
             .isEmpty();
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/0a393f69/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/HistoryEvolutionTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/HistoryEvolutionTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/HistoryEvolutionTest.java
index 566991c..2855e6f 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/HistoryEvolutionTest.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/HistoryEvolutionTest.java
@@ -57,7 +57,7 @@ class HistoryEvolutionTest {
     @Test
     void isModifiedShouldReturnTrueWhenHigherThresholdAlreadyReachedWithinGracePeriod() {
         assertThat(
-            HistoryEvolution.higherThresholdReached(SAMPLE_THRESHOLD, HistoryEvolution.HighestThresholdRecentness.AlreadyReachedDuringGracePriod)
+            HistoryEvolution.higherThresholdReached(SAMPLE_THRESHOLD, HistoryEvolution.HighestThresholdRecentness.AlreadyReachedDuringGracePeriod)
                 .isChange())
             .isTrue();
     }
@@ -89,7 +89,7 @@ class HistoryEvolutionTest {
     @Test
     void currentThresholdNotRecentlyReachedShouldReturnFalseWhenHigherThresholdReachedAlreadyReachedWithinGracePeriod() {
         assertThat(
-            HistoryEvolution.higherThresholdReached(SAMPLE_THRESHOLD, HistoryEvolution.HighestThresholdRecentness.AlreadyReachedDuringGracePriod)
+            HistoryEvolution.higherThresholdReached(SAMPLE_THRESHOLD, HistoryEvolution.HighestThresholdRecentness.AlreadyReachedDuringGracePeriod)
                 .currentThresholdNotRecentlyReached())
             .isFalse();
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/0a393f69/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdHistoryTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdHistoryTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdHistoryTest.java
index 9ea774d..a4bf51c 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdHistoryTest.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdHistoryTest.java
@@ -19,7 +19,7 @@
 
 package org.apache.james.mailbox.quota.model;
 
-import static org.apache.james.mailbox.quota.model.HistoryEvolution.HighestThresholdRecentness.AlreadyReachedDuringGracePriod;
+import static org.apache.james.mailbox.quota.model.HistoryEvolution.HighestThresholdRecentness.AlreadyReachedDuringGracePeriod;
 import static org.apache.james.mailbox.quota.model.HistoryEvolution.HighestThresholdRecentness.NotAlreadyReachedDuringGracePeriod;
 import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture.TestConstants.GRACE_PERIOD;
 import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture.TestConstants.NOW;
@@ -81,7 +81,7 @@ public class QuotaThresholdHistoryTest {
                     new QuotaThresholdChange(_75, NOW.minus(Duration.ofHours(12))),
                     new QuotaThresholdChange(_50, NOW.minus(Duration.ofHours(6))))
                 .compareWithCurrentThreshold(new QuotaThresholdChange(_75, NOW), GRACE_PERIOD))
-            .isEqualTo(HistoryEvolution.higherThresholdReached(new QuotaThresholdChange(_75, NOW), AlreadyReachedDuringGracePriod));
+            .isEqualTo(HistoryEvolution.higherThresholdReached(new QuotaThresholdChange(_75, NOW), AlreadyReachedDuringGracePeriod));
     }
 
 }
\ No newline at end of file


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


[14/15] james-project git commit: MAILBOX-333 Use mustache to render Quota Threshold notices

Posted by bt...@apache.org.
MAILBOX-333 Use mustache to render Quota Threshold notices


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/08e7d4bf
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/08e7d4bf
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/08e7d4bf

Branch: refs/heads/master
Commit: 08e7d4bf2efbf4c8e89dd80d24718d1807712703
Parents: d11d5d5
Author: benwa <bt...@linagora.com>
Authored: Wed May 9 10:32:11 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu May 10 09:24:27 2018 +0700

----------------------------------------------------------------------
 mailbox/plugin/quota-mailing-cassandra/pom.xml  |   5 +
 mailbox/plugin/quota-mailing-memory/pom.xml     |   7 +-
 mailbox/plugin/quota-mailing/pom.xml            |  15 +-
 .../QuotaMailingListenerConfiguration.java      |   6 +-
 .../subscribers/QuotaThresholdMailer.java       |  19 ++-
 .../subscribers/QuotaThresholdNotice.java       | 163 ++++++++++---------
 .../templates/QuotaThresholdMailBody.mustache   |  14 ++
 .../QuotaThresholdMailSubject.mustache          |   1 +
 .../QuotaThresholdListenersTestSystem.java      |   7 +-
 .../QuotaThresholdMailingIntegrationTest.java   |   4 +-
 .../subscribers/QuotaThresholdNoticeTest.java   |  49 ++++--
 .../quota/model/QuotaThresholdFixture.java      |   2 +-
 pom.xml                                         |   5 +
 server/mailet/integration-testing/pom.xml       |   1 -
 14 files changed, 193 insertions(+), 105 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/08e7d4bf/mailbox/plugin/quota-mailing-cassandra/pom.xml
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/pom.xml b/mailbox/plugin/quota-mailing-cassandra/pom.xml
index 38dbda2..b6b3b2c 100644
--- a/mailbox/plugin/quota-mailing-cassandra/pom.xml
+++ b/mailbox/plugin/quota-mailing-cassandra/pom.xml
@@ -73,6 +73,11 @@
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>james-server-data-memory</artifactId>
             <scope>test</scope>
         </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/08e7d4bf/mailbox/plugin/quota-mailing-memory/pom.xml
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-memory/pom.xml b/mailbox/plugin/quota-mailing-memory/pom.xml
index 612ed6a..ad3a70f 100644
--- a/mailbox/plugin/quota-mailing-memory/pom.xml
+++ b/mailbox/plugin/quota-mailing-memory/pom.xml
@@ -56,13 +56,18 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.apache.james</groupId>
+            <groupId>${project.groupId}</groupId>
             <artifactId>apache-mailet-base</artifactId>
             <type>test-jar</type>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>james-server-data-memory</artifactId>
             <scope>test</scope>
         </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/08e7d4bf/mailbox/plugin/quota-mailing/pom.xml
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/pom.xml b/mailbox/plugin/quota-mailing/pom.xml
index 480bae9..8cfb37f 100644
--- a/mailbox/plugin/quota-mailing/pom.xml
+++ b/mailbox/plugin/quota-mailing/pom.xml
@@ -54,13 +54,18 @@
             <artifactId>apache-mailet-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.apache.james</groupId>
+            <groupId>${project.groupId}</groupId>
             <artifactId>apache-mailet-base</artifactId>
             <type>test-jar</type>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>james-server-data-api</artifactId>
         </dependency>
         <dependency>
@@ -69,6 +74,14 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-filesystem-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.github.spullara.mustache.java</groupId>
+            <artifactId>compiler</artifactId>
+        </dependency>
+        <dependency>
             <groupId>javax.inject</groupId>
             <artifactId>javax.inject</artifactId>
         </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/08e7d4bf/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/QuotaMailingListenerConfiguration.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/QuotaMailingListenerConfiguration.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/QuotaMailingListenerConfiguration.java
index 5551b20..b501130 100644
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/QuotaMailingListenerConfiguration.java
+++ b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/QuotaMailingListenerConfiguration.java
@@ -61,17 +61,17 @@ public class QuotaMailingListenerConfiguration {
             return this;
         }
 
-        public Builder withGracePeriod(Duration duration) {
+        public Builder gracePeriod(Duration duration) {
             this.gradePeriod = Optional.of(duration);
             return this;
         }
         
-        public Builder withBodyTemplate(String bodyTemplate) {
+        public Builder bodyTemplate(String bodyTemplate) {
             this.bodyTemplate = Optional.of(bodyTemplate);
             return this;
         }
 
-        public Builder withSubjectTemplate(String subjectTemplate) {
+        public Builder subjectTemplate(String subjectTemplate) {
             this.subjectTemplate = Optional.of(subjectTemplate);
             return this;
         }

http://git-wip-us.apache.org/repos/asf/james-project/blob/08e7d4bf/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdMailer.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdMailer.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdMailer.java
index 2b5cc94..54cb1b9 100644
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdMailer.java
+++ b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdMailer.java
@@ -19,15 +19,17 @@
 
 package org.apache.james.mailbox.quota.mailing.subscribers;
 
+import java.io.IOException;
 import java.util.Optional;
 
 import javax.mail.MessagingException;
 
 import org.apache.james.core.MailAddress;
 import org.apache.james.core.User;
-import org.apache.james.core.builder.MimeMessageBuilder;
 import org.apache.james.eventsourcing.Event;
 import org.apache.james.eventsourcing.Subscriber;
+import org.apache.james.filesystem.api.FileSystem;
+import org.apache.james.mailbox.quota.mailing.QuotaMailingListenerConfiguration;
 import org.apache.james.mailbox.quota.mailing.events.QuotaThresholdChangedEvent;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
@@ -39,10 +41,14 @@ import com.google.common.collect.ImmutableList;
 public class QuotaThresholdMailer implements Subscriber {
     private final MailetContext mailetContext;
     private final UsersRepository usersRepository;
+    private final FileSystem fileSystem;
+    private final QuotaMailingListenerConfiguration configuration;
 
-    public QuotaThresholdMailer(MailetContext mailetContext, UsersRepository usersRepository) {
+    public QuotaThresholdMailer(MailetContext mailetContext, UsersRepository usersRepository, FileSystem fileSystem, QuotaMailingListenerConfiguration configuration) {
         this.mailetContext = mailetContext;
         this.usersRepository = usersRepository;
+        this.fileSystem = fileSystem;
+        this.configuration = configuration;
     }
 
     @Override
@@ -58,21 +64,20 @@ public class QuotaThresholdMailer implements Subscriber {
             .sizeQuota(event.getSizeQuota())
             .countThreshold(event.getCountHistoryEvolution())
             .sizeThreshold(event.getSizeHistoryEvolution())
+            .withConfiguration(configuration)
             .build();
 
         maybeNotice.ifPresent(Throwing.consumer(notice -> sendNotice(notice, event.getAggregateId().getUser())));
     }
 
-    private void sendNotice(QuotaThresholdNotice notice, User user) throws UsersRepositoryException, MessagingException {
+    private void sendNotice(QuotaThresholdNotice notice, User user) throws UsersRepositoryException, MessagingException, IOException {
         MailAddress sender = mailetContext.getPostmaster();
         MailAddress recipient = usersRepository.getMailAddressFor(user);
 
         mailetContext.sendMail(sender, ImmutableList.of(recipient),
-            MimeMessageBuilder.mimeMessageBuilder()
-                .addFrom(sender.asString())
+            notice.generateMimeMessage(fileSystem)
                 .addToRecipient(recipient.asString())
-                .setSubject("Warning: Your email usage just exceeded a configured threshold")
-                .setText(notice.generateReport())
+                .addFrom(sender.asString())
                 .build());
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/08e7d4bf/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNotice.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNotice.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNotice.java
index 34b166b..bc007c5 100644
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNotice.java
+++ b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNotice.java
@@ -19,17 +19,32 @@
 
 package org.apache.james.mailbox.quota.mailing.subscribers;
 
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.StringReader;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
 import java.util.Objects;
 import java.util.Optional;
 
 import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.james.core.builder.MimeMessageBuilder;
+import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.quota.QuotaCount;
 import org.apache.james.mailbox.quota.QuotaSize;
+import org.apache.james.mailbox.quota.mailing.QuotaMailingListenerConfiguration;
 import org.apache.james.mailbox.quota.model.HistoryEvolution;
 import org.apache.james.mailbox.quota.model.QuotaThreshold;
 import org.apache.james.mailbox.quota.model.QuotaThresholdChange;
 
+import com.github.mustachejava.DefaultMustacheFactory;
+import com.github.mustachejava.Mustache;
+import com.github.mustachejava.MustacheFactory;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 
@@ -40,6 +55,7 @@ public class QuotaThresholdNotice {
         private Optional<QuotaThreshold> sizeThreshold;
         private Quota<QuotaSize> sizeQuota;
         private Quota<QuotaCount> countQuota;
+        private QuotaMailingListenerConfiguration configuration;
 
         public Builder() {
             countThreshold = Optional.empty();
@@ -72,85 +88,29 @@ public class QuotaThresholdNotice {
             return this;
         }
 
+        public Builder withConfiguration(QuotaMailingListenerConfiguration configuration) {
+            this.configuration = configuration;
+            return this;
+        }
+
         boolean needsNotification(HistoryEvolution evolution) {
             return evolution.getThresholdHistoryChange() == HistoryEvolution.HistoryChangeType.HigherThresholdReached
                 && evolution.currentThresholdNotRecentlyReached();
         }
 
         public Optional<QuotaThresholdNotice> build() {
+            Preconditions.checkNotNull(configuration);
             Preconditions.checkNotNull(sizeQuota);
-            Preconditions.checkNotNull(countQuota);
+            Preconditions.checkNotNull(configuration);
 
             if (sizeThreshold.isPresent() || countThreshold.isPresent()) {
                 return Optional.of(
-                    new QuotaThresholdNotice(countThreshold, sizeThreshold, sizeQuota, countQuota));
+                    new QuotaThresholdNotice(countThreshold, sizeThreshold, sizeQuota, countQuota, configuration));
             }
             return Optional.empty();
         }
     }
 
-    public static class MessageBuilder {
-        public static final String PREAMBLE = "You receive this email because you recently exceeded a threshold related " +
-            "to the quotas of your email account.\n\n";
-        public static final String CONCLUSION = "You need to be aware that actions leading to exceeded quotas will be denied. " +
-            "This will result in a degraded service.\n" +
-            "To mitigate this issue you might reach your administrator in order to increase your configured quota. " +
-            "You might also delete some non important emails.";
-
-        private final StringBuilder stringBuilder;
-
-
-        public MessageBuilder() {
-            this.stringBuilder = new StringBuilder();
-        }
-
-        public MessageBuilder appendSizeReport(QuotaThreshold threshold, Quota<QuotaSize> sizeQuota) {
-            stringBuilder.append(String.format("You currently occupy more than %d %% of the total size allocated to you.\n" +
-                    "You currently occupy %s on a total of %s allocated to you.\n\n",
-                threshold.getQuotaOccupationRatioAsPercent(),
-                FileUtils.byteCountToDisplaySize(sizeQuota.getUsed().asLong()),
-                FileUtils.byteCountToDisplaySize(sizeQuota.getLimit().asLong())));
-            return this;
-        }
-
-        public MessageBuilder appendCountReport(QuotaThreshold threshold, Quota<QuotaCount> countQuota) {
-            stringBuilder.append(String.format("You currently occupy more than %d %% of the total message count allocated to you.\n" +
-                    "You currently have %d messages on a total of %d allowed for you.\n\n",
-                threshold.getQuotaOccupationRatioAsPercent(),
-                countQuota.getUsed().asLong(),
-                countQuota.getLimit().asLong()));
-            return this;
-        }
-
-        public MessageBuilder appendSizeReport(Optional<QuotaThreshold> threshold, Quota<QuotaSize> sizeQuota) {
-            if (threshold.isPresent()) {
-                return appendSizeReport(threshold.get(), sizeQuota);
-            }
-            return this;
-        }
-
-        public MessageBuilder appendCountReport(Optional<QuotaThreshold> threshold, Quota<QuotaCount> countQuota) {
-            if (threshold.isPresent()) {
-                return appendCountReport(threshold.get(), countQuota);
-            }
-            return this;
-        }
-
-        public MessageBuilder appendPreamble() {
-            stringBuilder.append(PREAMBLE);
-            return this;
-        }
-
-        public MessageBuilder appendConclusion() {
-            stringBuilder.append(CONCLUSION);
-            return this;
-        }
-
-        public String build() {
-            return stringBuilder.toString();
-        }
-    }
-
     public static Builder builder() {
         return new Builder();
     }
@@ -159,23 +119,77 @@ public class QuotaThresholdNotice {
     private final Optional<QuotaThreshold> sizeThreshold;
     private final Quota<QuotaSize> sizeQuota;
     private final Quota<QuotaCount> countQuota;
+    private final QuotaMailingListenerConfiguration configuration;
 
     @VisibleForTesting
     QuotaThresholdNotice(Optional<QuotaThreshold> countThreshold, Optional<QuotaThreshold> sizeThreshold,
-                         Quota<QuotaSize> sizeQuota, Quota<QuotaCount> countQuota) {
+                         Quota<QuotaSize> sizeQuota, Quota<QuotaCount> countQuota, QuotaMailingListenerConfiguration configuration) {
         this.countThreshold = countThreshold;
         this.sizeThreshold = sizeThreshold;
         this.sizeQuota = sizeQuota;
         this.countQuota = countQuota;
+        this.configuration = configuration;
+    }
+
+    public MimeMessageBuilder generateMimeMessage(FileSystem fileSystem) throws IOException {
+        return MimeMessageBuilder.mimeMessageBuilder()
+            .setSubject(generateSubject(fileSystem))
+            .setText(generateReport(fileSystem));
+    }
+
+    @VisibleForTesting
+    String generateSubject(FileSystem fileSystem) throws IOException {
+        return renderTemplate(fileSystem, configuration.getSubjectTemplate());
+    }
+
+    @VisibleForTesting
+    String generateReport(FileSystem fileSystem) throws IOException {
+        return renderTemplate(fileSystem, configuration.getBodyTemplate());
+    }
+
+    private String renderTemplate(FileSystem fileSystem, String template) throws IOException {
+        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+             Writer writer = new OutputStreamWriter(byteArrayOutputStream)) {
+
+            MustacheFactory mf = new DefaultMustacheFactory();
+            Mustache mustache = mf.compile(getPatternReader(fileSystem, template), "example");
+            mustache.execute(writer, computeScopes());
+            writer.flush();
+            return new String(byteArrayOutputStream.toByteArray(), StandardCharsets.UTF_8);
+        }
+    }
+
+    private StringReader getPatternReader(FileSystem fileSystem, String path) throws IOException {
+        try (InputStream patternStream = fileSystem.getResource(path);
+             ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
+
+            IOUtils.copy(patternStream, byteArrayOutputStream);
+            String pattern = new String(byteArrayOutputStream.toByteArray(), StandardCharsets.UTF_8);
+            return new StringReader(pattern);
+        }
     }
 
-    public String generateReport() {
-        return new MessageBuilder()
-            .appendPreamble()
-            .appendSizeReport(sizeThreshold, sizeQuota)
-            .appendCountReport(countThreshold, countQuota)
-            .appendConclusion()
-            .build();
+    private HashMap<String, Object> computeScopes() {
+        HashMap<String, Object> scopes = new HashMap<>();
+
+        scopes.put("hasExceededSizeThreshold", sizeThreshold.isPresent());
+        scopes.put("hasExceededCountThreshold", countThreshold.isPresent());
+        sizeThreshold.ifPresent(value -> scopes.put("sizeThreshold", value.getQuotaOccupationRatioAsPercent()));
+        countThreshold.ifPresent(value -> scopes.put("countThreshold", value.getQuotaOccupationRatioAsPercent()));
+
+        scopes.put("usedSize", FileUtils.byteCountToDisplaySize(sizeQuota.getUsed().asLong()));
+        scopes.put("hasSizeLimit", sizeQuota.getLimit().isLimited());
+        if (sizeQuota.getLimit().isLimited()) {
+            scopes.put("limitSize", FileUtils.byteCountToDisplaySize(sizeQuota.getLimit().asLong()));
+        }
+
+        scopes.put("usedCount", countQuota.getUsed().asLong());
+        scopes.put("hasCountLimit", countQuota.getLimit().isLimited());
+        if (countQuota.getLimit().isLimited()) {
+            scopes.put("limitCount", sizeQuota.getLimit().asLong());
+        }
+
+        return scopes;
     }
 
     @Override
@@ -186,14 +200,15 @@ public class QuotaThresholdNotice {
             return Objects.equals(this.countThreshold, that.countThreshold)
                 && Objects.equals(this.sizeThreshold, that.sizeThreshold)
                 && Objects.equals(this.sizeQuota, that.sizeQuota)
-                && Objects.equals(this.countQuota, that.countQuota);
+                && Objects.equals(this.countQuota, that.countQuota)
+                && Objects.equals(this.configuration, that.configuration);
         }
         return false;
     }
 
     @Override
     public final int hashCode() {
-        return Objects.hash(countThreshold, sizeThreshold, sizeQuota, countQuota);
+        return Objects.hash(countThreshold, sizeThreshold, sizeQuota, countQuota, configuration);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/08e7d4bf/mailbox/plugin/quota-mailing/src/main/resources/templates/QuotaThresholdMailBody.mustache
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/resources/templates/QuotaThresholdMailBody.mustache b/mailbox/plugin/quota-mailing/src/main/resources/templates/QuotaThresholdMailBody.mustache
new file mode 100644
index 0000000..1b5ebd9
--- /dev/null
+++ b/mailbox/plugin/quota-mailing/src/main/resources/templates/QuotaThresholdMailBody.mustache
@@ -0,0 +1,14 @@
+You receive this email because you recently exceeded a threshold related to the quotas of your email account.
+
+{{#hasExceededSizeThreshold}}
+You currently occupy more than {{sizeThreshold}} % of the total size allocated to you.
+You currently occupy {{usedSize}}{{#hasSizeLimit}} on a total of {{limitSize}} allocated to you{{/hasSizeLimit}}.
+
+{{/hasExceededSizeThreshold}}
+{{#hasExceededCountThreshold}}
+You currently occupy more than {{countThreshold}} % of the total message count allocated to you.
+You currently have {{usedCount}} messages{{#hasCountLimit}} on a total of {{limitCount}} allowed for you{{/hasCountLimit}}.
+
+{{/hasExceededCountThreshold}}
+You need to be aware that actions leading to exceeded quotas will be denied. This will result in a degraded service.
+To mitigate this issue you might reach your administrator in order to increase your configured quota. You might also delete some non important emails.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/08e7d4bf/mailbox/plugin/quota-mailing/src/main/resources/templates/QuotaThresholdMailSubject.mustache
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/resources/templates/QuotaThresholdMailSubject.mustache b/mailbox/plugin/quota-mailing/src/main/resources/templates/QuotaThresholdMailSubject.mustache
new file mode 100644
index 0000000..6efe171
--- /dev/null
+++ b/mailbox/plugin/quota-mailing/src/main/resources/templates/QuotaThresholdMailSubject.mustache
@@ -0,0 +1 @@
+Warning: Your email usage just exceeded a configured threshold
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/08e7d4bf/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdListenersTestSystem.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdListenersTestSystem.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdListenersTestSystem.java
index cfae4fc..bb1dce8 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdListenersTestSystem.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdListenersTestSystem.java
@@ -21,6 +21,7 @@ package org.apache.james.mailbox.quota.mailing.listeners;
 
 import org.apache.james.eventsourcing.EventSourcingSystem;
 import org.apache.james.eventsourcing.EventStore;
+import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.mailbox.Event;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.mock.MockMailboxSession;
@@ -28,6 +29,8 @@ import org.apache.james.mailbox.quota.mailing.QuotaMailingListenerConfiguration;
 import org.apache.james.mailbox.quota.mailing.commands.DetectThresholdCrossingHandler;
 import org.apache.james.mailbox.quota.mailing.subscribers.QuotaThresholdMailer;
 import org.apache.james.mailbox.store.event.DefaultDelegatingMailboxListener;
+import org.apache.james.server.core.JamesServerResourceLoader;
+import org.apache.james.server.core.filesystem.FileSystemImpl;
 import org.apache.james.user.memory.MemoryUsersRepository;
 import org.apache.mailet.MailetContext;
 
@@ -40,9 +43,11 @@ public class QuotaThresholdListenersTestSystem {
     public QuotaThresholdListenersTestSystem(MailetContext mailetContext, EventStore eventStore, QuotaMailingListenerConfiguration configuration) throws MailboxException {
         delegatingListener = new DefaultDelegatingMailboxListener();
 
+        FileSystem fileSystem = new FileSystemImpl(new JamesServerResourceLoader("."));
+
         EventSourcingSystem eventSourcingSystem = new EventSourcingSystem(
             ImmutableSet.of(new DetectThresholdCrossingHandler(eventStore, configuration)),
-            ImmutableSet.of(new QuotaThresholdMailer(mailetContext, MemoryUsersRepository.withVirtualHosting())),
+            ImmutableSet.of(new QuotaThresholdMailer(mailetContext, MemoryUsersRepository.withVirtualHosting(), fileSystem, configuration)),
             eventStore);
 
         QuotaThresholdCrossingListener thresholdCrossingListener =

http://git-wip-us.apache.org/repos/asf/james-project/blob/08e7d4bf/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java
index 86e947e..604d891 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java
@@ -192,7 +192,7 @@ public interface QuotaThresholdMailingIntegrationTest {
         QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
             QuotaMailingListenerConfiguration.builder()
                 .addThresholds(_50, _80)
-                .withGracePeriod(GRACE_PERIOD)
+                .gracePeriod(GRACE_PERIOD)
                 .build());
 
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._52_PERCENT, Sizes._30_PERCENT, NOW));
@@ -208,7 +208,7 @@ public interface QuotaThresholdMailingIntegrationTest {
         QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
             QuotaMailingListenerConfiguration.builder()
                 .addThresholds(_50, _80)
-                .withGracePeriod(GRACE_PERIOD)
+                .gracePeriod(GRACE_PERIOD)
                 .build());
 
         new ConcurrentTestRunner(10, 1, (threadNb, step) ->

http://git-wip-us.apache.org/repos/asf/james-project/blob/08e7d4bf/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java
index b656cf0..20ccaaa 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/subscribers/QuotaThresholdNoticeTest.java
@@ -21,12 +21,14 @@ package org.apache.james.mailbox.quota.mailing.subscribers;
 
 import static org.apache.james.mailbox.quota.model.HistoryEvolution.HighestThresholdRecentness.AlreadyReachedDuringGracePeriod;
 import static org.apache.james.mailbox.quota.model.HistoryEvolution.HighestThresholdRecentness.NotAlreadyReachedDuringGracePeriod;
+import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture.TestConstants.DEFAULT_CONFIGURATION;
 import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture.TestConstants.NOW;
 import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture._80;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.util.Optional;
 
+import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.quota.QuotaCount;
 import org.apache.james.mailbox.quota.QuotaSize;
@@ -34,13 +36,22 @@ import org.apache.james.mailbox.quota.model.HistoryEvolution;
 import org.apache.james.mailbox.quota.model.QuotaThresholdChange;
 import org.apache.james.mailbox.quota.model.QuotaThresholdFixture.Quotas.Counts;
 import org.apache.james.mailbox.quota.model.QuotaThresholdFixture.Quotas.Sizes;
-import org.junit.jupiter.api.Disabled;
+import org.apache.james.server.core.JamesServerResourceLoader;
+import org.apache.james.server.core.filesystem.FileSystemImpl;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
 
 class QuotaThresholdNoticeTest {
 
+    private FileSystem fileSystem;
+
+    @BeforeEach
+    public void setUp() {
+        fileSystem = new FileSystemImpl(new JamesServerResourceLoader("."));
+    }
+
     @Test
     void shouldMatchBeanContract() {
         EqualsVerifier.forClass(QuotaThresholdNotice.class)
@@ -53,6 +64,7 @@ class QuotaThresholdNoticeTest {
         assertThat(QuotaThresholdNotice.builder()
             .sizeQuota(Sizes._82_PERCENT)
             .countQuota(Counts._82_PERCENT)
+            .withConfiguration(DEFAULT_CONFIGURATION)
             .build())
             .isEmpty();
     }
@@ -63,6 +75,7 @@ class QuotaThresholdNoticeTest {
             .sizeQuota(Sizes._82_PERCENT)
             .countQuota(Counts._82_PERCENT)
             .sizeThreshold(HistoryEvolution.noChanges())
+            .withConfiguration(DEFAULT_CONFIGURATION)
             .build())
             .isEmpty();
     }
@@ -73,6 +86,7 @@ class QuotaThresholdNoticeTest {
             .sizeQuota(Sizes._82_PERCENT)
             .countQuota(Counts._82_PERCENT)
             .sizeThreshold(HistoryEvolution.lowerThresholdReached(new QuotaThresholdChange(_80, NOW)))
+            .withConfiguration(DEFAULT_CONFIGURATION)
             .build())
             .isEmpty();
     }
@@ -80,6 +94,7 @@ class QuotaThresholdNoticeTest {
     @Test
     void buildShouldReturnEmptyWhenAboveButRecentChanges() {
         assertThat(QuotaThresholdNotice.builder()
+            .withConfiguration(DEFAULT_CONFIGURATION)
             .sizeQuota(Sizes._82_PERCENT)
             .countQuota(Counts._82_PERCENT)
             .sizeThreshold(HistoryEvolution.higherThresholdReached(new QuotaThresholdChange(_80, NOW), AlreadyReachedDuringGracePeriod))
@@ -94,12 +109,13 @@ class QuotaThresholdNoticeTest {
         QuotaThresholdChange sizeThresholdChange = new QuotaThresholdChange(_80, NOW);
 
         assertThat(QuotaThresholdNotice.builder()
+            .withConfiguration(DEFAULT_CONFIGURATION)
             .sizeQuota(sizeQuota)
             .countQuota(countQuota)
             .sizeThreshold(HistoryEvolution.higherThresholdReached(sizeThresholdChange, NotAlreadyReachedDuringGracePeriod))
             .build())
             .isNotEmpty()
-            .contains(new QuotaThresholdNotice(Optional.empty(), Optional.of(sizeThresholdChange.getQuotaThreshold()), sizeQuota, countQuota));
+            .contains(new QuotaThresholdNotice(Optional.empty(), Optional.of(sizeThresholdChange.getQuotaThreshold()), sizeQuota, countQuota, DEFAULT_CONFIGURATION));
     }
 
     @Test
@@ -110,13 +126,14 @@ class QuotaThresholdNoticeTest {
         QuotaThresholdChange countThresholdChange = new QuotaThresholdChange(_80, NOW);
 
         assertThat(QuotaThresholdNotice.builder()
+            .withConfiguration(DEFAULT_CONFIGURATION)
             .sizeQuota(sizeQuota)
             .countQuota(countQuota)
             .sizeThreshold(HistoryEvolution.higherThresholdReached(sizeThresholdChange, NotAlreadyReachedDuringGracePeriod))
             .countThreshold(HistoryEvolution.lowerThresholdReached(countThresholdChange))
             .build())
             .isNotEmpty()
-            .contains(new QuotaThresholdNotice(Optional.empty(), Optional.of(sizeThresholdChange.getQuotaThreshold()), sizeQuota, countQuota));
+            .contains(new QuotaThresholdNotice(Optional.empty(), Optional.of(sizeThresholdChange.getQuotaThreshold()), sizeQuota, countQuota, DEFAULT_CONFIGURATION));
     }
 
     @Test
@@ -127,28 +144,30 @@ class QuotaThresholdNoticeTest {
         QuotaThresholdChange countThresholdChange = new QuotaThresholdChange(_80, NOW);
 
         assertThat(QuotaThresholdNotice.builder()
+            .withConfiguration(DEFAULT_CONFIGURATION)
             .sizeQuota(sizeQuota)
             .countQuota(countQuota)
             .sizeThreshold(HistoryEvolution.higherThresholdReached(sizeThresholdChange, NotAlreadyReachedDuringGracePeriod))
             .countThreshold(HistoryEvolution.higherThresholdReached(countThresholdChange, NotAlreadyReachedDuringGracePeriod))
             .build())
             .isNotEmpty()
-            .contains(new QuotaThresholdNotice(Optional.of(countThresholdChange.getQuotaThreshold()), Optional.of(sizeThresholdChange.getQuotaThreshold()), sizeQuota, countQuota));
+            .contains(new QuotaThresholdNotice(Optional.of(countThresholdChange.getQuotaThreshold()), Optional.of(sizeThresholdChange.getQuotaThreshold()), sizeQuota, countQuota, DEFAULT_CONFIGURATION));
     }
 
     @Test
-    void generateReportShouldGenerateAHumanReadableMessage() {
+    void generateReportShouldGenerateAHumanReadableMessage() throws Exception {
         QuotaThresholdChange sizeThresholdChange = new QuotaThresholdChange(_80, NOW);
         QuotaThresholdChange countThresholdChange = new QuotaThresholdChange(_80, NOW);
 
         assertThat(QuotaThresholdNotice.builder()
+            .withConfiguration(DEFAULT_CONFIGURATION)
             .sizeQuota(Sizes._82_PERCENT)
             .countQuota(Counts._92_PERCENT)
             .sizeThreshold(HistoryEvolution.higherThresholdReached(sizeThresholdChange, NotAlreadyReachedDuringGracePeriod))
             .countThreshold(HistoryEvolution.higherThresholdReached(countThresholdChange, NotAlreadyReachedDuringGracePeriod))
             .build()
             .get()
-            .generateReport())
+            .generateReport(fileSystem))
             .isEqualTo("You receive this email because you recently exceeded a threshold related to the quotas of your email account.\n" +
                 "\n" +
                 "You currently occupy more than 80 % of the total size allocated to you.\n" +
@@ -162,16 +181,17 @@ class QuotaThresholdNoticeTest {
     }
 
     @Test
-    void generateReportShouldOmitCountPartWhenNone() {
+    void generateReportShouldOmitCountPartWhenNone() throws Exception {
         QuotaThresholdChange sizeThresholdChange = new QuotaThresholdChange(_80, NOW);
 
         assertThat(QuotaThresholdNotice.builder()
+            .withConfiguration(DEFAULT_CONFIGURATION)
             .sizeQuota(Sizes._82_PERCENT)
             .countQuota(Counts._72_PERCENT)
             .sizeThreshold(HistoryEvolution.higherThresholdReached(sizeThresholdChange, NotAlreadyReachedDuringGracePeriod))
             .build()
             .get()
-            .generateReport())
+            .generateReport(fileSystem))
             .isEqualTo("You receive this email because you recently exceeded a threshold related to the quotas of your email account.\n" +
                 "\n" +
                 "You currently occupy more than 80 % of the total size allocated to you.\n" +
@@ -182,16 +202,17 @@ class QuotaThresholdNoticeTest {
     }
 
     @Test
-    void generateReportShouldOmitSizePartWhenNone() {
+    void generateReportShouldOmitSizePartWhenNone() throws Exception {
         QuotaThresholdChange countThresholdChange = new QuotaThresholdChange(_80, NOW);
 
         assertThat(QuotaThresholdNotice.builder()
+            .withConfiguration(DEFAULT_CONFIGURATION)
             .sizeQuota(Sizes._82_PERCENT)
             .countQuota(Counts._92_PERCENT)
             .countThreshold(HistoryEvolution.higherThresholdReached(countThresholdChange, NotAlreadyReachedDuringGracePeriod))
             .build()
             .get()
-            .generateReport())
+            .generateReport(fileSystem))
             .isEqualTo("You receive this email because you recently exceeded a threshold related to the quotas of your email account.\n" +
                 "\n" +
                 "You currently occupy more than 80 % of the total message count allocated to you.\n" +
@@ -201,22 +222,22 @@ class QuotaThresholdNoticeTest {
                 "To mitigate this issue you might reach your administrator in order to increase your configured quota. You might also delete some non important emails.");
     }
 
-    @Disabled
     @Test
-    void generateReportShouldNotFailWhenUnlimitedQuotaExceedsAThreshold() {
+    void generateReportShouldNotFailWhenUnlimitedQuotaExceedsAThreshold() throws Exception {
         QuotaThresholdChange countThresholdChange = new QuotaThresholdChange(_80, NOW);
 
         assertThat(QuotaThresholdNotice.builder()
+            .withConfiguration(DEFAULT_CONFIGURATION)
             .sizeQuota(Sizes._82_PERCENT)
             .countQuota(Counts._UNLIMITED)
             .countThreshold(HistoryEvolution.higherThresholdReached(countThresholdChange, NotAlreadyReachedDuringGracePeriod))
             .build()
             .get()
-            .generateReport())
+            .generateReport(fileSystem))
             .isEqualTo("You receive this email because you recently exceeded a threshold related to the quotas of your email account.\n" +
                 "\n" +
                 "You currently occupy more than 80 % of the total message count allocated to you.\n" +
-                "You currently have 92 messages on a total of 100 allowed for you.\n" +
+                "You currently have 92 messages.\n" +
                 "\n" +
                 "You need to be aware that actions leading to exceeded quotas will be denied. This will result in a degraded service.\n" +
                 "To mitigate this issue you might reach your administrator in order to increase your configured quota. You might also delete some non important emails.");

http://git-wip-us.apache.org/repos/asf/james-project/blob/08e7d4bf/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdFixture.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdFixture.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdFixture.java
index fc32afa..c8a251f 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdFixture.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdFixture.java
@@ -129,7 +129,7 @@ public interface QuotaThresholdFixture {
         Duration GRACE_PERIOD = Duration.ofDays(1);
         QuotaMailingListenerConfiguration DEFAULT_CONFIGURATION = QuotaMailingListenerConfiguration.builder()
             .addThresholds(_50)
-            .withGracePeriod(GRACE_PERIOD)
+            .gracePeriod(GRACE_PERIOD)
             .build();
         String BOB = "bob@domain";
         MockMailboxSession BOB_SESSION = new MockMailboxSession(BOB);

http://git-wip-us.apache.org/repos/asf/james-project/blob/08e7d4bf/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 9ba6851..4a41df0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1548,6 +1548,11 @@
                 <version>3.1.5</version>
             </dependency>
             <dependency>
+                <groupId>com.github.spullara.mustache.java</groupId>
+                <artifactId>compiler</artifactId>
+                <version>0.9.5</version>
+            </dependency>
+            <dependency>
                 <groupId>com.github.steveash.guavate</groupId>
                 <artifactId>guavate</artifactId>
                 <version>${guavate.version}</version>

http://git-wip-us.apache.org/repos/asf/james-project/blob/08e7d4bf/server/mailet/integration-testing/pom.xml
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/pom.xml b/server/mailet/integration-testing/pom.xml
index 2bbb9b1..4d47e1c 100644
--- a/server/mailet/integration-testing/pom.xml
+++ b/server/mailet/integration-testing/pom.xml
@@ -114,7 +114,6 @@
         <dependency>
             <groupId>com.github.spullara.mustache.java</groupId>
             <artifactId>compiler</artifactId>
-            <version>0.9.5</version>
         </dependency>
         <dependency>
             <groupId>com.google.guava</groupId>


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


[04/15] james-project git commit: MAILBOX-331 Testing quota threshold configuration changes

Posted by bt...@apache.org.
MAILBOX-331 Testing quota threshold configuration changes


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/4b9c3f7b
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/4b9c3f7b
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/4b9c3f7b

Branch: refs/heads/master
Commit: 4b9c3f7b6fdb16e2a2ce6eba25d6311c79d78e34
Parents: 8542f4a
Author: benwa <bt...@linagora.com>
Authored: Mon May 7 15:39:15 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu May 10 09:13:23 2018 +0700

----------------------------------------------------------------------
 ...yQuotaThresholdConfigurationChangesTest.java |  29 +++
 .../QuotaThresholdConfigurationChangesTest.java | 248 +++++++++++++++++++
 2 files changed, 277 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/4b9c3f7b/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/mailbox/quota/memory/listeners/InMemoryQuotaThresholdConfigurationChangesTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/mailbox/quota/memory/listeners/InMemoryQuotaThresholdConfigurationChangesTest.java b/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/mailbox/quota/memory/listeners/InMemoryQuotaThresholdConfigurationChangesTest.java
new file mode 100644
index 0000000..ba65405
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-memory/src/test/java/org/apache/james/mailbox/quota/memory/listeners/InMemoryQuotaThresholdConfigurationChangesTest.java
@@ -0,0 +1,29 @@
+/****************************************************************
+ * 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.quota.memory.listeners;
+
+import org.apache.james.eventsourcing.InMemoryEventStoreExtension;
+import org.apache.james.mailbox.quota.mailing.listeners.QuotaThresholdConfigurationChangesTest;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(InMemoryEventStoreExtension.class)
+public class InMemoryQuotaThresholdConfigurationChangesTest implements QuotaThresholdConfigurationChangesTest {
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/4b9c3f7b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java
new file mode 100644
index 0000000..135b84c
--- /dev/null
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java
@@ -0,0 +1,248 @@
+/****************************************************************
+ * 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.quota.mailing.listeners;
+
+import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture.TestConstants.BOB_SESSION;
+import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture.TestConstants.GRACE_PERIOD;
+import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture.TestConstants.NOW;
+import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture.TestConstants.QUOTAROOT;
+import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture._50;
+import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture._75;
+import static org.apache.james.mailbox.quota.model.QuotaThresholdFixture.mailetContext;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.james.eventsourcing.EventStore;
+import org.apache.james.mailbox.MailboxListener.QuotaUsageUpdatedEvent;
+import org.apache.james.mailbox.quota.mailing.QuotaMailingListenerConfiguration;
+import org.apache.james.mailbox.quota.model.QuotaThresholdFixture.Quotas.Counts;
+import org.apache.james.mailbox.quota.model.QuotaThresholdFixture.Quotas.Sizes;
+import org.apache.james.mailbox.quota.model.QuotaThresholds;
+import org.apache.mailet.base.test.FakeMailContext;
+import org.junit.jupiter.api.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public interface QuotaThresholdConfigurationChangesTest {
+
+    @Test
+    default void shouldNotSendMailWhenNoNewExceededThresholdAfterThresholdIncrease(EventStore store) throws Exception {
+        FakeMailContext mailetContext = mailetContext();
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._55_PERCENT, NOW));
+
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_75)), GRACE_PERIOD));
+
+        mailetContext.resetSentMails();
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._55_PERCENT, NOW));
+
+        assertThat(mailetContext.getSentMails()).isEmpty();
+    }
+
+    @Test
+    default void shouldNotSendMailAfterThresholdDecreaseWhenAboveAll(EventStore store) throws Exception {
+        FakeMailContext mailetContext = mailetContext();
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_75)), GRACE_PERIOD));
+
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
+
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+
+        mailetContext.resetSentMails();
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
+
+        assertThat(mailetContext.getSentMails()).isEmpty();
+    }
+
+    @Test
+    default void shouldSendMailWhenNewExceededThresholdAfterThresholdIncrease(EventStore store) throws Exception {
+        FakeMailContext mailetContext = mailetContext();
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
+
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_75)), GRACE_PERIOD));
+
+        mailetContext.resetSentMails();
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
+
+        assertThat(mailetContext.getSentMails()).hasSize(1);
+    }
+
+    @Test
+    default void shouldNotSendMailAfterThresholdIncreaseWhenBelowAll(EventStore store) throws Exception {
+        FakeMailContext mailetContext = mailetContext();
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._30_PERCENT, NOW));
+
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_75)), GRACE_PERIOD));
+
+        mailetContext.resetSentMails();
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._30_PERCENT, NOW));
+
+        assertThat(mailetContext.getSentMails()).isEmpty();
+    }
+
+    @Test
+    default void shouldNotSendMailAfterThresholdDecreaseWhenBelowAll(EventStore store) throws Exception {
+        FakeMailContext mailetContext = mailetContext();
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_75)), GRACE_PERIOD));
+
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._30_PERCENT, NOW));
+
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+
+        mailetContext.resetSentMails();
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._30_PERCENT, NOW));
+
+        assertThat(mailetContext.getSentMails()).isEmpty();
+    }
+
+    @Test
+    default void shouldSendMailWhenNewExceededThresholdAfterThresholdDecrease(EventStore store) throws Exception {
+        FakeMailContext mailetContext = mailetContext();
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_75)), GRACE_PERIOD));
+
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._60_PERCENT, NOW));
+
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+
+        mailetContext.resetSentMails();
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._60_PERCENT, NOW));
+
+        assertThat(mailetContext.getSentMails()).hasSize(1);
+    }
+
+    @Test
+    default void shouldSendEmailWhenAddingANewHighestExceededThreshold(EventStore store) throws Exception {
+        FakeMailContext mailetContext = mailetContext();
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
+
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50, _75)), GRACE_PERIOD));
+
+        mailetContext.resetSentMails();
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
+
+        assertThat(mailetContext.getSentMails()).hasSize(1);
+    }
+
+    @Test
+    default void shouldNotSendEmailWhenAddingAHighestNonExceededThreshold(EventStore store) throws Exception {
+        FakeMailContext mailetContext = mailetContext();
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._60_PERCENT, NOW));
+
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50, _75)), GRACE_PERIOD));
+
+        mailetContext.resetSentMails();
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._60_PERCENT, NOW));
+
+        assertThat(mailetContext.getSentMails()).isEmpty();
+    }
+
+    @Test
+    default void shouldNotSendEmailWhenAddingANonHighestExceededThreshold(EventStore store) throws Exception {
+        FakeMailContext mailetContext = mailetContext();
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_75)), GRACE_PERIOD));
+
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
+
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50, _75)), GRACE_PERIOD));
+
+        mailetContext.resetSentMails();
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
+
+        assertThat(mailetContext.getSentMails()).isEmpty();
+    }
+
+    @Test
+    default void shouldNotSendEmailWhenRemovingANonHighestExceededThreshold(EventStore store) throws Exception {
+        FakeMailContext mailetContext = mailetContext();
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50, _75)), GRACE_PERIOD));
+
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
+
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_75)), GRACE_PERIOD));
+
+        mailetContext.resetSentMails();
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
+
+        assertThat(mailetContext.getSentMails()).isEmpty();
+    }
+
+    @Test
+    default void shouldNotSendEmailWhenRemovingHighestExceededThreshold(EventStore store) throws Exception {
+        FakeMailContext mailetContext = mailetContext();
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50, _75)), GRACE_PERIOD));
+
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
+
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+
+        mailetContext.resetSentMails();
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
+
+        assertThat(mailetContext.getSentMails()).isEmpty();
+    }
+
+    @Test
+    default void shouldNotSendEmailWhenRemovingHighestNonExceededThreshold(EventStore store) throws Exception {
+        FakeMailContext mailetContext = mailetContext();
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50, _75)), GRACE_PERIOD));
+
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._60_PERCENT, NOW));
+
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+
+        mailetContext.resetSentMails();
+        testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._60_PERCENT, NOW));
+
+        assertThat(mailetContext.getSentMails()).isEmpty();
+    }
+
+}
\ No newline at end of file


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


[08/15] james-project git commit: MAILBOX-332 Cassandra implementation for Quota Threshold Crossing notification

Posted by bt...@apache.org.
MAILBOX-332 Cassandra implementation for Quota Threshold Crossing notification


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/c3a1bda2
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/c3a1bda2
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/c3a1bda2

Branch: refs/heads/master
Commit: c3a1bda2d0bd84c936b5848d06ec6fd9a176868c
Parents: a686c2b
Author: Matthieu Baechler <ma...@apache.org>
Authored: Mon May 7 18:05:45 2018 +0200
Committer: benwa <bt...@linagora.com>
Committed: Thu May 10 09:15:40 2018 +0700

----------------------------------------------------------------------
 .../cassandra/DockerCassandraExtension.java     |   4 +
 .../apache/james/mailbox/quota/QuotaCount.java  |   6 +-
 .../apache/james/mailbox/quota/QuotaSize.java   |   6 +-
 mailbox/plugin/quota-mailing-cassandra/pom.xml  | 135 +++++++++++++++++
 .../cassandra/CassandraEventStore.java          |  62 ++++++++
 .../cassandra/CassandraEventStoreModule.java    |  62 ++++++++
 .../cassandra/CassandraEventStoreTable.java     |  27 ++++
 .../eventsourcing/cassandra/EventStoreDao.java  | 122 +++++++++++++++
 .../cassandra/JsonEventSerializer.java          |  98 +++++++++++++
 .../eventsourcing/cassandra/dto/EventDTO.java   |  26 ++++
 .../cassandra/dto/EventDTOModule.java           |  32 ++++
 .../cassandra/dto/HistoryEvolutionDTO.java      |  98 +++++++++++++
 .../mailbox/quota/cassandra/dto/QuotaDTO.java   |  73 +++++++++
 .../dto/QuotaThresholdChangedEventDTO.java      | 110 ++++++++++++++
 .../QuotaThresholdChangedEventDTOModule.java    |  54 +++++++
 .../CassandraEventSourcingSystemTest.java       |  28 ++++
 .../cassandra/CassandraEventStoreExtension.java |  86 +++++++++++
 .../cassandra/CassandraEventStoreTest.java      |  28 ++++
 .../cassandra/JsonEventSerializerTest.java      |  67 +++++++++
 .../cassandra/dto/TestEventDTO.java             |  73 +++++++++
 .../cassandra/dto/TestEventDTOModule.java       |  56 +++++++
 .../mailbox/quota/cassandra/dto/DTOTest.java    | 147 +++++++++++++++++++
 ...draQuotaMailingListenersIntegrationTest.java |  29 ++++
 .../james/eventsource/InMemoryEventStore.java   |  11 +-
 .../org/apache/james/eventsourcing/Event.java   |  11 ++
 .../events/QuotaThresholdChangedEvent.java      |  20 +++
 .../mailbox/quota/model/HistoryEvolution.java   |  22 +--
 .../quota/model/QuotaThresholdHistory.java      |   8 +
 .../eventsourcing/EventSourcingSystemTest.java  |   3 +-
 .../james/eventsourcing/EventStoreTest.java     |   2 +-
 .../james/eventsourcing/TestAggregateId.java    |   4 +
 mailbox/pom.xml                                 |   1 +
 32 files changed, 1488 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraExtension.java
----------------------------------------------------------------------
diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraExtension.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraExtension.java
index 43a3cb5..add70c8 100644
--- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraExtension.java
+++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraExtension.java
@@ -56,6 +56,10 @@ public class DockerCassandraExtension implements BeforeAllCallback, AfterAllCall
     public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
         return dockerCassandra;
     }
+
+    public DockerCassandra getDockerCassandra() {
+        return dockerCassandra;
+    }
     
     public static class DockerCassandra {
         

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaCount.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaCount.java b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaCount.java
index a932c33..ac17fa0 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaCount.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaCount.java
@@ -30,7 +30,11 @@ public class QuotaCount implements QuotaValue<QuotaCount> {
     }
 
     public static QuotaCount count(long value) {
-        return new QuotaCount(Optional.of(value));
+        return count(Optional.of(value));
+    }
+
+    public static QuotaCount count(Optional<Long> value) {
+        return new QuotaCount(value);
     }
 
     private final Optional<Long> value;

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaSize.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaSize.java b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaSize.java
index c8fb1a0..4d16e52 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaSize.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/quota/QuotaSize.java
@@ -32,7 +32,11 @@ public class QuotaSize implements QuotaValue<QuotaSize> {
     }
 
     public static QuotaSize size(long value) {
-        return new QuotaSize(Optional.of(value));
+        return size(Optional.of(value));
+    }
+
+    public static QuotaSize size(Optional<Long> value) {
+        return new QuotaSize(value);
     }
 
     private final Optional<Long> value;

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/pom.xml
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/pom.xml b/mailbox/plugin/quota-mailing-cassandra/pom.xml
new file mode 100644
index 0000000..38dbda2
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/pom.xml
@@ -0,0 +1,135 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>apache-james-mailbox</artifactId>
+        <groupId>org.apache.james</groupId>
+        <version>3.1.0-SNAPSHOT</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>quota-mailing-cassandra</artifactId>
+    <name>Apache James :: Mailbox :: Plugin :: Quota Mailing :: Cassandra</name>
+    <description>Apache James Mailbox Cassandra implementation of Quota mailing listener</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-backends-cassandra</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-backends-cassandra</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-quota-mailing</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-quota-mailing</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-store</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-mailet-base</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-data-memory</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-jdk8</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>net.javacrumbs.json-unit</groupId>
+            <artifactId>json-unit</artifactId>
+            <version>1.5.5</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>net.javacrumbs.json-unit</groupId>
+            <artifactId>json-unit-fluent</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>nl.jqno.equalsverifier</groupId>
+            <artifactId>equalsverifier</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-launcher</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>testcontainers</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStore.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStore.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStore.java
new file mode 100644
index 0000000..61c5a06
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStore.java
@@ -0,0 +1,62 @@
+/****************************************************************
+ * 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.eventsourcing.cassandra;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.james.eventsourcing.AggregateId;
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.EventStore;
+
+import com.google.common.base.Preconditions;
+
+public class CassandraEventStore implements EventStore {
+
+    private final EventStoreDao eventStoreDao;
+
+    @Inject
+    public CassandraEventStore(EventStoreDao eventStoreDao) {
+        this.eventStoreDao = eventStoreDao;
+    }
+
+    @Override
+    public void appendAll(List<Event> events) {
+        if (events.isEmpty()) {
+            return;
+        }
+        doAppendAll(events);
+    }
+
+    public void doAppendAll(List<Event> events) {
+        Preconditions.checkArgument(Event.belongsToSameAggregate(events));
+
+        boolean success = eventStoreDao.appendAll(events).join();
+        if (!success) {
+            throw new EventStoreFailedException();
+        }
+    }
+
+    @Override
+    public History getEventsOfAggregate(AggregateId aggregateId) {
+        return eventStoreDao.getEventsOfAggregate(aggregateId);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreModule.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreModule.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreModule.java
new file mode 100644
index 0000000..ed15cb2
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreModule.java
@@ -0,0 +1,62 @@
+/****************************************************************
+ * 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.eventsourcing.cassandra;
+
+import java.util.List;
+
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.backends.cassandra.components.CassandraTable;
+import org.apache.james.backends.cassandra.components.CassandraType;
+import org.apache.james.backends.cassandra.utils.CassandraConstants;
+
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.schemabuilder.SchemaBuilder;
+import com.google.common.collect.ImmutableList;
+
+public class CassandraEventStoreModule implements CassandraModule {
+    private final List<CassandraTable> tables;
+    private final List<CassandraType> types;
+
+    public CassandraEventStoreModule() {
+        tables = ImmutableList.of(
+            new CassandraTable(CassandraEventStoreTable.EVENTS_TABLE,
+                SchemaBuilder.createTable(CassandraEventStoreTable.EVENTS_TABLE)
+                    .ifNotExists()
+                    .addPartitionKey(CassandraEventStoreTable.AGGREGATE_ID, DataType.varchar())
+                    .addClusteringColumn(CassandraEventStoreTable.EVENT_ID, DataType.cint())
+                    .addColumn(CassandraEventStoreTable.EVENT, DataType.text())
+                    .withOptions()
+                    .comment("Store events of a EventSourcing aggregate")
+                    .caching(SchemaBuilder.KeyCaching.ALL,
+                            SchemaBuilder.rows(CassandraConstants.DEFAULT_CACHED_ROW_PER_PARTITION))));
+        types = ImmutableList.of();
+    }
+
+    @Override
+    public List<CassandraTable> moduleTables() {
+        return tables;
+    }
+
+    @Override
+    public List<CassandraType> moduleTypes() {
+        return types;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreTable.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreTable.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreTable.java
new file mode 100644
index 0000000..c90b81e
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreTable.java
@@ -0,0 +1,27 @@
+/****************************************************************
+ * 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.eventsourcing.cassandra;
+
+public interface CassandraEventStoreTable {
+    String EVENTS_TABLE = "eventStore";
+    String AGGREGATE_ID = "aggregateId";
+    String EVENT = "event";
+    String EVENT_ID = "eventId";
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/EventStoreDao.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/EventStoreDao.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/EventStoreDao.java
new file mode 100644
index 0000000..2518f02
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/EventStoreDao.java
@@ -0,0 +1,122 @@
+/****************************************************************
+ * 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.eventsourcing.cassandra;
+
+import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+import static org.apache.james.eventsourcing.cassandra.CassandraEventStoreTable.AGGREGATE_ID;
+import static org.apache.james.eventsourcing.cassandra.CassandraEventStoreTable.EVENT;
+import static org.apache.james.eventsourcing.cassandra.CassandraEventStoreTable.EVENTS_TABLE;
+import static org.apache.james.eventsourcing.cassandra.CassandraEventStoreTable.EVENT_ID;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import javax.inject.Inject;
+
+import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.eventsourcing.AggregateId;
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.EventStore;
+
+import com.datastax.driver.core.BatchStatement;
+import com.datastax.driver.core.BoundStatement;
+import com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.github.steveash.guavate.Guavate;
+
+public class EventStoreDao {
+    private final CassandraUtils cassandraUtils;
+    private final CassandraAsyncExecutor cassandraAsyncExecutor;
+    private final PreparedStatement insert;
+    private final PreparedStatement select;
+    private final JsonEventSerializer jsonEventSerializer;
+
+    @Inject
+    public EventStoreDao(Session session, CassandraUtils cassandraUtils, JsonEventSerializer jsonEventSerializer) {
+        this.cassandraUtils = cassandraUtils;
+        this.cassandraAsyncExecutor = new CassandraAsyncExecutor(session);
+        this.jsonEventSerializer = jsonEventSerializer;
+        this.insert = prepareInsert(session);
+        this.select = prepareSelect(session);
+    }
+
+    private PreparedStatement prepareInsert(Session session) {
+        return session.prepare(insertInto(EVENTS_TABLE)
+            .value(AGGREGATE_ID, bindMarker(AGGREGATE_ID))
+            .value(EVENT_ID, bindMarker(EVENT_ID))
+            .value(EVENT, bindMarker(EVENT))
+            .ifNotExists());
+    }
+
+    private PreparedStatement prepareSelect(Session session) {
+        return session.prepare(select()
+            .from(EVENTS_TABLE)
+            .where(eq(AGGREGATE_ID, bindMarker(AGGREGATE_ID))));
+    }
+
+    public CompletableFuture<Boolean> appendAll(List<Event> events) {
+        BatchStatement batch = new BatchStatement();
+        events.forEach(event -> batch.add(insertEvent(event)));
+        return cassandraAsyncExecutor.executeReturnApplied(batch);
+    }
+
+    private BoundStatement insertEvent(Event event) {
+        try {
+            return insert
+                .bind()
+                .setString(AGGREGATE_ID, event.getAggregateId().asAggregateKey())
+                .setInt(EVENT_ID, event.eventId().serialize())
+                .setString(EVENT, jsonEventSerializer.serialize(event));
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public EventStore.History getEventsOfAggregate(AggregateId aggregateId) {
+        return toHistory(
+            cassandraAsyncExecutor.execute(
+                select.bind()
+                    .setString(AGGREGATE_ID, aggregateId.asAggregateKey()))
+                .join());
+    }
+
+    private EventStore.History toHistory(ResultSet resultSet) {
+        List<Event> events = cassandraUtils.convertToStream(resultSet)
+            .map(this::toEvent)
+            .collect(Guavate.toImmutableList());
+        return EventStore.History.of(events);
+    }
+
+    private Event toEvent(Row row) {
+        try {
+            return jsonEventSerializer.deserialize(row.getString(EVENT));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializer.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializer.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializer.java
new file mode 100644
index 0000000..bf3a5dc
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializer.java
@@ -0,0 +1,98 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.cassandra;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+
+import javax.inject.Inject;
+
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.cassandra.dto.EventDTO;
+import org.apache.james.eventsourcing.cassandra.dto.EventDTOModule;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+import com.github.steveash.guavate.Guavate;
+import com.google.common.collect.ImmutableSet;
+
+public class JsonEventSerializer {
+    public static class UnknownEventException extends RuntimeException {
+        public UnknownEventException(String message) {
+            super(message);
+        }
+    }
+
+    private final Map<Class<? extends Event>, EventDTOModule> eventClassToModule;
+    private final Map<String, EventDTOModule> typeToModule;
+    private final ObjectMapper objectMapper;
+
+    @Inject
+    public JsonEventSerializer(Set<EventDTOModule> modules) {
+        objectMapper = new ObjectMapper();
+        objectMapper.registerModule(new Jdk8Module());
+        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
+
+        typeToModule = modules.stream()
+            .collect(Guavate.toImmutableMap(
+                EventDTOModule::getType,
+                Function.identity()));
+
+        eventClassToModule = modules.stream()
+            .collect(Guavate.toImmutableMap(
+                EventDTOModule::getEventClass,
+                Function.identity()));
+    }
+    
+    public JsonEventSerializer(EventDTOModule... modules) {
+        this(ImmutableSet.copyOf(modules));
+    }
+
+    public String serialize(Event event) throws JsonProcessingException {
+        Object dto = Optional.ofNullable(eventClassToModule.get(event.getClass()))
+            .orElseThrow(() -> new UnknownEventException("unknown event class " + event.getClass()))
+            .toDTO(event);
+        return objectMapper.writeValueAsString(dto);
+    }
+
+    public Event deserialize(String value) throws IOException {
+        JsonNode jsonNode = objectMapper.readTree(value);
+
+        String type = jsonNode.path("type").asText();
+
+        EventDTO dto = objectMapper.readValue(
+            objectMapper.treeAsTokens(jsonNode),
+            retrieveDTOClass(type));
+        return dto.toEvent();
+    }
+
+    public Class<? extends EventDTO> retrieveDTOClass(String type) {
+        return Optional.ofNullable(typeToModule.get(type))
+            .map(EventDTOModule::getDTOClass)
+            .orElseThrow(() -> new UnknownEventException("unknown event type " + type));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/dto/EventDTO.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/dto/EventDTO.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/dto/EventDTO.java
new file mode 100644
index 0000000..4616248
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/dto/EventDTO.java
@@ -0,0 +1,26 @@
+/****************************************************************
+ * 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.eventsourcing.cassandra.dto;
+
+import org.apache.james.eventsourcing.Event;
+
+public interface EventDTO {
+    Event toEvent();
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/dto/EventDTOModule.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/dto/EventDTOModule.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/dto/EventDTOModule.java
new file mode 100644
index 0000000..d86d1d7
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/eventsourcing/cassandra/dto/EventDTOModule.java
@@ -0,0 +1,32 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.eventsourcing.cassandra.dto;
+
+import org.apache.james.eventsourcing.Event;
+
+public interface EventDTOModule {
+    String getType();
+
+    Class<? extends EventDTO> getDTOClass();
+
+    Class<? extends Event> getEventClass();
+
+    EventDTO toDTO(Event event);
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/HistoryEvolutionDTO.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/HistoryEvolutionDTO.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/HistoryEvolutionDTO.java
new file mode 100644
index 0000000..2d1dda1
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/HistoryEvolutionDTO.java
@@ -0,0 +1,98 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.quota.cassandra.dto;
+
+import java.time.Instant;
+import java.util.Optional;
+
+import org.apache.james.mailbox.quota.model.HistoryEvolution;
+import org.apache.james.mailbox.quota.model.QuotaThreshold;
+import org.apache.james.mailbox.quota.model.QuotaThresholdChange;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Preconditions;
+import com.google.common.primitives.Booleans;
+
+class HistoryEvolutionDTO {
+
+    public static HistoryEvolutionDTO toDto(HistoryEvolution historyEvolution) {
+        return new HistoryEvolutionDTO(
+            historyEvolution.getThresholdHistoryChange(),
+            historyEvolution.getRecentness(),
+            historyEvolution.getThresholdChange()
+                .map(QuotaThresholdChange::getQuotaThreshold)
+                .map(QuotaThreshold::getQuotaOccupationRatio),
+            historyEvolution.getThresholdChange()
+                .map(QuotaThresholdChange::getInstant)
+                .map(Instant::toEpochMilli));
+    }
+
+    private final HistoryEvolution.HistoryChangeType change;
+    private final Optional<HistoryEvolution.HighestThresholdRecentness> recentness;
+    private final Optional<Double> threshold;
+    private final Optional<Long> instant;
+
+    @JsonCreator
+    public HistoryEvolutionDTO(
+            @JsonProperty("changeType") HistoryEvolution.HistoryChangeType change,
+            @JsonProperty("recentness") Optional<HistoryEvolution.HighestThresholdRecentness> recentness,
+            @JsonProperty("threshold") Optional<Double> threshold,
+            @JsonProperty("instant") Optional<Long> instant) {
+        this.change = change;
+        this.recentness = recentness;
+        this.threshold = threshold;
+        this.instant = instant;
+    }
+
+    public HistoryEvolution.HistoryChangeType getChange() {
+        return change;
+    }
+
+    public Optional<HistoryEvolution.HighestThresholdRecentness> getRecentness() {
+        return recentness;
+    }
+
+    public Optional<Double> getThreshold() {
+        return threshold;
+    }
+
+    public Optional<Long> getInstant() {
+        return instant;
+    }
+
+    @JsonIgnore
+    public HistoryEvolution toHistoryEvolution() {
+        Preconditions.checkState(Booleans.countTrue(
+            threshold.isPresent(), instant.isPresent()) != 1,
+            "threshold and instant needs to be both set, or both unset. Mixed states not allowed.");
+
+        Optional<QuotaThresholdChange> quotaThresholdChange = threshold
+            .map(QuotaThreshold::new)
+            .map(value -> new QuotaThresholdChange(value, Instant.ofEpochMilli(instant.get())));
+
+        return new HistoryEvolution(
+            change,
+            recentness,
+            quotaThresholdChange);
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaDTO.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaDTO.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaDTO.java
new file mode 100644
index 0000000..bf204c8
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaDTO.java
@@ -0,0 +1,73 @@
+/****************************************************************
+ * 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.quota.cassandra.dto;
+
+import java.util.Optional;
+
+import org.apache.james.mailbox.model.Quota;
+import org.apache.james.mailbox.quota.QuotaCount;
+import org.apache.james.mailbox.quota.QuotaSize;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+class QuotaDTO {
+    public static QuotaDTO from(Quota<?> quota) {
+        if (quota.getLimit().isUnlimited()) {
+            return new QuotaDTO(quota.getUsed().asLong(), Optional.empty());
+        }
+        return new QuotaDTO(quota.getUsed().asLong(), Optional.of(quota.getLimit().asLong()));
+    }
+
+    private final long used;
+    private final Optional<Long> limit;
+
+    @JsonCreator
+    private QuotaDTO(@JsonProperty("used") long used,
+                     @JsonProperty("limit") Optional<Long> limit) {
+        this.used = used;
+        this.limit = limit;
+    }
+
+    public long getUsed() {
+        return used;
+    }
+
+    public Optional<Long> getLimit() {
+        return limit;
+    }
+
+    @JsonIgnore
+    public Quota<QuotaSize> asSizeQuota() {
+        return Quota.<QuotaSize>builder()
+            .used(QuotaSize.size(used))
+            .computedLimit(QuotaSize.size(limit))
+            .build();
+    }
+
+    @JsonIgnore
+    public Quota<QuotaCount> asCountQuota() {
+        return Quota.<QuotaCount>builder()
+            .used(QuotaCount.count(used))
+            .computedLimit(QuotaCount.count(limit))
+            .build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTO.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTO.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTO.java
new file mode 100644
index 0000000..80eae8d
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTO.java
@@ -0,0 +1,110 @@
+/****************************************************************
+ * 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.quota.cassandra.dto;
+
+import org.apache.james.core.User;
+import org.apache.james.eventsourcing.EventId;
+import org.apache.james.eventsourcing.cassandra.dto.EventDTO;
+import org.apache.james.mailbox.quota.mailing.aggregates.UserQuotaThresholds;
+import org.apache.james.mailbox.quota.mailing.events.QuotaThresholdChangedEvent;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+class QuotaThresholdChangedEventDTO implements EventDTO {
+
+    @JsonIgnore
+    public static QuotaThresholdChangedEventDTO from(QuotaThresholdChangedEvent event, String type) {
+        return new QuotaThresholdChangedEventDTO(
+            type, event.eventId().serialize(),
+            event.getAggregateId().getUser().asString(),
+            QuotaDTO.from(event.getSizeQuota()),
+            QuotaDTO.from(event.getCountQuota()),
+            HistoryEvolutionDTO.toDto(event.getSizeHistoryEvolution()),
+            HistoryEvolutionDTO.toDto(event.getCountHistoryEvolution()));
+    }
+
+    private final String type;
+    private final int eventId;
+    private final String user;
+    private final QuotaDTO sizeQuota;
+    private final QuotaDTO countQuota;
+    private final HistoryEvolutionDTO sizeEvolution;
+    private final HistoryEvolutionDTO countEvolution;
+
+    @JsonCreator
+    private QuotaThresholdChangedEventDTO(
+            @JsonProperty("type") String type,
+            @JsonProperty("eventId") int eventId,
+            @JsonProperty("user") String user,
+            @JsonProperty("sizeQuota") QuotaDTO sizeQuota,
+            @JsonProperty("countQuota") QuotaDTO countQuota,
+            @JsonProperty("sizeEvolution") HistoryEvolutionDTO sizeEvolution,
+            @JsonProperty("countEvolution") HistoryEvolutionDTO countEvolution) {
+        this.type = type;
+        this.eventId = eventId;
+        this.user = user;
+        this.sizeQuota = sizeQuota;
+        this.countQuota = countQuota;
+        this.sizeEvolution = sizeEvolution;
+        this.countEvolution = countEvolution;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public long getEventId() {
+        return eventId;
+    }
+
+    public String getUser() {
+        return user;
+    }
+
+    public QuotaDTO getSizeQuota() {
+        return sizeQuota;
+    }
+
+    public QuotaDTO getCountQuota() {
+        return countQuota;
+    }
+
+    public HistoryEvolutionDTO getSizeEvolution() {
+        return sizeEvolution;
+    }
+
+    public HistoryEvolutionDTO getCountEvolution() {
+        return countEvolution;
+    }
+
+    @JsonIgnore
+    @Override
+    public QuotaThresholdChangedEvent toEvent() {
+        return new QuotaThresholdChangedEvent(
+            EventId.fromSerialized(eventId),
+            sizeEvolution.toHistoryEvolution(),
+            countEvolution.toHistoryEvolution(),
+            sizeQuota.asSizeQuota(),
+            countQuota.asCountQuota(),
+            UserQuotaThresholds.Id.from(User.fromUsername(user)));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTOModule.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTOModule.java b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTOModule.java
new file mode 100644
index 0000000..328cb09
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/main/java/org/apache/james/mailbox/quota/cassandra/dto/QuotaThresholdChangedEventDTOModule.java
@@ -0,0 +1,54 @@
+/****************************************************************
+ * 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.quota.cassandra.dto;
+
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.cassandra.dto.EventDTO;
+import org.apache.james.eventsourcing.cassandra.dto.EventDTOModule;
+import org.apache.james.mailbox.quota.mailing.events.QuotaThresholdChangedEvent;
+
+import com.google.common.base.Preconditions;
+
+public class QuotaThresholdChangedEventDTOModule implements EventDTOModule {
+    private static final String QUOTA_THRESHOLD_CHANGE = "quota-threshold-change";
+
+    @Override
+    public String getType() {
+        return QUOTA_THRESHOLD_CHANGE;
+    }
+
+    @Override
+    public Class<? extends EventDTO> getDTOClass() {
+        return QuotaThresholdChangedEventDTO.class;
+    }
+
+    @Override
+    public Class<? extends Event> getEventClass() {
+        return QuotaThresholdChangedEvent.class;
+    }
+
+    @Override
+    public EventDTO toDTO(Event event) {
+        Preconditions.checkArgument(event instanceof QuotaThresholdChangedEvent);
+        return QuotaThresholdChangedEventDTO.from(
+            (QuotaThresholdChangedEvent) event,
+            QUOTA_THRESHOLD_CHANGE);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventSourcingSystemTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventSourcingSystemTest.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventSourcingSystemTest.java
new file mode 100644
index 0000000..bee6e88
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventSourcingSystemTest.java
@@ -0,0 +1,28 @@
+/****************************************************************
+ * 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.eventsourcing.cassandra;
+
+import org.apache.james.eventsourcing.EventSourcingSystemTest;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(CassandraEventStoreExtension.class)
+public class CassandraEventSourcingSystemTest implements EventSourcingSystemTest {
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreExtension.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreExtension.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreExtension.java
new file mode 100644
index 0000000..1b0066f
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreExtension.java
@@ -0,0 +1,86 @@
+/****************************************************************
+ * 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.eventsourcing.cassandra;
+
+import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.backends.cassandra.DockerCassandraExtension;
+import org.apache.james.backends.cassandra.DockerCassandraExtension.DockerCassandra;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.eventsourcing.EventStore;
+import org.apache.james.eventsourcing.cassandra.dto.TestEventDTOModule;
+import org.apache.james.mailbox.quota.cassandra.dto.QuotaThresholdChangedEventDTOModule;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.ParameterResolver;
+
+public class CassandraEventStoreExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback, ParameterResolver {
+    private final DockerCassandraExtension dockerCassandraExtension;
+    private CassandraCluster cassandra;
+    private DockerCassandra dockerCassandra;
+    private EventStoreDao eventStoreDao;
+
+    public CassandraEventStoreExtension() {
+        dockerCassandraExtension = new DockerCassandraExtension();
+    }
+
+    @Override
+    public void beforeAll(ExtensionContext context) throws Exception {
+        dockerCassandraExtension.beforeAll(context);
+        dockerCassandra = dockerCassandraExtension.getDockerCassandra();
+    }
+
+    @Override
+    public void afterAll(ExtensionContext context) throws Exception {
+        dockerCassandraExtension.afterAll(context);
+    }
+
+    @Override
+    public void beforeEach(ExtensionContext context) {
+        cassandra = CassandraCluster.create(
+                new CassandraEventStoreModule(), dockerCassandra.getIp(), dockerCassandra.getBindingPort());
+
+        JsonEventSerializer jsonEventSerializer = new JsonEventSerializer(
+            new QuotaThresholdChangedEventDTOModule(),
+            new TestEventDTOModule());
+
+        eventStoreDao = new EventStoreDao(cassandra.getConf(), CassandraUtils.WITH_DEFAULT_CONFIGURATION,
+            jsonEventSerializer);
+    }
+
+    @Override
+    public void afterEach(ExtensionContext context) {
+        cassandra.close();
+    }
+
+    @Override
+    public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        return (parameterContext.getParameter().getType() == EventStore.class);
+    }
+
+    @Override
+    public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        return new CassandraEventStore(eventStoreDao);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreTest.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreTest.java
new file mode 100644
index 0000000..314b185
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/CassandraEventStoreTest.java
@@ -0,0 +1,28 @@
+/****************************************************************
+ * 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.eventsourcing.cassandra;
+
+import org.apache.james.eventsourcing.EventStoreTest;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(CassandraEventStoreExtension.class)
+class CassandraEventStoreTest implements EventStoreTest {
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializerTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializerTest.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializerTest.java
new file mode 100644
index 0000000..893647b
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializerTest.java
@@ -0,0 +1,67 @@
+/****************************************************************
+ * 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.eventsourcing.cassandra;
+
+import static net.javacrumbs.jsonunit.fluent.JsonFluentAssert.assertThatJson;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import org.apache.james.eventsourcing.EventId;
+import org.apache.james.eventsourcing.TestAggregateId;
+import org.apache.james.eventsourcing.TestEvent;
+import org.apache.james.eventsourcing.cassandra.dto.TestEventDTOModule;
+import org.junit.jupiter.api.Test;
+
+class JsonEventSerializerTest {
+    public static final String TEST_EVENT_JSON = "{\"type\":\"TestType\",\"data\":\"first\",\"eventId\":0,\"aggregate\":1}";
+    public static final TestEvent TEST_EVENT = new TestEvent(
+        EventId.fromSerialized(0),
+        TestAggregateId.testId(1),
+        "first");
+
+    @Test
+    void shouldDeserializeKnownEvent() throws Exception {
+        assertThat(new JsonEventSerializer(new TestEventDTOModule())
+            .deserialize(TEST_EVENT_JSON))
+            .isEqualTo(TEST_EVENT);
+    }
+
+    @Test
+    void shouldThrowWhenDeserializeUnknownEvent() {
+        assertThatThrownBy(() -> new JsonEventSerializer()
+            .deserialize(TEST_EVENT_JSON))
+            .isInstanceOf(JsonEventSerializer.UnknownEventException.class);
+    }
+
+    @Test
+    void shouldSerializeKnownEvent() throws Exception {
+        assertThatJson(new JsonEventSerializer(new TestEventDTOModule())
+            .serialize(TEST_EVENT))
+            .isEqualTo(TEST_EVENT_JSON);
+    }
+
+    @Test
+    void shouldThrowWhenSerializeUnknownEvent() {
+        assertThatThrownBy(() -> new JsonEventSerializer()
+            .serialize(TEST_EVENT))
+            .isInstanceOf(JsonEventSerializer.UnknownEventException.class);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/TestEventDTO.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/TestEventDTO.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/TestEventDTO.java
new file mode 100644
index 0000000..529d8a9
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/TestEventDTO.java
@@ -0,0 +1,73 @@
+/****************************************************************
+ * 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.eventsourcing.cassandra.dto;
+
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.EventId;
+import org.apache.james.eventsourcing.TestAggregateId;
+import org.apache.james.eventsourcing.TestEvent;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class TestEventDTO implements EventDTO {
+    private final String type;
+    private final String data;
+    private final int eventId;
+    private final int aggregate;
+
+    @JsonCreator
+    public TestEventDTO(
+            @JsonProperty("type") String type,
+            @JsonProperty("data") String data,
+            @JsonProperty("eventId") int eventId,
+            @JsonProperty("aggregate") int aggregate) {
+        this.type = type;
+        this.data = data;
+        this.eventId = eventId;
+        this.aggregate = aggregate;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public String getData() {
+        return data;
+    }
+
+    public long getEventId() {
+        return eventId;
+    }
+
+    public int getAggregate() {
+        return aggregate;
+    }
+
+    @JsonIgnore
+    @Override
+    public Event toEvent() {
+        return new TestEvent(
+            EventId.fromSerialized(eventId),
+            TestAggregateId.testId(aggregate),
+            data);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/TestEventDTOModule.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/TestEventDTOModule.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/TestEventDTOModule.java
new file mode 100644
index 0000000..6b46268
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/TestEventDTOModule.java
@@ -0,0 +1,56 @@
+/****************************************************************
+ * 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.eventsourcing.cassandra.dto;
+
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.TestEvent;
+import org.testcontainers.shaded.com.google.common.base.Preconditions;
+
+public class TestEventDTOModule implements EventDTOModule {
+
+    public static final String TEST_TYPE = "TestType";
+
+    @Override
+    public String getType() {
+        return TEST_TYPE;
+    }
+
+    @Override
+    public Class<? extends EventDTO> getDTOClass() {
+        return TestEventDTO.class;
+    }
+
+    @Override
+    public Class<? extends Event> getEventClass() {
+        return TestEvent.class;
+    }
+
+    @Override
+    public EventDTO toDTO(Event event) {
+        Preconditions.checkArgument(event instanceof TestEvent);
+
+        TestEvent testEvent = (TestEvent) event;
+        return new TestEventDTO(
+            TEST_TYPE,
+            testEvent.getData(),
+            testEvent.eventId().serialize(),
+            testEvent.getAggregateId().getId());
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
new file mode 100644
index 0000000..a42725a
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/dto/DTOTest.java
@@ -0,0 +1,147 @@
+/****************************************************************
+ * 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.quota.cassandra.dto;
+
+import static net.javacrumbs.jsonunit.fluent.JsonFluentAssert.assertThatJson;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.james.core.User;
+import org.apache.james.eventsourcing.EventId;
+import org.apache.james.eventsourcing.cassandra.JsonEventSerializer;
+import org.apache.james.mailbox.model.Quota;
+import org.apache.james.mailbox.quota.QuotaCount;
+import org.apache.james.mailbox.quota.QuotaSize;
+import org.apache.james.mailbox.quota.mailing.aggregates.UserQuotaThresholds;
+import org.apache.james.mailbox.quota.mailing.events.QuotaThresholdChangedEvent;
+import org.apache.james.mailbox.quota.model.HistoryEvolution;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+
+class DTOTest {
+
+    public static final Quota<QuotaSize> SIZE_QUOTA = Quota.<QuotaSize>builder().used(QuotaSize.size(23)).computedLimit(QuotaSize.size(33)).build();
+    public static final Quota<QuotaCount> COUNT_QUOTA = Quota.<QuotaCount>builder().used(QuotaCount.count(12)).computedLimit(QuotaCount.count(45)).build();
+    public static final QuotaThresholdChangedEvent EVENT = new QuotaThresholdChangedEvent(
+        EventId.first(),
+        HistoryEvolution.noChanges(),
+        HistoryEvolution.noChanges(),
+        SIZE_QUOTA,
+        COUNT_QUOTA,
+        UserQuotaThresholds.Id.from(User.fromUsername("foo@bar.com")));
+
+    public static final String EVENT_JSON = "{" +
+        " \"type\": \"quota-threshold-change\"," +
+        " \"eventId\": 0," +
+        " \"user\": \"foo@bar.com\"," +
+        " \"sizeQuota\": {" +
+        "   \"used\": 23," +
+        "   \"limit\": 33" +
+        " }," +
+        " \"countQuota\": {" +
+        "   \"used\": 12," +
+        "   \"limit\": 45" +
+        " }," +
+        " \"sizeEvolution\": {" +
+        "   \"change\": \"NoChange\"," +
+        "   \"threshold\": null," +
+        "   \"instant\": null," +
+        "   \"recentness\": null" +
+        " }," +
+        " \"countEvolution\": {" +
+        "   \"change\": \"NoChange\"," +
+        "   \"threshold\": null," +
+        "   \"instant\": null," +
+        "   \"recentness\": null" +
+        " }" +
+        "}";
+
+    public static final String COUNT_QUOTA_JSON = "{" +
+        "   \"used\": 12," +
+        "   \"limit\": 45" +
+        " }";
+
+    public static final String NO_CHANGES_JSON = "{" +
+        "  \"change\":\"NoChange\"" +
+        "}";
+
+    private ObjectMapper objectMapper;
+
+    @BeforeEach
+    public void setUp() {
+        objectMapper = new ObjectMapper();
+        objectMapper.registerModule(new Jdk8Module());
+        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
+    }
+
+    @Test
+    void shouldSerializeQuotaDTO() throws Exception {
+        assertThatJson(objectMapper.writeValueAsString(QuotaDTO.from(COUNT_QUOTA)))
+            .isEqualTo(COUNT_QUOTA_JSON);
+    }
+
+    @Test
+    void shouldDeserializeQuotaDTO() throws Exception {
+        assertThat(objectMapper.readValue(COUNT_QUOTA_JSON, QuotaDTO.class).asCountQuota())
+            .isEqualTo(COUNT_QUOTA);
+    }
+
+    @Test
+    void shouldSerializeHistoryEvolutionDTO() throws Exception {
+        assertThatJson(objectMapper.writeValueAsString(HistoryEvolutionDTO.toDto(
+            HistoryEvolution.noChanges())))
+            .isEqualTo(NO_CHANGES_JSON);
+    }
+
+    @Test
+    void shouldDeserializeHistoryEvolutionDTO() throws Exception {
+        assertThat(objectMapper.readValue(NO_CHANGES_JSON, HistoryEvolutionDTO.class)
+            .toHistoryEvolution())
+            .isEqualTo(HistoryEvolution.noChanges());
+    }
+
+    @Test
+    void shouldSerializeQuotaThresholdChangedEventDTO() throws Exception {
+        assertThatJson(objectMapper.writeValueAsString(
+            new QuotaThresholdChangedEventDTOModule().toDTO(EVENT)))
+            .isEqualTo(EVENT_JSON);
+    }
+
+    @Test
+    void shouldDeserializeQuotaThresholdChangedEventDTO() throws Exception {
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.registerModule(new Jdk8Module());
+
+        assertThat(objectMapper.readValue(EVENT_JSON, QuotaThresholdChangedEventDTO.class)
+            .toEvent())
+            .isEqualTo(EVENT);
+    }
+
+    @Test
+    void shouldSerializeQuotaThresholdChangedEvent() throws Exception {
+        assertThatJson(new JsonEventSerializer(new QuotaThresholdChangedEventDTOModule())
+            .serialize(EVENT))
+            .isEqualTo(EVENT_JSON);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraQuotaMailingListenersIntegrationTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraQuotaMailingListenersIntegrationTest.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraQuotaMailingListenersIntegrationTest.java
new file mode 100644
index 0000000..3ea097a
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/mailbox/quota/cassandra/listeners/CassandraQuotaMailingListenersIntegrationTest.java
@@ -0,0 +1,29 @@
+/****************************************************************
+ * 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.quota.cassandra.listeners;
+
+import org.apache.james.eventsourcing.cassandra.CassandraEventStoreExtension;
+import org.apache.james.mailbox.quota.mailing.listeners.QuotaThresholdMailingIntegrationTest;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(CassandraEventStoreExtension.class)
+public class CassandraQuotaMailingListenersIntegrationTest implements QuotaThresholdMailingIntegrationTest {
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing-memory/src/main/java/org/apache/james/eventsource/InMemoryEventStore.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-memory/src/main/java/org/apache/james/eventsource/InMemoryEventStore.java b/mailbox/plugin/quota-mailing-memory/src/main/java/org/apache/james/eventsource/InMemoryEventStore.java
index 91cdbb9..11c8e46 100644
--- a/mailbox/plugin/quota-mailing-memory/src/main/java/org/apache/james/eventsource/InMemoryEventStore.java
+++ b/mailbox/plugin/quota-mailing-memory/src/main/java/org/apache/james/eventsource/InMemoryEventStore.java
@@ -54,21 +54,14 @@ public class InMemoryEventStore implements EventStore {
 
     private AggregateId getAggregateId(List<? extends Event> events) {
         Preconditions.checkArgument(!events.isEmpty());
-        Preconditions.checkArgument(belongsToSameAggregate(events));
+        Preconditions.checkArgument(Event.belongsToSameAggregate(events));
+
         return events.stream()
             .map(Event::getAggregateId)
             .findFirst()
             .get();
     }
 
-    private boolean belongsToSameAggregate(List<? extends Event> events) {
-        return events.stream()
-            .map(Event::getAggregateId)
-            .distinct()
-            .limit(2)
-            .count() <= 1;
-    }
-
     private void appendToEmptyHistory(AggregateId aggregateId, List<Event> events) {
         History newHistory = History.of(events);
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/Event.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/Event.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/Event.java
index 7b3bc00..2b31374 100644
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/Event.java
+++ b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/Event.java
@@ -19,8 +19,18 @@
 
 package org.apache.james.eventsourcing;
 
+import java.util.List;
+
 public interface Event extends Comparable<Event> {
 
+    static boolean belongsToSameAggregate(List<? extends Event> events) {
+        return events.stream()
+            .map(Event::getAggregateId)
+            .distinct()
+            .limit(2)
+            .count() == 1;
+    }
+
     EventId eventId();
 
     AggregateId getAggregateId();
@@ -29,4 +39,5 @@ public interface Event extends Comparable<Event> {
     default int compareTo(Event o) {
         return eventId().compareTo(o.eventId());
     }
+
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/events/QuotaThresholdChangedEvent.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/events/QuotaThresholdChangedEvent.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/events/QuotaThresholdChangedEvent.java
index 3c21a3f..1c036f7 100644
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/events/QuotaThresholdChangedEvent.java
+++ b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/events/QuotaThresholdChangedEvent.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.mailbox.quota.mailing.events;
 
+import java.util.Objects;
+
 import org.apache.james.eventsourcing.Event;
 import org.apache.james.eventsourcing.EventId;
 import org.apache.james.mailbox.model.Quota;
@@ -71,5 +73,23 @@ public class QuotaThresholdChangedEvent implements Event {
         return aggregateId;
     }
 
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof QuotaThresholdChangedEvent) {
+            QuotaThresholdChangedEvent that = (QuotaThresholdChangedEvent) o;
+
+            return Objects.equals(this.eventId, that.eventId)
+                && Objects.equals(this.sizeHistoryEvolution, that.sizeHistoryEvolution)
+                && Objects.equals(this.countHistoryEvolution, that.countHistoryEvolution)
+                && Objects.equals(this.sizeQuota, that.sizeQuota)
+                && Objects.equals(this.countQuota, that.countQuota)
+                && Objects.equals(this.aggregateId, that.aggregateId);
+        }
+        return false;
+    }
 
+    @Override
+    public final int hashCode() {
+        return Objects.hash(eventId, sizeHistoryEvolution, countHistoryEvolution, sizeQuota, countQuota, aggregateId);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/c3a1bda2/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/HistoryEvolution.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/HistoryEvolution.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/HistoryEvolution.java
index e7cdf14..7f71025 100644
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/HistoryEvolution.java
+++ b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/model/HistoryEvolution.java
@@ -22,13 +22,14 @@ package org.apache.james.mailbox.quota.model;
 import java.util.Objects;
 import java.util.Optional;
 
+import com.google.common.base.MoreObjects;
+
 public class HistoryEvolution {
 
     public static HistoryEvolution noChanges() {
         return new HistoryEvolution(HistoryChangeType.NoChange,
             Optional.empty(),
-            Optional.empty()
-            );
+            Optional.empty());
     }
 
     public static HistoryEvolution lowerThresholdReached(QuotaThresholdChange currentThreshold) {
@@ -58,7 +59,7 @@ public class HistoryEvolution {
     private final Optional<HighestThresholdRecentness> recentness;
     private final Optional<QuotaThresholdChange> thresholdChange;
 
-    private HistoryEvolution(HistoryChangeType thresholdHistoryChange, Optional<HighestThresholdRecentness> recentness, Optional<QuotaThresholdChange> thresholdChange) {
+    public HistoryEvolution(HistoryChangeType thresholdHistoryChange, Optional<HighestThresholdRecentness> recentness, Optional<QuotaThresholdChange> thresholdChange) {
         this.thresholdHistoryChange = thresholdHistoryChange;
         this.recentness = recentness;
         this.thresholdChange = thresholdChange;
@@ -82,6 +83,10 @@ public class HistoryEvolution {
         return thresholdHistoryChange;
     }
 
+    public Optional<HighestThresholdRecentness> getRecentness() {
+        return recentness;
+    }
+
     @Override
     public final boolean equals(Object o) {
         if (o instanceof HistoryEvolution) {
@@ -99,13 +104,12 @@ public class HistoryEvolution {
         return Objects.hash(thresholdHistoryChange, recentness, thresholdChange);
     }
 
-
     @Override
     public String toString() {
-        return "HistoryEvolution{" +
-            "thresholdHistoryChange=" + thresholdHistoryChange +
-            ", recentness=" + recentness +
-            ", thresholdChange=" + thresholdChange +
-            '}';
+        return MoreObjects.toStringHelper(this)
+            .add("thresholdHistoryChange", thresholdHistoryChange)
+            .add("recentness", recentness)
+            .add("thresholdChange", thresholdChange)
+            .toString();
     }
 }


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


[02/15] james-project git commit: JAMES-2392 Use Apache mirrors

Posted by bt...@apache.org.
JAMES-2392 Use Apache mirrors


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/8542f4a0
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/8542f4a0
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/8542f4a0

Branch: refs/heads/master
Commit: 8542f4a027709470a9b969cbb0534622f00f1859
Parents: 96bdad6
Author: benwa <bt...@linagora.com>
Authored: Wed May 9 11:25:00 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu May 10 09:12:25 2018 +0700

----------------------------------------------------------------------
 src/site/xdoc/download.xml | 158 ++++++++++++++++++++--------------------
 1 file changed, 79 insertions(+), 79 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/8542f4a0/src/site/xdoc/download.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/download.xml b/src/site/xdoc/download.xml
index e5c4e9c..016926d 100644
--- a/src/site/xdoc/download.xml
+++ b/src/site/xdoc/download.xml
@@ -111,10 +111,10 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
       files using the PGP or SHA-1 signatures.</p>
       
       <p>The PGP signatures can be verified using PGP or GPG.  First
-      download the <a href="https://www.apache.org/dist/james/KEYS">KEYS</a>
+      download the <a href="https://www.apache.org/dyn/closer.lua/james/KEYS">KEYS</a>
       as well as the <code>asc</code> signature file for the particular
       distribution.  Make sure you get these files from the <a
-      href="https://www.apache.org/dist/james/">main distribution
+      href="https://www.apache.org/dyn/closer.lua/james/">main distribution
       directory</a>, rather than from a mirror. Then verify the signatures
       using</p>
       
@@ -159,14 +159,14 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
 
       <ul>
         <li>Source code (ZIP Format):
-          <a href="https://www.apache.org/dist/james/server/james-server-sources-3.0.1.zip">apache-james-3.0.1-app.zip</a>
-          [<a href="https://www.apache.org/dist/james/server/james-server-sources-3.0.1.zip.sha1">SHA-1</a>]
-          [<a href="https://www.apache.org/dist/james/server/james-server-sources-3.0.1.zip.asc">PGP</a>]</li>
+          <a href="https://www.apache.org/dyn/closer.lua/james/server/james-server-sources-3.0.1.zip">apache-james-3.0.1-app.zip</a>
+          [<a href="https://www.apache.org/dyn/closer.lua/james/server/james-server-sources-3.0.1.zip.sha1">SHA-1</a>]
+          [<a href="https://www.apache.org/dyn/closer.lua/james/server/james-server-sources-3.0.1.zip.asc">PGP</a>]</li>
 
         <li>Binary (ZIP Format):
-          <a href="https://www.apache.org/dist/james/server/james-server-app-3.0.1-app.zip">apache-james-3.0.1-app.zip</a>
-          [<a href="https://www.apache.org/dist/james/server/james-server-app-3.0.1-app.zip.sha1">SHA-1</a>]
-          [<a href="https://www.apache.org/dist/james/server/james-server-app-3.0.1-app.zip.sig">PGP</a>]
+          <a href="https://www.apache.org/dyn/closer.lua/james/server/james-server-app-3.0.1-app.zip">apache-james-3.0.1-app.zip</a>
+          [<a href="https://www.apache.org/dyn/closer.lua/james/server/james-server-app-3.0.1-app.zip.sha1">SHA-1</a>]
+          [<a href="https://www.apache.org/dyn/closer.lua/james/server/james-server-app-3.0.1-app.zip.sig">PGP</a>]
         </li>
 
       </ul>
@@ -200,23 +200,23 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
       <ul>
 
         <li>Source (Unix TAR): <a href="[preferred]/james/server/james-2.3.2.1-src.tar.gz">james-2.3.2.1-src.tar.gz</a>
-          [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.tar.gz.sha1">SHA-1</a>]
-          [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.tar.gz.asc">PGP</a>]
+          [<a href="https://www.apache.org/dyn/closer.lua/james/server/james-2.3.2.1-src.tar.gz.sha1">SHA-1</a>]
+          [<a href="https://www.apache.org/dyn/closer.lua/james/server/james-2.3.2.1-src.tar.gz.asc">PGP</a>]
         </li>
 
         <li>Source (ZIP Format): <a href="[preferred]/james/server/james-2.3.2.1-src.zip">james-2.3.2.1-src.zip</a>
-          [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.zip.sha1">SHA-1</a>]
-          [<a href="https://www.apache.org/dist/james/server/james-2.3.2.1-src.zip.asc">PGP</a>]
+          [<a href="https://www.apache.org/dyn/closer.lua/james/server/james-2.3.2.1-src.zip.sha1">SHA-1</a>]
+          [<a href="https://www.apache.org/dyn/closer.lua/james/server/james-2.3.2.1-src.zip.asc">PGP</a>]
         </li>
       
         <li>Binary (Unix TAR): <a href="[preferred]/james/server/james-binary-2.3.2.1.tar.gz">james-binary-2.3.2.1.tar.gz</a>
-          [<a href="https://www.apache.org/dist/james/server/james-binary-2.3.2.1.tar.gz.sha1">SHA-1</a>]
-          [<a href="https://www.apache.org/dist/james/server/james-binary-2.3.2.1.tar.gz.asc">PGP</a>]
+          [<a href="https://www.apache.org/dyn/closer.lua/james/server/james-binary-2.3.2.1.tar.gz.sha1">SHA-1</a>]
+          [<a href="https://www.apache.org/dyn/closer.lua/james/server/james-binary-2.3.2.1.tar.gz.asc">PGP</a>]
         </li>
       
         <li>Binary (ZIP Format): <a href="[preferred]/james/server/james-binary-2.3.2.1.zip">james-binary-2.3.2.1.zip</a>
-          [<a href="https://www.apache.org/dist/james/server/james-binary-2.3.2.1.zip.sha1">SHA-1</a>]
-          [<a href="https://www.apache.org/dist/james/server/james-binary-2.3.2.1.zip.asc">PGP</a>]
+          [<a href="https://www.apache.org/dyn/closer.lua/james/server/james-binary-2.3.2.1.zip.sha1">SHA-1</a>]
+          [<a href="https://www.apache.org/dyn/closer.lua/james/server/james-binary-2.3.2.1.zip.asc">PGP</a>]
         </li>
       
       </ul>
@@ -236,9 +236,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     <p>Apache Mime4J 0.8.2 is the latest stable version.</p>
 
     <p>Sources:
-      <a href="https://www.apache.org/dist/james/mime4j/0.8.2/james-mime4j-sources-0.8.2.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/james-mime4j-sources-0.8.2.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/james-mime4j-sources-0.8.2.zip.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/mime4j/0.8.2/james-mime4j-sources-0.8.2.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mime4j/0.8.2/james-mime4j-sources-0.8.2.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mime4j/0.8.2/james-mime4j-sources-0.8.2.zip.asc">PGP</a>]
     </p>
 
     <p>You can directly use the core library with maven:</p>
@@ -254,9 +254,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     </pre>
 
     <p>Direct download link:
-      <a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-core-0.8.2.jar">(Jar)</a>
-      [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-core-0.8.2.jar.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-core-0.8.2.jar.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/mime4j/0.8.2/apache-mime4j-core-0.8.2.jar">(Jar)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mime4j/0.8.2/apache-mime4j-core-0.8.2.jar.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mime4j/0.8.2/apache-mime4j-core-0.8.2.jar.asc">PGP</a>]
       </p>
 
     <p>In order to use Mime-4j DOM:</p>
@@ -272,9 +272,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     </pre>
 
     <p>Direct download link:
-      <a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-dom-0.8.2.jar">(Jar)</a>
-      [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-dom-0.8.2.jar.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-dom-0.8.2.jar.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/mime4j/0.8.2/apache-mime4j-dom-0.8.2.jar">(Jar)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mime4j/0.8.2/apache-mime4j-dom-0.8.2.jar.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mime4j/0.8.2/apache-mime4j-dom-0.8.2.jar.asc">PGP</a>]
     </p>
 
     <p>An aggregator project is also available:</p>
@@ -290,9 +290,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     </pre>
 
     <p>Direct download link:
-      <a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-0.8.2-bin.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-0.8.2-bin.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mime4j/0.8.2/apache-mime4j-0.8.2-bin.zip.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/mime4j/0.8.2/apache-mime4j-0.8.2-bin.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mime4j/0.8.2/apache-mime4j-0.8.2-bin.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mime4j/0.8.2/apache-mime4j-0.8.2-bin.zip.asc">PGP</a>]
     </p>
   
   </section>
@@ -302,9 +302,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     <p>Apache James jSPF 1.0.1 is the latest jSPF stable version.</p>
 
     <p>Sources:
-      <a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-sources-1.0.1.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-sources-1.0.1.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-sources-1.0.1.zip.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/jspf/1.0.1/apache-jspf-sources-1.0.1.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/jspf/1.0.1/apache-jspf-sources-1.0.1.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/jspf/1.0.1/apache-jspf-sources-1.0.1.zip.asc">PGP</a>]
     </p>
 
     <p>You can directly use it with maven:</p>
@@ -320,9 +320,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     </pre>
 
     <p>Direct download link:
-      <a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-1.0.1-bin.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-1.0.1-bin.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/jspf/1.0.1/apache-jspf-1.0.1-bin.zip.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/jspf/1.0.1/apache-jspf-1.0.1-bin.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/jspf/1.0.1/apache-jspf-1.0.1-bin.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/jspf/1.0.1/apache-jspf-1.0.1-bin.zip.asc">PGP</a>]
     </p>
   
   </section>
@@ -332,9 +332,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     <p>Apache James jDKIM 0.2 is the latest jDKIM stable version.</p>
 
     <p>Sources:
-      <a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-project-0.2-source-release.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-project-0.2-source-release.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-project-0.2-source-release.zip.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/jdkim/apache-jdkim-project-0.2-source-release.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/jdkim/apache-jdkim-project-0.2-source-release.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/jdkim/apache-jdkim-project-0.2-source-release.zip.asc">PGP</a>]
     </p>
 
     <p>You can directly use it with maven:</p>
@@ -350,9 +350,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     </pre>
 
     <p>Direct download link:
-      <a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-0.2-bin.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-0.2-bin.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/jdkim/apache-jdkim-0.2-bin.zip.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/jdkim/apache-jdkim-0.2-bin.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/jdkim/apache-jdkim-0.2-bin.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/jdkim/apache-jdkim-0.2-bin.zip.asc">PGP</a>]
     </p>
   
   </section>
@@ -362,9 +362,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     <p>Apache JSieve 0.7 is the latest stable version.</p>
 
     <p>Sources:
-      <a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-sources-0.7.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-sources-0.7.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-sources-0.7.zip.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/jsieve/0.7/apache-jsieve-sources-0.7.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/jsieve/0.7/apache-jsieve-sources-0.7.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/jsieve/0.7/apache-jsieve-sources-0.7.zip.asc">PGP</a>]
     </p>
 
     <p>You can directly use it with maven:</p>
@@ -380,9 +380,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     </pre>
 
     <p>Direct download link:
-      <a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-core-0.7.jar">(Jar)</a>
-      [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-core-0.7.jar.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-core-0.7.jar.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/jsieve/0.7/apache-jsieve-core-0.7.jar">(Jar)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/jsieve/0.7/apache-jsieve-core-0.7.jar.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/jsieve/0.7/apache-jsieve-core-0.7.jar.asc">PGP</a>]
     </p>
 
     <p>An aggregator project is also available:</p>
@@ -398,9 +398,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     </pre>
 
     <p>Direct download link:
-      <a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-0.7-all.tar.gz">(Tar Gz)</a>
-      [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-0.7-all.tar.gz.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/jsieve/0.7/apache-jsieve-0.7-all.tar.gz.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/jsieve/0.7/apache-jsieve-0.7-all.tar.gz">(Tar Gz)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/jsieve/0.7/apache-jsieve-0.7-all.tar.gz.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/jsieve/0.7/apache-jsieve-0.7-all.tar.gz.asc">PGP</a>]
     </p>
 
   
@@ -412,9 +412,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
 
 
     <p>Sources:
-      <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-api-sources-3.0.1.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-api-sources-3.0.1.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-api-sources-3.0.1.zip.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-james-mailet-api-sources-3.0.1.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-james-mailet-api-sources-3.0.1.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-james-mailet-api-sources-3.0.1.zip.asc">PGP</a>]
     </p>
 
     <p>You can use the mailet API using this maven dependency:</p>
@@ -430,9 +430,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     </pre>
 
     <p>Direct download link:
-      <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-api-3.0.1.jar">(Jar)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-api-3.0.1.jar.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-api-3.0.1.jar.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-mailet-api-3.0.1.jar">(Jar)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-mailet-api-3.0.1.jar.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-mailet-api-3.0.1.jar.asc">PGP</a>]
     </p>
     
   </section>
@@ -442,9 +442,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     <p>Apache Mailet Base 3.0.1 is the latest stable version.</p>
 
     <p>Sources:
-      <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-base-sources-3.0.1.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-base-sources-3.0.1.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-base-sources-3.0.1.zip.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-james-mailet-base-sources-3.0.1.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-james-mailet-base-sources-3.0.1.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-james-mailet-base-sources-3.0.1.zip.asc">PGP</a>]
     </p>
 
     <p>You can use the mailet API using this maven dependency:</p>
@@ -460,9 +460,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     </pre>
 
     <p>Direct download link:
-      <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-base-3.0.1.jar">(Jar)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-base-3.0.1.jar.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-base-3.0.1.jar.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-mailet-base-3.0.1.jar">(Jar)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-mailet-base-3.0.1.jar.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-mailet-base-3.0.1.jar.asc">PGP</a>]
     </p>
 
   </section>
@@ -472,9 +472,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     <p>Apache Mailet Standard 3.0.1 is the latest stable version. </p>
 
     <p>Sources:
-      <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-standard-sources-3.0.1.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-standard-sources-3.0.1.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-standard-sources-3.0.1.zip.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-james-mailet-standard-sources-3.0.1.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-james-mailet-standard-sources-3.0.1.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-james-mailet-standard-sources-3.0.1.zip.asc">PGP</a>]
     </p>
 
     <p>You can use mailet Standard content using this maven dependency:</p>
@@ -490,9 +490,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     </pre>
 
     <p>Direct download link:
-      <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-standard-3.0.1.jar">(Jar)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-standard-3.0.1.jar.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-standard-3.0.1.jar.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-mailet-standard-3.0.1.jar">(Jar)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-mailet-standard-3.0.1.jar.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-mailet-standard-3.0.1.jar.asc">PGP</a>]
     </p>
 
   </section>
@@ -516,9 +516,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
   </div>
 
     <p>Sources:
-      <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-crypto-sources-3.0.1.zip">(Zip)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-crypto-sources-3.0.1.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-james-mailet-crypto-sources-3.0.1.zip.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-james-mailet-crypto-sources-3.0.1.zip">(Zip)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-james-mailet-crypto-sources-3.0.1.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-james-mailet-crypto-sources-3.0.1.zip.asc">PGP</a>]
     </p>
 
     <p>You can use Mailet AI content using this maven dependency:</p>
@@ -534,9 +534,9 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     </pre>
 
     <p>Direct download link:
-      <a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-crypto-3.0.1.jar">(Jar)</a>
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-crypto-3.0.1.jar.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mailets/3.0.1/apache-mailet-crypto-3.0.1.jar.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-mailet-crypto-3.0.1.jar">(Jar)</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-mailet-crypto-3.0.1.jar.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mailets/3.0.1/apache-mailet-crypto-3.0.1.jar.asc">PGP</a>]
     </p>
     
   </section>
@@ -564,14 +564,14 @@ is found <a href='https://www.apache.org/licenses/exports/'>here</a>.
     <ul>
     
     <li>Source (Unix TAR):
-      <a href="https://www.apache.org/dist/james/mpt/0.1/apache-james-mpt-0.1-src.tar.gz">apache-james-mpt-0.1-src.tar.gz</a>
-      [<a href="https://www.apache.org/dist/james/mpt/0.1/apache-james-mpt-0.1-src.tar.gz.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mpt/0.1/apache-james-mpt-0.1-src.tar.gz.asc">PGP</a>]
+      <a href="https://www.apache.org/dyn/closer.lua/james/mpt/0.1/apache-james-mpt-0.1-src.tar.gz">apache-james-mpt-0.1-src.tar.gz</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mpt/0.1/apache-james-mpt-0.1-src.tar.gz.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mpt/0.1/apache-james-mpt-0.1-src.tar.gz.asc">PGP</a>]
     </li>
     
-    <li>Source (ZIP Format): <a href="https://www.apache.org/dist/james/mpt/0.1/apache-james-mpt-0.1-src.zip">apache-james-mpt-0.1-src.zip</a>
-      [<a href="https://www.apache.org/dist/james/mpt/0.1/apache-james-mpt-0.1-src.zip.sha1">SHA-1</a>]
-      [<a href="https://www.apache.org/dist/james/mpt/0.1/apache-james-mpt-0.1-src.zip.asc">PGP</a>]
+    <li>Source (ZIP Format): <a href="https://www.apache.org/dyn/closer.lua/james/mpt/0.1/apache-james-mpt-0.1-src.zip">apache-james-mpt-0.1-src.zip</a>
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mpt/0.1/apache-james-mpt-0.1-src.zip.sha1">SHA-1</a>]
+      [<a href="https://www.apache.org/dyn/closer.lua/james/mpt/0.1/apache-james-mpt-0.1-src.zip.asc">PGP</a>]
     </li>
     
     <li>Jars (including source and javadocs) for the modules are distributed through the standard 


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


[13/15] james-project git commit: MAILBOX-333 Configuration should allow passing templates

Posted by bt...@apache.org.
MAILBOX-333 Configuration should allow passing templates


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/ae9a8e6c
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ae9a8e6c
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ae9a8e6c

Branch: refs/heads/master
Commit: ae9a8e6cf1d4f1089eceeb95d9941bc8bf521bde
Parents: 409792c
Author: benwa <bt...@linagora.com>
Authored: Wed May 9 09:51:58 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu May 10 09:24:27 2018 +0700

----------------------------------------------------------------------
 .../QuotaMailingListenerConfiguration.java      | 89 ++++++++++++++++++--
 .../QuotaThresholdConfigurationChangesTest.java | 83 +++++++++---------
 .../QuotaThresholdMailingIntegrationTest.java   | 12 ++-
 .../quota/model/QuotaThresholdFixture.java      |  8 +-
 4 files changed, 134 insertions(+), 58 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/ae9a8e6c/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/QuotaMailingListenerConfiguration.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/QuotaMailingListenerConfiguration.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/QuotaMailingListenerConfiguration.java
index 25d504c..5551b20 100644
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/QuotaMailingListenerConfiguration.java
+++ b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/mailbox/quota/mailing/QuotaMailingListenerConfiguration.java
@@ -20,24 +20,89 @@
 package org.apache.james.mailbox.quota.mailing;
 
 import java.time.Duration;
+import java.util.Collection;
 import java.util.Objects;
+import java.util.Optional;
 
+import org.apache.james.filesystem.api.FileSystem;
+import org.apache.james.mailbox.quota.model.QuotaThreshold;
 import org.apache.james.mailbox.quota.model.QuotaThresholds;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.collect.ImmutableList;
 
 public class QuotaMailingListenerConfiguration {
-    public static QuotaMailingListenerConfiguration DEFAULT = new QuotaMailingListenerConfiguration(
-        new QuotaThresholds(ImmutableList.of()),
-        Duration.ofDays(1));
+
+    public static class Builder {
+        private ImmutableList.Builder<QuotaThreshold> thresholds;
+        private Optional<Duration> gradePeriod;
+        private Optional<String> bodyTemplate;
+        private Optional<String> subjectTemplate;
+
+        private Builder() {
+            thresholds = ImmutableList.builder();
+            gradePeriod = Optional.empty();
+            bodyTemplate = Optional.empty();
+            subjectTemplate = Optional.empty();
+        }
+
+        public Builder addThreshold(QuotaThreshold quotaThreshold) {
+            thresholds.add(quotaThreshold);
+            return this;
+        }
+
+        public Builder addThresholds(QuotaThreshold... quotaThresholds) {
+            thresholds.add(quotaThresholds);
+            return this;
+        }
+
+        public Builder addThresholds(Collection<QuotaThreshold> quotaThresholds) {
+            thresholds.addAll(quotaThresholds);
+            return this;
+        }
+
+        public Builder withGracePeriod(Duration duration) {
+            this.gradePeriod = Optional.of(duration);
+            return this;
+        }
+        
+        public Builder withBodyTemplate(String bodyTemplate) {
+            this.bodyTemplate = Optional.of(bodyTemplate);
+            return this;
+        }
+
+        public Builder withSubjectTemplate(String subjectTemplate) {
+            this.subjectTemplate = Optional.of(subjectTemplate);
+            return this;
+        }
+
+        public QuotaMailingListenerConfiguration build() {
+            return new QuotaMailingListenerConfiguration(
+                new QuotaThresholds(thresholds.build()),
+                gradePeriod.orElse(DEFAULT_GRACE_PERIOD),
+                bodyTemplate.orElse(DEFAULT_BODY_TEMPLATE),
+                subjectTemplate.orElse(DEFAULT_SUBJECT_TEMPLATE));
+        }
+    }
+
+    public static final String DEFAULT_BODY_TEMPLATE = FileSystem.CLASSPATH_PROTOCOL + "//templates/QuotaThresholdMailBody.mustache";
+    public static final String DEFAULT_SUBJECT_TEMPLATE = FileSystem.CLASSPATH_PROTOCOL + "//templates/QuotaThresholdMailSubject.mustache";
+    public static final Duration DEFAULT_GRACE_PERIOD = Duration.ofDays(1);
+
+    public static Builder builder() {
+        return new Builder();
+    }
 
     private final QuotaThresholds thresholds;
     private final Duration gracePeriod;
+    private final String bodyTemplate;
+    private final String subjectTemplate;
 
-    public QuotaMailingListenerConfiguration(QuotaThresholds thresholds, Duration gracePeriod) {
+    private QuotaMailingListenerConfiguration(QuotaThresholds thresholds, Duration gracePeriod, String bodyTemplate, String subjectTemplate) {
         this.thresholds = thresholds;
         this.gracePeriod = gracePeriod;
+        this.bodyTemplate = bodyTemplate;
+        this.subjectTemplate = subjectTemplate;
     }
 
     public QuotaThresholds getThresholds() {
@@ -48,20 +113,30 @@ public class QuotaMailingListenerConfiguration {
         return gracePeriod;
     }
 
+    public String getBodyTemplate() {
+        return bodyTemplate;
+    }
+
+    public String getSubjectTemplate() {
+        return subjectTemplate;
+    }
+
     @Override
     public final boolean equals(Object o) {
         if (o instanceof QuotaMailingListenerConfiguration) {
             QuotaMailingListenerConfiguration that = (QuotaMailingListenerConfiguration) o;
 
             return Objects.equals(this.thresholds, that.thresholds)
-                && Objects.equals(this.gracePeriod, that.gracePeriod);
+                && Objects.equals(this.gracePeriod, that.gracePeriod)
+                && Objects.equals(this.bodyTemplate, that.bodyTemplate)
+                && Objects.equals(this.subjectTemplate, that.subjectTemplate);
         }
         return false;
     }
 
     @Override
     public final int hashCode() {
-        return Objects.hash(thresholds, gracePeriod);
+        return Objects.hash(thresholds, gracePeriod, bodyTemplate, subjectTemplate);
     }
 
     @Override
@@ -69,6 +144,8 @@ public class QuotaMailingListenerConfiguration {
         return MoreObjects.toStringHelper(this)
             .add("thresholds", thresholds)
             .add("gracePeriod", gracePeriod)
+            .add("bodyTemplate", bodyTemplate)
+            .add("subjectTemplate", subjectTemplate)
             .toString();
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/ae9a8e6c/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java
index 135b84c..fe57929 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdConfigurationChangesTest.java
@@ -33,24 +33,33 @@ import org.apache.james.mailbox.MailboxListener.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.quota.mailing.QuotaMailingListenerConfiguration;
 import org.apache.james.mailbox.quota.model.QuotaThresholdFixture.Quotas.Counts;
 import org.apache.james.mailbox.quota.model.QuotaThresholdFixture.Quotas.Sizes;
-import org.apache.james.mailbox.quota.model.QuotaThresholds;
 import org.apache.mailet.base.test.FakeMailContext;
 import org.junit.jupiter.api.Test;
 
-import com.google.common.collect.ImmutableList;
-
 public interface QuotaThresholdConfigurationChangesTest {
 
+    QuotaMailingListenerConfiguration CONFIGURATION_50 = QuotaMailingListenerConfiguration.builder()
+        .addThreshold(_50)
+        .gracePeriod(GRACE_PERIOD)
+        .build();
+    QuotaMailingListenerConfiguration CONFIGURATION_75 = QuotaMailingListenerConfiguration.builder()
+        .addThreshold(_75)
+        .gracePeriod(GRACE_PERIOD)
+        .build();
+    QuotaMailingListenerConfiguration CONFIGURATION_50_75 = QuotaMailingListenerConfiguration.builder()
+        .addThresholds(_50, _75)
+        .gracePeriod(GRACE_PERIOD)
+        .build();
+
     @Test
     default void shouldNotSendMailWhenNoNewExceededThresholdAfterThresholdIncrease(EventStore store) throws Exception {
         FakeMailContext mailetContext = mailetContext();
-        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_50);
+
 
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._55_PERCENT, NOW));
 
-        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_75)), GRACE_PERIOD));
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_75);
 
         mailetContext.resetSentMails();
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._55_PERCENT, NOW));
@@ -61,13 +70,11 @@ public interface QuotaThresholdConfigurationChangesTest {
     @Test
     default void shouldNotSendMailAfterThresholdDecreaseWhenAboveAll(EventStore store) throws Exception {
         FakeMailContext mailetContext = mailetContext();
-        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_75)), GRACE_PERIOD));
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_75);
 
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
 
-        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_50);
 
         mailetContext.resetSentMails();
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
@@ -78,13 +85,11 @@ public interface QuotaThresholdConfigurationChangesTest {
     @Test
     default void shouldSendMailWhenNewExceededThresholdAfterThresholdIncrease(EventStore store) throws Exception {
         FakeMailContext mailetContext = mailetContext();
-        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_50);
 
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
 
-        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_75)), GRACE_PERIOD));
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_75);
 
         mailetContext.resetSentMails();
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
@@ -95,13 +100,11 @@ public interface QuotaThresholdConfigurationChangesTest {
     @Test
     default void shouldNotSendMailAfterThresholdIncreaseWhenBelowAll(EventStore store) throws Exception {
         FakeMailContext mailetContext = mailetContext();
-        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_50);
 
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._30_PERCENT, NOW));
 
-        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_75)), GRACE_PERIOD));
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_75);
 
         mailetContext.resetSentMails();
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._30_PERCENT, NOW));
@@ -112,13 +115,11 @@ public interface QuotaThresholdConfigurationChangesTest {
     @Test
     default void shouldNotSendMailAfterThresholdDecreaseWhenBelowAll(EventStore store) throws Exception {
         FakeMailContext mailetContext = mailetContext();
-        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_75)), GRACE_PERIOD));
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_75);
 
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._30_PERCENT, NOW));
 
-        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_50);
 
         mailetContext.resetSentMails();
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._30_PERCENT, NOW));
@@ -129,13 +130,11 @@ public interface QuotaThresholdConfigurationChangesTest {
     @Test
     default void shouldSendMailWhenNewExceededThresholdAfterThresholdDecrease(EventStore store) throws Exception {
         FakeMailContext mailetContext = mailetContext();
-        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_75)), GRACE_PERIOD));
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_75);
 
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._60_PERCENT, NOW));
 
-        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_50);
 
         mailetContext.resetSentMails();
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._60_PERCENT, NOW));
@@ -146,13 +145,12 @@ public interface QuotaThresholdConfigurationChangesTest {
     @Test
     default void shouldSendEmailWhenAddingANewHighestExceededThreshold(EventStore store) throws Exception {
         FakeMailContext mailetContext = mailetContext();
-        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_50);
 
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
 
         testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50, _75)), GRACE_PERIOD));
+            CONFIGURATION_50_75);
 
         mailetContext.resetSentMails();
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
@@ -163,13 +161,12 @@ public interface QuotaThresholdConfigurationChangesTest {
     @Test
     default void shouldNotSendEmailWhenAddingAHighestNonExceededThreshold(EventStore store) throws Exception {
         FakeMailContext mailetContext = mailetContext();
-        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_50);
 
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._60_PERCENT, NOW));
 
         testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50, _75)), GRACE_PERIOD));
+            CONFIGURATION_50_75);
 
         mailetContext.resetSentMails();
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._60_PERCENT, NOW));
@@ -180,13 +177,12 @@ public interface QuotaThresholdConfigurationChangesTest {
     @Test
     default void shouldNotSendEmailWhenAddingANonHighestExceededThreshold(EventStore store) throws Exception {
         FakeMailContext mailetContext = mailetContext();
-        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_75)), GRACE_PERIOD));
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_75);
 
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
 
         testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50, _75)), GRACE_PERIOD));
+            CONFIGURATION_50_75);
 
         mailetContext.resetSentMails();
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
@@ -198,12 +194,11 @@ public interface QuotaThresholdConfigurationChangesTest {
     default void shouldNotSendEmailWhenRemovingANonHighestExceededThreshold(EventStore store) throws Exception {
         FakeMailContext mailetContext = mailetContext();
         QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50, _75)), GRACE_PERIOD));
+            CONFIGURATION_50_75);
 
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
 
-        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_75)), GRACE_PERIOD));
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_75);
 
         mailetContext.resetSentMails();
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
@@ -215,12 +210,11 @@ public interface QuotaThresholdConfigurationChangesTest {
     default void shouldNotSendEmailWhenRemovingHighestExceededThreshold(EventStore store) throws Exception {
         FakeMailContext mailetContext = mailetContext();
         QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50, _75)), GRACE_PERIOD));
+            CONFIGURATION_50_75);
 
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
 
-        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_50);
 
         mailetContext.resetSentMails();
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._92_PERCENT, NOW));
@@ -232,12 +226,11 @@ public interface QuotaThresholdConfigurationChangesTest {
     default void shouldNotSendEmailWhenRemovingHighestNonExceededThreshold(EventStore store) throws Exception {
         FakeMailContext mailetContext = mailetContext();
         QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50, _75)), GRACE_PERIOD));
+            CONFIGURATION_50_75);
 
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._60_PERCENT, NOW));
 
-        testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(ImmutableList.of(_50)), GRACE_PERIOD));
+        testee = new QuotaThresholdListenersTestSystem(mailetContext, store, CONFIGURATION_50);
 
         mailetContext.resetSentMails();
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._60_PERCENT, NOW));

http://git-wip-us.apache.org/repos/asf/james-project/blob/ae9a8e6c/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java
index 54854cc..86e947e 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/mailing/listeners/QuotaThresholdMailingIntegrationTest.java
@@ -42,7 +42,6 @@ import org.apache.james.mailbox.MailboxListener.QuotaUsageUpdatedEvent;
 import org.apache.james.mailbox.quota.mailing.QuotaMailingListenerConfiguration;
 import org.apache.james.mailbox.quota.model.QuotaThresholdFixture.Quotas.Counts;
 import org.apache.james.mailbox.quota.model.QuotaThresholdFixture.Quotas.Sizes;
-import org.apache.james.mailbox.quota.model.QuotaThresholds;
 import org.apache.james.util.concurrency.ConcurrentTestRunner;
 import org.apache.mailet.base.test.FakeMailContext;
 import org.junit.jupiter.api.Test;
@@ -191,7 +190,10 @@ public interface QuotaThresholdMailingIntegrationTest {
     default void shouldSendOneNoticePerThreshold(EventStore store) throws Exception {
         FakeMailContext mailetContext = mailetContext();
         QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
-            new QuotaMailingListenerConfiguration(new QuotaThresholds(_50, _80), GRACE_PERIOD));
+            QuotaMailingListenerConfiguration.builder()
+                .addThresholds(_50, _80)
+                .withGracePeriod(GRACE_PERIOD)
+                .build());
 
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._52_PERCENT, Sizes._30_PERCENT, NOW));
         testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._85_PERCENT, Sizes._42_PERCENT, NOW));
@@ -203,7 +205,11 @@ public interface QuotaThresholdMailingIntegrationTest {
     @Test
     default void shouldSendOneMailUponConcurrentEvents(EventStore store) throws Exception {
         FakeMailContext mailetContext = mailetContext();
-        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store, new QuotaMailingListenerConfiguration(new QuotaThresholds(_50, _80), GRACE_PERIOD));
+        QuotaThresholdListenersTestSystem testee = new QuotaThresholdListenersTestSystem(mailetContext, store,
+            QuotaMailingListenerConfiguration.builder()
+                .addThresholds(_50, _80)
+                .withGracePeriod(GRACE_PERIOD)
+                .build());
 
         new ConcurrentTestRunner(10, 1, (threadNb, step) ->
             testee.event(new QuotaUsageUpdatedEvent(BOB_SESSION, QUOTAROOT, Counts._40_PERCENT, Sizes._55_PERCENT, NOW)))

http://git-wip-us.apache.org/repos/asf/james-project/blob/ae9a8e6c/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdFixture.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdFixture.java b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdFixture.java
index 1770420..7445fb7 100644
--- a/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdFixture.java
+++ b/mailbox/plugin/quota-mailing/src/test/java/org/apache/james/mailbox/quota/model/QuotaThresholdFixture.java
@@ -32,8 +32,6 @@ import org.apache.james.mailbox.quota.mailing.QuotaMailingListenerConfiguration;
 import org.apache.mailet.base.MailAddressFixture;
 import org.apache.mailet.base.test.FakeMailContext;
 
-import com.google.common.collect.ImmutableList;
-
 public interface QuotaThresholdFixture {
     QuotaThreshold _50 = new QuotaThreshold(0.50);
     QuotaThreshold _75 = new QuotaThreshold(0.75);
@@ -124,8 +122,10 @@ public interface QuotaThresholdFixture {
 
     interface TestConstants {
         Duration GRACE_PERIOD = Duration.ofDays(1);
-        QuotaThresholds SINGLE_THRESHOLD = new QuotaThresholds(ImmutableList.of(_50));
-        QuotaMailingListenerConfiguration DEFAULT_CONFIGURATION = new QuotaMailingListenerConfiguration(SINGLE_THRESHOLD, GRACE_PERIOD);
+        QuotaMailingListenerConfiguration DEFAULT_CONFIGURATION = QuotaMailingListenerConfiguration.builder()
+            .addThresholds(_50)
+            .withGracePeriod(GRACE_PERIOD)
+            .build();
         String BOB = "bob@domain";
         MockMailboxSession BOB_SESSION = new MockMailboxSession(BOB);
         Instant NOW = Instant.now();


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


[09/15] james-project git commit: MAILBOX-332 Demonstrate JsonEventSerializer polymorphism

Posted by bt...@apache.org.
MAILBOX-332 Demonstrate JsonEventSerializer polymorphism


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/c76a4ec9
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/c76a4ec9
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/c76a4ec9

Branch: refs/heads/master
Commit: c76a4ec93a95c9cb24c57abae1d59b42103ad711
Parents: c3a1bda
Author: benwa <bt...@linagora.com>
Authored: Wed May 9 16:27:29 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu May 10 09:15:41 2018 +0700

----------------------------------------------------------------------
 .../cassandra/JsonEventSerializerTest.java      | 43 ++++++++++--
 .../eventsourcing/cassandra/dto/OtherEvent.java | 50 ++++++++++++++
 .../cassandra/dto/OtherTestEventDTO.java        | 72 ++++++++++++++++++++
 .../cassandra/dto/OtherTestEventDTOModule.java  | 55 +++++++++++++++
 4 files changed, 216 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/c76a4ec9/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializerTest.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializerTest.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializerTest.java
index 893647b..89770bb 100644
--- a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializerTest.java
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/JsonEventSerializerTest.java
@@ -26,15 +26,20 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import org.apache.james.eventsourcing.EventId;
 import org.apache.james.eventsourcing.TestAggregateId;
 import org.apache.james.eventsourcing.TestEvent;
+import org.apache.james.eventsourcing.cassandra.dto.OtherEvent;
+import org.apache.james.eventsourcing.cassandra.dto.OtherTestEventDTOModule;
 import org.apache.james.eventsourcing.cassandra.dto.TestEventDTOModule;
 import org.junit.jupiter.api.Test;
 
 class JsonEventSerializerTest {
+    public static final EventId EVENT_ID = EventId.fromSerialized(0);
+    public static final TestAggregateId AGGREGATE_ID = TestAggregateId.testId(1);
+
+    public static final OtherEvent OTHER_EVENT = new OtherEvent(EVENT_ID, AGGREGATE_ID, 1);
+    public static final TestEvent TEST_EVENT = new TestEvent(EVENT_ID, AGGREGATE_ID, "first");
+
     public static final String TEST_EVENT_JSON = "{\"type\":\"TestType\",\"data\":\"first\",\"eventId\":0,\"aggregate\":1}";
-    public static final TestEvent TEST_EVENT = new TestEvent(
-        EventId.fromSerialized(0),
-        TestAggregateId.testId(1),
-        "first");
+    public static final String OTHER_EVENT_JSON = "{\"type\":\"other-type\",\"data\":1,\"eventId\":0,\"aggregate\":1}";
 
     @Test
     void shouldDeserializeKnownEvent() throws Exception {
@@ -51,6 +56,36 @@ class JsonEventSerializerTest {
     }
 
     @Test
+    void serializeShouldHandleAllKnownEvents() throws Exception {
+        JsonEventSerializer jsonEventSerializer = new JsonEventSerializer(
+            new TestEventDTOModule(),
+            new OtherTestEventDTOModule());
+
+        assertThatJson(
+            jsonEventSerializer.serialize(OTHER_EVENT))
+            .isEqualTo(OTHER_EVENT_JSON);
+
+        assertThatJson(
+            jsonEventSerializer.serialize(TEST_EVENT))
+            .isEqualTo(TEST_EVENT_JSON);
+    }
+
+    @Test
+    void deserializeShouldHandleAllKnownEvents() throws Exception {
+        JsonEventSerializer jsonEventSerializer = new JsonEventSerializer(
+            new TestEventDTOModule(),
+            new OtherTestEventDTOModule());
+
+        assertThatJson(
+            jsonEventSerializer.deserialize(OTHER_EVENT_JSON))
+            .isEqualTo(OTHER_EVENT);
+
+        assertThatJson(
+            jsonEventSerializer.deserialize(TEST_EVENT_JSON))
+            .isEqualTo(TEST_EVENT);
+    }
+
+    @Test
     void shouldSerializeKnownEvent() throws Exception {
         assertThatJson(new JsonEventSerializer(new TestEventDTOModule())
             .serialize(TEST_EVENT))

http://git-wip-us.apache.org/repos/asf/james-project/blob/c76a4ec9/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherEvent.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherEvent.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherEvent.java
new file mode 100644
index 0000000..4e74720
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherEvent.java
@@ -0,0 +1,50 @@
+/****************************************************************
+ * 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.eventsourcing.cassandra.dto;
+
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.EventId;
+import org.apache.james.eventsourcing.TestAggregateId;
+
+public class OtherEvent implements Event {
+    private final EventId eventId;
+    private final TestAggregateId aggregateId;
+    private final long payload;
+
+    public OtherEvent(EventId eventId, TestAggregateId aggregateId, long payload) {
+        this.eventId = eventId;
+        this.aggregateId = aggregateId;
+        this.payload = payload;
+    }
+
+    @Override
+    public EventId eventId() {
+        return eventId;
+    }
+
+    @Override
+    public TestAggregateId getAggregateId() {
+        return aggregateId;
+    }
+
+    public long getPayload() {
+        return payload;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c76a4ec9/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherTestEventDTO.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherTestEventDTO.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherTestEventDTO.java
new file mode 100644
index 0000000..4f35c12
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherTestEventDTO.java
@@ -0,0 +1,72 @@
+/****************************************************************
+ * 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.eventsourcing.cassandra.dto;
+
+import org.apache.james.eventsourcing.Event;
+import org.apache.james.eventsourcing.EventId;
+import org.apache.james.eventsourcing.TestAggregateId;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class OtherTestEventDTO implements EventDTO {
+    private final String type;
+    private final long data;
+    private final int eventId;
+    private final int aggregate;
+
+    @JsonCreator
+    public OtherTestEventDTO(
+            @JsonProperty("type") String type,
+            @JsonProperty("data") long data,
+            @JsonProperty("eventId") int eventId,
+            @JsonProperty("aggregate") int aggregate) {
+        this.type = type;
+        this.data = data;
+        this.eventId = eventId;
+        this.aggregate = aggregate;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public long getData() {
+        return data;
+    }
+
+    public long getEventId() {
+        return eventId;
+    }
+
+    public int getAggregate() {
+        return aggregate;
+    }
+
+    @JsonIgnore
+    @Override
+    public Event toEvent() {
+        return new OtherEvent(
+            EventId.fromSerialized(eventId),
+            TestAggregateId.testId(aggregate),
+            data);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c76a4ec9/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherTestEventDTOModule.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherTestEventDTOModule.java b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherTestEventDTOModule.java
new file mode 100644
index 0000000..deb9a02
--- /dev/null
+++ b/mailbox/plugin/quota-mailing-cassandra/src/test/java/org/apache/james/eventsourcing/cassandra/dto/OtherTestEventDTOModule.java
@@ -0,0 +1,55 @@
+/****************************************************************
+ * 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.eventsourcing.cassandra.dto;
+
+import org.apache.james.eventsourcing.Event;
+import org.testcontainers.shaded.com.google.common.base.Preconditions;
+
+public class OtherTestEventDTOModule implements EventDTOModule {
+
+    public static final String OTHER_TYPE = "other-type";
+
+    @Override
+    public String getType() {
+        return OTHER_TYPE;
+    }
+
+    @Override
+    public Class<? extends EventDTO> getDTOClass() {
+        return OtherTestEventDTO.class;
+    }
+
+    @Override
+    public Class<? extends Event> getEventClass() {
+        return OtherEvent.class;
+    }
+
+    @Override
+    public EventDTO toDTO(Event event) {
+        Preconditions.checkArgument(event instanceof OtherEvent);
+        OtherEvent otherEvent = (OtherEvent) event;
+
+        return new OtherTestEventDTO(
+            OTHER_TYPE,
+            otherEvent.getPayload(),
+            otherEvent.eventId().serialize(),
+            otherEvent.getAggregateId().getId());
+    }
+}


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


[06/15] james-project git commit: MAILBOX-332 EventId should be an int

Posted by bt...@apache.org.
MAILBOX-332 EventId should be an int


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/17ff45f4
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/17ff45f4
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/17ff45f4

Branch: refs/heads/master
Commit: 17ff45f49f6ec31014ed03f15413a46506a7a93d
Parents: 4b9c3f7
Author: Matthieu Baechler <ma...@apache.org>
Authored: Wed May 9 14:37:00 2018 +0200
Committer: benwa <bt...@linagora.com>
Committed: Thu May 10 09:15:22 2018 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/eventsourcing/EventId.java    | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/17ff45f4/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventId.java
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventId.java b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventId.java
index 1d636f6..cb5bd1e 100644
--- a/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventId.java
+++ b/mailbox/plugin/quota-mailing/src/main/java/org/apache/james/eventsourcing/EventId.java
@@ -27,13 +27,17 @@ import com.google.common.base.Preconditions;
 
 public class EventId implements Comparable<EventId> {
 
+    public static EventId fromSerialized(int value) {
+        return new EventId(value);
+    }
+
     public static EventId first() {
         return new EventId(0);
     }
 
-    private final long value;
+    private final int value;
 
-    private EventId(long value) {
+    private EventId(int value) {
         Preconditions.checkArgument(value >= 0, "EventId can not be negative");
         this.value = value;
     }
@@ -75,4 +79,8 @@ public class EventId implements Comparable<EventId> {
             .add("value", value)
             .toString();
     }
+
+    public int serialize() {
+        return value;
+    }
 }


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