JAMES-1717 We should avoid a read to Cassandra if the mail is automatically sent


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

Branch: refs/heads/master
Commit: a05bcee71442c6a3c3a7e9153b29024ef9e6c07c
Parents: 9eec8d9
Author: Benoit Tellier <btell...@linagora.com>
Authored: Wed May 25 11:45:35 2016 +0700
Committer: Benoit Tellier <btell...@linagora.com>
Committed: Fri May 27 18:03:29 2016 +0700

----------------------------------------------------------------------
 .../james/jmap/mailet/VacationMailet.java       |  44 +++---
 .../james/jmap/mailet/VacationMailetTest.java   | 133 +++----------------
 2 files changed, 37 insertions(+), 140 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/a05bcee7/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/VacationMailet.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/VacationMailet.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/VacationMailet.java
index 374336b..02258e4 100644
--- 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/VacationMailet.java
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/mailet/VacationMailet.java
@@ -59,11 +59,13 @@ public class VacationMailet extends GenericMailet {
     @Override
     public void service(Mail mail) {
         try {
-            ZonedDateTime processingDate = zonedDateTimeProvider.get();
-            mail.getRecipients()
-                .stream()
-                .map(mailAddress -> manageVacation(mailAddress, mail, 
processingDate))
-                .forEach(CompletableFuture::join);
+            if (! automaticallySentMailDetector.isAutomaticallySent(mail)) {
+                ZonedDateTime processingDate = zonedDateTimeProvider.get();
+                mail.getRecipients()
+                    .stream()
+                    .map(mailAddress -> manageVacation(mailAddress, mail, 
processingDate))
+                    .forEach(CompletableFuture::join);
+            }
         } catch (Throwable e) {
             LOGGER.warn("Can not process vacation for one or more recipients 
in {}", mail.getRecipients(), e);
         }
@@ -72,34 +74,20 @@ public class VacationMailet extends GenericMailet {
     public CompletableFuture<Void> manageVacation(MailAddress recipient, Mail 
processedMail, ZonedDateTime processingDate) {
         AccountId accountId = AccountId.fromString(recipient.toString());
         CompletableFuture<Vacation> vacationFuture = 
vacationRepository.retrieveVacation(accountId);
-        return vacationFuture.thenAccept(vacation -> {
-            if (shouldSendNotification(vacation, processedMail, recipient, 
processingDate)) {
+        CompletableFuture<Boolean> hasAlreadyBeenSent = 
notificationRegistry.isRegistered(
+            AccountId.fromString(recipient.toString()),
+            RecipientId.fromMailAddress(processedMail.getSender()));
+
+        return vacationFuture.thenAcceptBoth(hasAlreadyBeenSent, (vacation, 
alreadySent) -> {
+            if (shouldSendNotification(vacation, processingDate, alreadySent)) 
{
                 sendNotification(recipient, processedMail, vacation);
             }
         });
     }
 
-    private boolean shouldSendNotification(Vacation vacation, Mail 
processedMail, MailAddress recipient, ZonedDateTime processingDate) {
-        try {
-            return vacation.isActiveAtDate(processingDate)
-                && ! 
automaticallySentMailDetector.isAutomaticallySent(processedMail)
-                && hasNotSentNotificationsYet(processedMail, recipient);
-        } catch (MessagingException e) {
-            LOGGER.warn("Failed detect automatic response in a mail from {} to 
{}", processedMail.getSender(), recipient, e);
-            return false;
-        }
-    }
-
-    private boolean hasNotSentNotificationsYet(Mail processedMail, MailAddress 
recipient) {
-        CompletableFuture<Boolean> hasAlreadyBeenSent = 
notificationRegistry.isRegistered(
-            AccountId.fromString(recipient.toString()),
-            RecipientId.fromMailAddress(processedMail.getSender()));
-        try {
-            return !hasAlreadyBeenSent.join();
-        } catch (Throwable t) {
-            LOGGER.warn("Error while checking registration state of vacation 
notification for user {} and sender {}", recipient, processedMail.getSender(), 
t);
-            return true;
-        }
+    private boolean shouldSendNotification(Vacation vacation, ZonedDateTime 
processingDate, boolean alreadySent) {
+        return vacation.isActiveAtDate(processingDate)
+            && ! alreadySent;
     }
 
     private void sendNotification(MailAddress recipient, Mail processedMail, 
Vacation vacation) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/a05bcee7/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/VacationMailetTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/VacationMailetTest.java
 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/VacationMailetTest.java
index 1de142a..f3047e4 100644
--- 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/VacationMailetTest.java
+++ 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/mailet/VacationMailetTest.java
@@ -54,9 +54,15 @@ public class VacationMailetTest {
     public static final ZonedDateTime DATE_TIME_2016 = 
ZonedDateTime.parse("2016-10-09T08:07:06+07:00[Asia/Vientiane]");
     public static final ZonedDateTime DATE_TIME_2017 = 
ZonedDateTime.parse("2017-10-09T08:07:06+07:00[Asia/Vientiane]");
     public static final ZonedDateTime DATE_TIME_2018 = 
ZonedDateTime.parse("2018-10-09T08:07:06+07:00[Asia/Vientiane]");
-
     public static final String USERNAME = "be...@apache.org";
     public static final AccountId ACCOUNT_ID = AccountId.fromString(USERNAME);
+    public static final Vacation VACATION = Vacation.builder()
+        .enabled(true)
+        .fromDate(Optional.of(DATE_TIME_2016))
+        .toDate(Optional.of(DATE_TIME_2018))
+        .textBody("Explaining my vacation")
+        .build();
+
     private VacationMailet testee;
     private VacationRepository vacationRepository;
     private ZonedDateTimeProvider zonedDateTimeProvider;
@@ -66,12 +72,18 @@ public class VacationMailetTest {
     private AutomaticallySentMailDetector automaticallySentMailDetector;
     private NotificationRegistry notificationRegistry;
     private RecipientId recipientId;
+    private FakeMail mail;
 
     @Before
     public void setUp() throws Exception {
         originalSender = new MailAddress("dist...@apache.org");
         originalRecipient = new MailAddress(USERNAME);
         recipientId = RecipientId.fromMailAddress(originalSender);
+        mail = FakeMail.builder()
+            .fileName("spamMail.eml")
+            .recipient(originalRecipient)
+            .sender(originalSender)
+            .build();
 
         vacationRepository = mock(VacationRepository.class);
         zonedDateTimeProvider = mock(ZonedDateTimeProvider.class);
@@ -84,11 +96,6 @@ public class VacationMailetTest {
 
     @Test
     public void unactivatedVacationShouldNotSendNotification() throws 
Exception {
-        FakeMail mail = FakeMail.builder()
-            .fileName("spamMail.eml")
-            .recipient(originalRecipient)
-            .sender(new MailAddress("owner-l...@any.com"))
-            .build();
         when(zonedDateTimeProvider.get()).thenReturn(DATE_TIME_2017);
         
when(vacationRepository.retrieveVacation(AccountId.fromString(USERNAME)))
             
.thenReturn(CompletableFuture.completedFuture(VacationRepository.DEFAULT_VACATION));
@@ -101,19 +108,8 @@ public class VacationMailetTest {
 
     @Test
     public void activateVacationShouldSendNotification() throws Exception {
-        FakeMail mail = FakeMail.builder()
-            .fileName("spamMail.eml")
-            .recipient(originalRecipient)
-            .sender(originalSender)
-            .build();
         
when(vacationRepository.retrieveVacation(AccountId.fromString(USERNAME)))
-            .thenReturn(CompletableFuture.completedFuture(
-                Vacation.builder()
-                    .enabled(true)
-                    .fromDate(Optional.of(DATE_TIME_2016))
-                    .toDate(Optional.of(DATE_TIME_2018))
-                    .textBody("Explaining my vacation")
-                    .build()));
+            .thenReturn(CompletableFuture.completedFuture(VACATION));
         when(zonedDateTimeProvider.get()).thenReturn(DATE_TIME_2017);
         
when(automaticallySentMailDetector.isAutomaticallySent(mail)).thenReturn(false);
         when(notificationRegistry.isRegistered(ACCOUNT_ID, recipientId))
@@ -129,19 +125,8 @@ public class VacationMailetTest {
 
     @Test
     public void activateVacationShouldNotSendNotificationIfAlreadySent() 
throws Exception {
-        FakeMail mail = FakeMail.builder()
-            .fileName("spamMail.eml")
-            .recipient(originalRecipient)
-            .sender(originalSender)
-            .build();
         
when(vacationRepository.retrieveVacation(AccountId.fromString(USERNAME)))
-            .thenReturn(CompletableFuture.completedFuture(
-                Vacation.builder()
-                    .enabled(true)
-                    .fromDate(Optional.of(DATE_TIME_2016))
-                    .toDate(Optional.of(DATE_TIME_2018))
-                    .textBody("Explaining my vacation")
-                    .build()));
+            .thenReturn(CompletableFuture.completedFuture(VACATION));
         when(zonedDateTimeProvider.get()).thenReturn(DATE_TIME_2017);
         when(notificationRegistry.isRegistered(ACCOUNT_ID, recipientId))
             .thenReturn(CompletableFuture.completedFuture(true));
@@ -153,19 +138,8 @@ public class VacationMailetTest {
 
     @Test
     public void 
activateVacationShouldSendNotificationIfErrorUpdatingNotificationRepository() 
throws Exception {
-        FakeMail mail = FakeMail.builder()
-            .fileName("spamMail.eml")
-            .recipient(originalRecipient)
-            .sender(originalSender)
-            .build();
         
when(vacationRepository.retrieveVacation(AccountId.fromString(USERNAME)))
-            .thenReturn(CompletableFuture.completedFuture(
-                Vacation.builder()
-                    .enabled(true)
-                    .fromDate(Optional.of(DATE_TIME_2016))
-                    .toDate(Optional.of(DATE_TIME_2018))
-                    .textBody("Explaining my vacation")
-                    .build()));
+            .thenReturn(CompletableFuture.completedFuture(VACATION));
         when(zonedDateTimeProvider.get()).thenReturn(DATE_TIME_2017);
         RecipientId recipientId = RecipientId.fromMailAddress(originalSender);
         when(notificationRegistry.isRegistered(ACCOUNT_ID, recipientId))
@@ -180,19 +154,8 @@ public class VacationMailetTest {
 
     @Test
     public void 
activateVacationShouldSendNotificationIfErrorRetrievingNotificationRepository() 
throws Exception {
-        FakeMail mail = FakeMail.builder()
-            .fileName("spamMail.eml")
-            .recipient(originalRecipient)
-            .sender(originalSender)
-            .build();
         
when(vacationRepository.retrieveVacation(AccountId.fromString(USERNAME)))
-            .thenReturn(CompletableFuture.completedFuture(
-                Vacation.builder()
-                    .enabled(true)
-                    .fromDate(Optional.of(DATE_TIME_2016))
-                    .toDate(Optional.of(DATE_TIME_2018))
-                    .textBody("Explaining my vacation")
-                    .build()));
+            .thenReturn(CompletableFuture.completedFuture(VACATION));
         when(zonedDateTimeProvider.get()).thenReturn(DATE_TIME_2017);
         RecipientId recipientId = RecipientId.fromMailAddress(originalSender);
         when(notificationRegistry.isRegistered(ACCOUNT_ID, recipientId))
@@ -205,23 +168,8 @@ public class VacationMailetTest {
 
     @Test
     public void activateVacationShouldNotSendNotificationToMailingList() 
throws Exception {
-        FakeMail mail = FakeMail.builder()
-            .fileName("spamMail.eml")
-            .recipient(originalRecipient)
-            .sender(new MailAddress("owner-l...@any.com"))
-            .build();
-        
when(vacationRepository.retrieveVacation(AccountId.fromString(USERNAME)))
-            .thenReturn(CompletableFuture.completedFuture(
-                Vacation.builder()
-                    .enabled(true)
-                    .fromDate(Optional.of(DATE_TIME_2016))
-                    .toDate(Optional.of(DATE_TIME_2018))
-                    .textBody("Explaining my vacation")
-                    .build()));
         when(zonedDateTimeProvider.get()).thenReturn(DATE_TIME_2017);
         
when(automaticallySentMailDetector.isAutomaticallySent(mail)).thenReturn(true);
-        when(notificationRegistry.isRegistered(ACCOUNT_ID, 
RecipientId.fromMailAddress(originalSender)))
-            .thenReturn(CompletableFuture.completedFuture(false));
 
         testee.service(mail);
 
@@ -240,21 +188,9 @@ public class VacationMailetTest {
             .sender(originalSender)
             .build();
         
when(vacationRepository.retrieveVacation(AccountId.fromString(USERNAME)))
-            .thenReturn(CompletableFuture.completedFuture(
-                Vacation.builder()
-                    .enabled(true)
-                    .fromDate(Optional.of(DATE_TIME_2016))
-                    .toDate(Optional.of(DATE_TIME_2018))
-                    .textBody("Explaining my vacation")
-                    .build()));
+            .thenReturn(CompletableFuture.completedFuture(VACATION));
         when(vacationRepository.retrieveVacation(secondAccountId))
-            .thenReturn(CompletableFuture.completedFuture(
-                Vacation.builder()
-                    .enabled(true)
-                    .fromDate(Optional.of(DATE_TIME_2016))
-                    .toDate(Optional.of(DATE_TIME_2018))
-                    .textBody("Explaining my vacation")
-                    .build()));
+            .thenReturn(CompletableFuture.completedFuture(VACATION));
         when(zonedDateTimeProvider.get()).thenReturn(DATE_TIME_2017);
         
when(automaticallySentMailDetector.isAutomaticallySent(mail)).thenReturn(false);
         when(notificationRegistry.isRegistered(ACCOUNT_ID, 
RecipientId.fromMailAddress(originalSender)))
@@ -271,11 +207,6 @@ public class VacationMailetTest {
 
     @Test
     public void 
serviceShouldNotSendNotificationUponErrorsRetrievingVacationObject() throws 
Exception {
-        FakeMail mail = FakeMail.builder()
-            .fileName("spamMail.eml")
-            .recipient(originalRecipient)
-            .sender(new MailAddress("owner-l...@any.com"))
-            .build();
         
when(vacationRepository.retrieveVacation(AccountId.fromString(USERNAME)))
             .thenReturn(CompletableFuture.supplyAsync(() -> {
                 throw new RuntimeException();
@@ -290,19 +221,8 @@ public class VacationMailetTest {
 
     @Test
     public void 
serviceShouldNotSendNotificationUponErrorsDetectingAutomaticallySentMails() 
throws Exception {
-        FakeMail mail = FakeMail.builder()
-            .fileName("spamMail.eml")
-            .recipient(originalRecipient)
-            .sender(originalSender)
-            .build();
         
when(vacationRepository.retrieveVacation(AccountId.fromString(USERNAME)))
-            .thenReturn(CompletableFuture.completedFuture(
-                Vacation.builder()
-                    .enabled(true)
-                    .fromDate(Optional.of(DATE_TIME_2016))
-                    .toDate(Optional.of(DATE_TIME_2018))
-                    .textBody("Explaining my vacation")
-                    .build()));
+            .thenReturn(CompletableFuture.completedFuture(VACATION));
         when(zonedDateTimeProvider.get()).thenReturn(DATE_TIME_2017);
         
when(automaticallySentMailDetector.isAutomaticallySent(mail)).thenThrow(new 
MessagingException());
 
@@ -313,19 +233,8 @@ public class VacationMailetTest {
 
     @Test
     public void serviceShouldNotPropagateExceptionIfSendFails() throws 
Exception {
-        FakeMail mail = FakeMail.builder()
-            .fileName("spamMail.eml")
-            .recipient(originalRecipient)
-            .sender(originalSender)
-            .build();
         
when(vacationRepository.retrieveVacation(AccountId.fromString(USERNAME)))
-            .thenReturn(CompletableFuture.completedFuture(
-                Vacation.builder()
-                    .enabled(true)
-                    .fromDate(Optional.of(DATE_TIME_2016))
-                    .toDate(Optional.of(DATE_TIME_2018))
-                    .textBody("Explaining my vacation")
-                    .build()));
+            .thenReturn(CompletableFuture.completedFuture(VACATION));
         when(zonedDateTimeProvider.get()).thenReturn(DATE_TIME_2017);
         
when(automaticallySentMailDetector.isAutomaticallySent(mail)).thenReturn(false);
         when(notificationRegistry.isRegistered(ACCOUNT_ID, 
RecipientId.fromMailAddress(originalSender)))


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

Reply via email to