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:21 UTC

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

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