INT-1375, INT-1376, Added support for Flags.SEEN. Added namespace support for should-mark-messages-as-read for IMAP idle, test cases
This commit is contained in:
@@ -147,19 +147,20 @@ public abstract class AbstractMailReceiver implements MailReceiver, DisposableBe
|
||||
* Specify whether mail messages should be deleted after retrieval.
|
||||
*/
|
||||
public void setShouldDeleteMessages(boolean shouldDeleteMessages) {
|
||||
if (this.shouldMarkMessagesAsRead && shouldDeleteMessages){
|
||||
throw new IllegalArgumentException("setting both 'shouldDeleteMessages' and 'shouldMarkMessagesAsRead' to true is not allowed");
|
||||
}
|
||||
this.shouldDeleteMessages = shouldDeleteMessages;
|
||||
}
|
||||
/**
|
||||
* Check if messages should be marked as read
|
||||
* @return
|
||||
*/
|
||||
public boolean isShouldMarkMessagesAsRead() {
|
||||
return shouldMarkMessagesAsRead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify is messages should be marked as read
|
||||
* @return
|
||||
*/
|
||||
public void setShouldMarkMessagesAsRead(boolean shouldMarkMessagesAsRead) {
|
||||
if (this.shouldDeleteMessages && shouldMarkMessagesAsRead){
|
||||
throw new IllegalArgumentException("setting both 'shouldDeleteMessages' and 'shouldMarkMessagesAsRead' to true is not allowed");
|
||||
}
|
||||
this.shouldMarkMessagesAsRead = shouldMarkMessagesAsRead;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* @author Jonas Partner
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
public class ImapIdleChannelAdapterParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
@@ -79,6 +80,7 @@ public class ImapIdleChannelAdapterParser extends AbstractSingleBeanDefinitionPa
|
||||
}
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(receiverBuilder, element, "max-fetch-size");
|
||||
receiverBuilder.addPropertyValue("shouldDeleteMessages", element.getAttribute("should-delete-messages"));
|
||||
receiverBuilder.addPropertyValue("shouldMarkMessagesAsRead", element.getAttribute("should-mark-messages-as-read"));
|
||||
return receiverBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.util.xml.DomUtils;
|
||||
*
|
||||
* @author Jonas Partner
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
public class MailInboundChannelAdapterParser extends AbstractPollingInboundChannelAdapterParser {
|
||||
|
||||
@@ -80,6 +81,7 @@ public class MailInboundChannelAdapterParser extends AbstractPollingInboundChann
|
||||
}
|
||||
}
|
||||
receiverBuilder.addPropertyValue("shouldDeleteMessages", element.getAttribute("should-delete-messages"));
|
||||
receiverBuilder.addPropertyValue("shouldMarkMessagesAsRead", element.getAttribute("should-mark-messages-as-read"));
|
||||
return receiverBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ import javax.mail.Authenticator;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.URLName;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.integration.mail.AbstractMailReceiver;
|
||||
@@ -33,9 +35,11 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 1.0.3
|
||||
*/
|
||||
public class MailReceiverFactoryBean implements FactoryBean<MailReceiver>, DisposableBean {
|
||||
protected final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
private volatile String storeUri;
|
||||
|
||||
@@ -54,6 +58,8 @@ public class MailReceiverFactoryBean implements FactoryBean<MailReceiver>, Dispo
|
||||
* This value will be <code>null</code> <i>unless</i> explicitly configured.
|
||||
*/
|
||||
private volatile Boolean shouldDeleteMessages = null;
|
||||
|
||||
private volatile boolean shouldMarkMessagesAsRead;
|
||||
|
||||
private volatile int maxFetchSize = 1;
|
||||
|
||||
@@ -141,6 +147,11 @@ public class MailReceiverFactoryBean implements FactoryBean<MailReceiver>, Dispo
|
||||
receiver.setShouldDeleteMessages(this.shouldDeleteMessages);
|
||||
}
|
||||
receiver.setMaxFetchSize(this.maxFetchSize);
|
||||
if (isPop3 && this.shouldMarkMessagesAsRead){
|
||||
logger.warn("Setting 'should-mark-messages-as-read' to 'true' while using POP3 has no effect");
|
||||
} else {
|
||||
receiver.setShouldMarkMessagesAsRead(this.shouldMarkMessagesAsRead);
|
||||
}
|
||||
return receiver;
|
||||
}
|
||||
|
||||
@@ -149,5 +160,13 @@ public class MailReceiverFactoryBean implements FactoryBean<MailReceiver>, Dispo
|
||||
((DisposableBean) this.receiver).destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isShouldMarkMessagesAsRead() {
|
||||
return shouldMarkMessagesAsRead;
|
||||
}
|
||||
|
||||
public void setShouldMarkMessagesAsRead(boolean shouldMarkMessagesAsRead) {
|
||||
this.shouldMarkMessagesAsRead = shouldMarkMessagesAsRead;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -188,13 +188,20 @@
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="should-delete-messages" type="xsd:string" use="required">
|
||||
<xsd:attribute name="should-delete-messages" type="xsd:string" use="optional" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specify whether mail messages should be deleted after retrieval.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="should-mark-messages-as-read" type="xsd:string" use="optional" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specify whether mail messages should be marked as read aftre being retrieved (Not supported in POP3).
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="auto-startup" type="xsd:string" default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
|
||||
@@ -20,6 +20,7 @@ import javax.mail.Flags.Flag;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
@@ -34,28 +35,9 @@ import static org.mockito.Mockito.verify;
|
||||
*
|
||||
*/
|
||||
public class AbstractMailReceiverTests {
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void validateDeleteAndReadIsNotAllowed(){
|
||||
AbstractMailReceiver receiver = new ImapMailReceiver();
|
||||
receiver.setShouldDeleteMessages(true);
|
||||
receiver.setShouldMarkMessagesAsRead(true);
|
||||
}
|
||||
@Test
|
||||
public void validateDeleteOrReadIsAllowed_Read(){
|
||||
AbstractMailReceiver receiver = new ImapMailReceiver();
|
||||
receiver.setShouldDeleteMessages(false);
|
||||
receiver.setShouldMarkMessagesAsRead(true);
|
||||
}
|
||||
@Test
|
||||
public void validateDeleteOrReadIsAllowed_Delete(){
|
||||
AbstractMailReceiver receiver = new ImapMailReceiver();
|
||||
receiver.setShouldDeleteMessages(true);
|
||||
receiver.setShouldMarkMessagesAsRead(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void receieveAndMarkAsRead() throws Exception{
|
||||
public void receieveAndMarkAsReadDontDelete() throws Exception{
|
||||
AbstractMailReceiver receiver = new ImapMailReceiver();
|
||||
receiver.setShouldMarkMessagesAsRead(true);
|
||||
receiver = spy(receiver);
|
||||
@@ -83,6 +65,39 @@ public class AbstractMailReceiverTests {
|
||||
receiver.receive();
|
||||
verify(msg1, times(1)).setFlag(Flag.SEEN, true);
|
||||
verify(msg2, times(1)).setFlag(Flag.SEEN, true);
|
||||
verify(receiver, times(0)).deleteMessages((Message[]) Mockito.any());
|
||||
}
|
||||
@Test
|
||||
public void receieveMarkAsReadAndDelete() throws Exception{
|
||||
AbstractMailReceiver receiver = new ImapMailReceiver();
|
||||
receiver.setShouldMarkMessagesAsRead(true);
|
||||
receiver.setShouldDeleteMessages(true);
|
||||
receiver = spy(receiver);
|
||||
Message msg1 = mock(MimeMessage.class);
|
||||
Message msg2 = mock(MimeMessage.class);
|
||||
final Message[] messages = new Message[]{msg1, msg2};
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
// just to avoid the exception
|
||||
return null;
|
||||
}
|
||||
}).when(receiver).openFolder();
|
||||
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
return messages;
|
||||
}
|
||||
}).when(receiver).searchForNewMessages();
|
||||
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
return null;
|
||||
}
|
||||
}).when(receiver).fetchMessages(messages);
|
||||
receiver.receive();
|
||||
verify(msg1, times(1)).setFlag(Flag.SEEN, true);
|
||||
verify(msg2, times(1)).setFlag(Flag.SEEN, true);
|
||||
verify(receiver, times(1)).deleteMessages((Message[]) Mockito.any());
|
||||
}
|
||||
@Test
|
||||
public void receieveAndDontMarkAsRead() throws Exception{
|
||||
|
||||
@@ -32,6 +32,13 @@
|
||||
channel="channel"
|
||||
auto-startup="false"
|
||||
should-delete-messages="true"/>
|
||||
|
||||
<mail:imap-idle-channel-adapter id="simpleAdapterMarkAsRead"
|
||||
store-uri="imap:foo"
|
||||
channel="channel"
|
||||
auto-startup="false"
|
||||
should-delete-messages="true"
|
||||
should-mark-messages-as-read="true"/>
|
||||
|
||||
<mail:imap-idle-channel-adapter id="customAdapter"
|
||||
store-uri="imap:foo"
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
@@ -63,6 +64,26 @@ public class ImapIdleChannelAdapterParserTests {
|
||||
Properties properties = (Properties) receiverAccessor.getPropertyValue("javaMailProperties");
|
||||
assertEquals(0, properties.size());
|
||||
assertEquals(Boolean.TRUE, receiverAccessor.getPropertyValue("shouldDeleteMessages"));
|
||||
assertEquals(Boolean.FALSE, receiverAccessor.getPropertyValue("shouldMarkMessagesAsRead"));
|
||||
}
|
||||
@Test
|
||||
public void simpleAdapterWithMarkeMessagesAsRead() {
|
||||
Object adapter = context.getBean("simpleAdapterMarkAsRead");
|
||||
assertEquals(ImapIdleChannelAdapter.class, adapter.getClass());
|
||||
DirectFieldAccessor adapterAccessor = new DirectFieldAccessor(adapter);
|
||||
Object channel = context.getBean("channel");
|
||||
assertSame(channel, adapterAccessor.getPropertyValue("outputChannel"));
|
||||
assertNull(adapterAccessor.getPropertyValue("taskExecutor"));
|
||||
assertEquals(Boolean.FALSE, adapterAccessor.getPropertyValue("autoStartup"));
|
||||
Object receiver = adapterAccessor.getPropertyValue("mailReceiver");
|
||||
assertEquals(ImapMailReceiver.class, receiver.getClass());
|
||||
DirectFieldAccessor receiverAccessor = new DirectFieldAccessor(receiver);
|
||||
Object url = receiverAccessor.getPropertyValue("url");
|
||||
assertEquals(new URLName("imap:foo"), url);
|
||||
Properties properties = (Properties) receiverAccessor.getPropertyValue("javaMailProperties");
|
||||
assertEquals(0, properties.size());
|
||||
assertEquals(Boolean.TRUE, receiverAccessor.getPropertyValue("shouldDeleteMessages"));
|
||||
assertEquals(Boolean.TRUE, receiverAccessor.getPropertyValue("shouldMarkMessagesAsRead"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -93,6 +93,8 @@
|
||||
<mail:inbound-channel-adapter id="imapWithoutStoreUri" channel="testChannel" protocol="imap" should-delete-messages="false" auto-startup="false"/>
|
||||
|
||||
<mail:imap-idle-channel-adapter id="imapIdleWithoutStoreUri" channel="testChannel" should-delete-messages="false" auto-startup="false"/>
|
||||
|
||||
<mail:inbound-channel-adapter id="pop3ShouldMarkAsReadTrue" channel="testChannel" protocol="pop3" should-delete-messages="false" auto-startup="false" should-mark-messages-as-read="true"/>
|
||||
|
||||
|
||||
<!-- COMMON CONFIGURATION -->
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 1.0.5
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@@ -62,6 +63,14 @@ public class InboundChannelAdapterParserTests {
|
||||
Boolean value = (Boolean) new DirectFieldAccessor(receiver).getPropertyValue("shouldDeleteMessages");
|
||||
assertTrue(value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pop3ShouldMarkMessagesAsRead() {
|
||||
AbstractMailReceiver receiver = this.getReceiver("pop3ShouldMarkAsReadTrue");
|
||||
assertEquals(Pop3MailReceiver.class, receiver.getClass());
|
||||
Boolean value = (Boolean) new DirectFieldAccessor(receiver).getPropertyValue("shouldMarkMessagesAsRead");
|
||||
assertFalse(value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pop3ShouldDeleteFalse() {
|
||||
|
||||
Reference in New Issue
Block a user