From 5209db5793c18fea05aea98dcceaf0b08f3f18c6 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Thu, 23 Sep 2010 13:46:31 -0400 Subject: [PATCH] INT-1475 fixed the 'flderOpenMode' setting to ensure that it is set to TRUE if deleteMessages flag is set to TRUE, introduced bunchof test cases to make sure that these setting are covered and could be cought in the future if more refactoring is required --- .../mail/AbstractMailReceiver.java | 30 +-- .../integration/mail/ImapMailReceiver.java | 2 +- .../integration/mail/MailTransportUtils.java | 22 +- .../integration/mail/Pop3MailReceiver.java | 3 +- .../mail/config/MailReceiverFactoryBean.java | 1 + .../mail/ImapMailReceiverTests.java | 40 ++++ .../mail/Pop3MailReceiverTests.java | 197 ++++++++++++++++++ 7 files changed, 269 insertions(+), 26 deletions(-) create mode 100644 spring-integration-mail/src/test/java/org/springframework/integration/mail/Pop3MailReceiverTests.java diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java index 2578583c33..df363c0601 100755 --- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java +++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java @@ -27,7 +27,6 @@ import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Store; import javax.mail.URLName; -import javax.mail.Flags.Flag; import javax.mail.internet.MimeMessage; import org.apache.commons.logging.Log; @@ -63,7 +62,7 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl private volatile boolean shouldDeleteMessages = false; - private volatile int folderOpenMode = Folder.READ_ONLY; + protected volatile int folderOpenMode = Folder.READ_ONLY; private volatile Properties javaMailProperties = new Properties(); @@ -207,7 +206,7 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl if (logger.isDebugEnabled()) { logger.debug("opening folder [" + MailTransportUtils.toPasswordProtectedString(this.url) + "]"); } - this.folder.open(folderOpenMode); + this.folder.open(this.folderOpenMode); } public synchronized Message[] receive() { @@ -244,7 +243,7 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl "failure occurred while receiving from folder", e); } finally { - MailTransportUtils.closeFolder(this.folder); + MailTransportUtils.closeFolder(this.folder, this.shouldDeleteMessages); } } @@ -278,7 +277,7 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl public void destroy() throws Exception { synchronized (this.initializationMonitor) { - MailTransportUtils.closeFolder(this.folder); + MailTransportUtils.closeFolder(this.folder, this.shouldDeleteMessages); MailTransportUtils.closeService(this.store); this.folder = null; this.store = null; @@ -290,14 +289,21 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl public String toString() { return this.url.toString(); } + /** + * Optional method allowing you to set additional flags. + * Currently only implemented in IMapMailReceiever. + * + * @param message + * @throws MessagingException + */ + protected void setAdditionalFlags(Message message) throws MessagingException {} - protected void setAdditionalFlags(Message message) throws MessagingException { - if (this.shouldDeleteMessages) { - message.setFlag(Flag.DELETED, true); + /** + * + */ + protected void onInit() throws Exception { + if (this.shouldDeleteMessages){ + this.folderOpenMode = Folder.READ_WRITE; } } - - void setFolderOpenMode(int folderOpenMode) { - this.folderOpenMode = folderOpenMode; - } } diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapMailReceiver.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapMailReceiver.java index 77f51740c8..b16d6ef677 100755 --- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapMailReceiver.java +++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapMailReceiver.java @@ -179,7 +179,7 @@ public class ImapMailReceiver extends AbstractMailReceiver { */ protected void onInit() throws Exception { if (this.shouldMarkMessagesAsRead){ - this.setFolderOpenMode(Folder.READ_WRITE); + this.folderOpenMode = Folder.READ_WRITE; } } /** diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/MailTransportUtils.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/MailTransportUtils.java index 480e34fa76..5a3ad02760 100644 --- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/MailTransportUtils.java +++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/MailTransportUtils.java @@ -58,16 +58,16 @@ public abstract class MailTransportUtils { } } - /** - * Close the given JavaMail Folder and ignore any thrown exception. This is - * useful for typical finally blocks in manual JavaMail code. - * - * @param folder the JavaMail Folder to close (may be null) - */ - - public static void closeFolder(Folder folder) { - closeFolder(folder, false); - } +// /** +// * Close the given JavaMail Folder and ignore any thrown exception. This is +// * useful for typical finally blocks in manual JavaMail code. +// * +// * @param folder the JavaMail Folder to close (may be null) +// */ +// +// public static void closeFolder(Folder folder) { +// closeFolder(folder, false); +// } /** * Close the given JavaMail Folder and ignore any thrown exception. This is @@ -79,7 +79,7 @@ public abstract class MailTransportUtils { public static void closeFolder(Folder folder, boolean expunge) { if (folder != null && folder.isOpen()) { try { - folder.close(expunge); + folder.close(expunge); } catch (MessagingException ex) { logger.debug("Could not close JavaMail Folder", ex); diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/Pop3MailReceiver.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/Pop3MailReceiver.java index 0fa3df95a0..4a2fb337c4 100755 --- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/Pop3MailReceiver.java +++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/Pop3MailReceiver.java @@ -16,6 +16,7 @@ package org.springframework.integration.mail; +import javax.mail.Folder; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.URLName; @@ -79,7 +80,5 @@ public class Pop3MailReceiver extends AbstractMailReceiver { for (int i = 0; i < messages.length; i++) { new MimeMessage((MimeMessage) messages[i]); } - MailTransportUtils.closeFolder(this.getFolder(), true); } - } diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/MailReceiverFactoryBean.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/MailReceiverFactoryBean.java index 002425eff6..f382949d8b 100644 --- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/MailReceiverFactoryBean.java +++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/MailReceiverFactoryBean.java @@ -155,6 +155,7 @@ public class MailReceiverFactoryBean implements FactoryBean, Dispo ((ImapMailReceiver)receiver).setShouldMarkMessagesAsRead(this.shouldMarkMessagesAsRead); } } + receiver.afterPropertiesSet(); return receiver; } diff --git a/spring-integration-mail/src/test/java/org/springframework/integration/mail/ImapMailReceiverTests.java b/spring-integration-mail/src/test/java/org/springframework/integration/mail/ImapMailReceiverTests.java index 04d65bbece..d82e7e5b7c 100644 --- a/spring-integration-mail/src/test/java/org/springframework/integration/mail/ImapMailReceiverTests.java +++ b/spring-integration-mail/src/test/java/org/springframework/integration/mail/ImapMailReceiverTests.java @@ -53,6 +53,8 @@ import com.sun.mail.imap.IMAPFolder; */ public class ImapMailReceiverTests { + + @Test public void receieveAndMarkAsReadDontDelete() throws Exception{ AbstractMailReceiver receiver = new ImapMailReceiver(); @@ -164,6 +166,44 @@ public class ImapMailReceiverTests { verify(msg2, times(0)).setFlag(Flag.SEEN, true); } @Test + public void receieveAndDontMarkAsReadButDelete() throws Exception{ + AbstractMailReceiver receiver = new Pop3MailReceiver(); + ((Pop3MailReceiver)receiver).setShouldDeleteMessages(true); + receiver = spy(receiver); + receiver.afterPropertiesSet(); + Message msg1 = mock(MimeMessage.class); + Message msg2 = mock(MimeMessage.class); + final Message[] messages = new Message[]{msg1, msg2}; + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + DirectFieldAccessor accessor = new DirectFieldAccessor(invocation.getMock()); + int folderOpenMode = (Integer) accessor.getPropertyValue("folderOpenMode"); + if (folderOpenMode != Folder.READ_WRITE){ + throw new IllegalArgumentException("Folder had to be open in READ_WRITE mode"); + } + return null; + } + }).when(receiver).openFolder(); + + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + return messages; + } + }).when(receiver).searchForNewMessages(); + + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + return null; + } + }).when(receiver).fetchMessages(messages); + receiver.afterPropertiesSet(); + receiver.receive(); + verify(msg1, times(0)).setFlag(Flag.SEEN, true); + verify(msg2, times(0)).setFlag(Flag.SEEN, true); + verify(msg1, times(1)).setFlag(Flag.DELETED, true); + verify(msg2, times(1)).setFlag(Flag.DELETED, true); + } + @Test public void receieveAndIgnoreMarkAsReadDontDelete() throws Exception{ AbstractMailReceiver receiver = new ImapMailReceiver(); receiver = spy(receiver); diff --git a/spring-integration-mail/src/test/java/org/springframework/integration/mail/Pop3MailReceiverTests.java b/spring-integration-mail/src/test/java/org/springframework/integration/mail/Pop3MailReceiverTests.java new file mode 100644 index 0000000000..d5f8790682 --- /dev/null +++ b/spring-integration-mail/src/test/java/org/springframework/integration/mail/Pop3MailReceiverTests.java @@ -0,0 +1,197 @@ +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed 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.springframework.integration.mail; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Properties; + +import javax.mail.Flags; +import javax.mail.Flags.Flag; +import javax.mail.Folder; +import javax.mail.Message; +import javax.mail.internet.MimeMessage; + +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.springframework.beans.DirectFieldAccessor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.integration.core.PollableChannel; +import org.springframework.integration.history.MessageHistory; +import org.springframework.integration.mail.config.ImapIdleChannelAdapterParserTests; +import org.springframework.integration.test.util.TestUtils; + +import com.sun.mail.imap.IMAPFolder; + +/** + * @author Oleg Zhurakousky + * + */ +public class Pop3MailReceiverTests { + @Test + public void receieveAndDelete() throws Exception{ + AbstractMailReceiver receiver = new Pop3MailReceiver(); + ((Pop3MailReceiver)receiver).setShouldDeleteMessages(true); + receiver = spy(receiver); + receiver.afterPropertiesSet(); + Message msg1 = mock(MimeMessage.class); + Message msg2 = mock(MimeMessage.class); + final Message[] messages = new Message[]{msg1, msg2}; + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + DirectFieldAccessor accessor = new DirectFieldAccessor(invocation.getMock()); + int folderOpenMode = (Integer) accessor.getPropertyValue("folderOpenMode"); + if (folderOpenMode != Folder.READ_WRITE){ + throw new IllegalArgumentException("Folder had to be open in READ_WRITE mode"); + } + return null; + } + }).when(receiver).openFolder(); + + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + return messages; + } + }).when(receiver).searchForNewMessages(); + + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + return null; + } + }).when(receiver).fetchMessages(messages); + receiver.afterPropertiesSet(); + receiver.receive(); + verify(msg1, times(1)).setFlag(Flag.DELETED, true); + verify(msg2, times(1)).setFlag(Flag.DELETED, true); + } + @Test + public void receieveAndDontDelete() throws Exception{ + AbstractMailReceiver receiver = new Pop3MailReceiver(); + ((Pop3MailReceiver)receiver).setShouldDeleteMessages(false); + receiver = spy(receiver); + receiver.afterPropertiesSet(); + Message msg1 = mock(MimeMessage.class); + Message msg2 = mock(MimeMessage.class); + final Message[] messages = new Message[]{msg1, msg2}; + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + DirectFieldAccessor accessor = new DirectFieldAccessor(invocation.getMock()); + int folderOpenMode = (Integer) accessor.getPropertyValue("folderOpenMode"); + if (folderOpenMode == Folder.READ_WRITE){ + throw new IllegalArgumentException("Folder had to be open in READ_ONLY mode"); + } + return null; + } + }).when(receiver).openFolder(); + + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + return messages; + } + }).when(receiver).searchForNewMessages(); + + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + return null; + } + }).when(receiver).fetchMessages(messages); + receiver.afterPropertiesSet(); + receiver.receive(); + verify(msg1, times(0)).setFlag(Flag.DELETED, true); + verify(msg2, times(0)).setFlag(Flag.DELETED, true); + } + @Test @Ignore + public void receieveAndDontSetDeleteFlagWithUrl() throws Exception{ + AbstractMailReceiver receiver = new Pop3MailReceiver("pop3://some.host"); + receiver = spy(receiver); + receiver.afterPropertiesSet(); + Message msg1 = mock(MimeMessage.class); + Message msg2 = mock(MimeMessage.class); + final Message[] messages = new Message[]{msg1, msg2}; + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + DirectFieldAccessor accessor = new DirectFieldAccessor(invocation.getMock()); + int folderOpenMode = (Integer) accessor.getPropertyValue("folderOpenMode"); + if (folderOpenMode == Folder.READ_WRITE){ + throw new IllegalArgumentException("Folder had to be open in READ_ONLY mode"); + } + return null; + } + }).when(receiver).openFolder(); + + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + return messages; + } + }).when(receiver).searchForNewMessages(); + + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + return null; + } + }).when(receiver).fetchMessages(messages); + receiver.afterPropertiesSet(); + receiver.receive(); + verify(msg1, times(0)).setFlag(Flag.DELETED, true); + verify(msg2, times(0)).setFlag(Flag.DELETED, true); + } + @Test + public void receieveAndDontSetDeleteFlagWithoutUrl() throws Exception{ + AbstractMailReceiver receiver = new Pop3MailReceiver(); + receiver = spy(receiver); + receiver.afterPropertiesSet(); + Message msg1 = mock(MimeMessage.class); + Message msg2 = mock(MimeMessage.class); + final Message[] messages = new Message[]{msg1, msg2}; + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + DirectFieldAccessor accessor = new DirectFieldAccessor(invocation.getMock()); + int folderOpenMode = (Integer) accessor.getPropertyValue("folderOpenMode"); + if (folderOpenMode == Folder.READ_WRITE){ + throw new IllegalArgumentException("Folder had to be open in READ_ONLY mode"); + } + return null; + } + }).when(receiver).openFolder(); + + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + return messages; + } + }).when(receiver).searchForNewMessages(); + + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + return null; + } + }).when(receiver).fetchMessages(messages); + receiver.afterPropertiesSet(); + receiver.receive(); + verify(msg1, times(0)).setFlag(Flag.DELETED, true); + verify(msg2, times(0)).setFlag(Flag.DELETED, true); + } +}