INT-3879: Mail: Configurable USER Flag
JIRA: https://jira.spring.io/browse/INT-3879 Namespace support to follow in 4.3. Simple polishing and fix some typos in the `mail.adoc`
This commit is contained in:
committed by
Artem Bilan
parent
eec937b6d9
commit
b3dd85fb4b
@@ -81,7 +81,6 @@ import org.springframework.integration.mail.ImapIdleChannelAdapter.ImapIdleExcep
|
||||
import org.springframework.integration.mail.PoorMansMailServer.ImapServer;
|
||||
import org.springframework.integration.mail.config.ImapIdleChannelAdapterParserTests;
|
||||
import org.springframework.integration.test.support.LongRunningIntegrationTest;
|
||||
import org.springframework.integration.test.util.SocketUtils;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
@@ -103,9 +102,7 @@ public class ImapMailReceiverTests {
|
||||
|
||||
private final AtomicInteger failed = new AtomicInteger(0);
|
||||
|
||||
private final static int imapIdlePort = SocketUtils.findAvailableServerSocket();
|
||||
|
||||
private final static ImapServer imapIdleServer = PoorMansMailServer.imap(imapIdlePort);
|
||||
private final static ImapServer imapIdleServer = PoorMansMailServer.imap(0);
|
||||
|
||||
|
||||
@BeforeClass
|
||||
@@ -123,15 +120,9 @@ public class ImapMailReceiverTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdleWithServer() throws Exception {
|
||||
Properties mailProps = new Properties();
|
||||
mailProps.put("mail.debug", "true");
|
||||
mailProps.put("mail.imap.connectionpool.debug", "true");
|
||||
ImapMailReceiver receiver = new ImapMailReceiver("imap://user:pw@localhost:" + imapIdlePort + "/INBOX");
|
||||
receiver.setJavaMailProperties(mailProps);
|
||||
receiver.setMaxFetchSize(1);
|
||||
receiver.setShouldDeleteMessages(false);
|
||||
receiver.setShouldMarkMessagesAsRead(true);
|
||||
public void testIdleWithServerCustomSearch() throws Exception {
|
||||
ImapMailReceiver receiver = new ImapMailReceiver("imap://user:pw@localhost:" + imapIdleServer.getPort()
|
||||
+ "/INBOX");
|
||||
receiver.setSearchTermStrategy(new SearchTermStrategy() {
|
||||
|
||||
@Override
|
||||
@@ -146,9 +137,30 @@ public class ImapMailReceiverTests {
|
||||
}
|
||||
}
|
||||
});
|
||||
testIdleWithServerGuts(receiver);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdleWithServerDefaultSearch() throws Exception {
|
||||
ImapMailReceiver receiver = new ImapMailReceiver("imap://user:pw@localhost:" + imapIdleServer.getPort()
|
||||
+ "/INBOX");
|
||||
testIdleWithServerGuts(receiver);
|
||||
assertTrue(imapIdleServer.assertReceived("searchWithUserFlag"));
|
||||
}
|
||||
|
||||
public void testIdleWithServerGuts(ImapMailReceiver receiver) throws MessagingException {
|
||||
imapIdleServer.resetServer();
|
||||
Properties mailProps = new Properties();
|
||||
mailProps.put("mail.debug", "true");
|
||||
mailProps.put("mail.imap.connectionpool.debug", "true");
|
||||
receiver.setJavaMailProperties(mailProps);
|
||||
receiver.setMaxFetchSize(1);
|
||||
receiver.setShouldDeleteMessages(false);
|
||||
receiver.setShouldMarkMessagesAsRead(true);
|
||||
receiver.setCancelIdleInterval(8);
|
||||
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
|
||||
setUpScheduler(receiver, taskScheduler);
|
||||
receiver.setUserFlag("testSIUserFlag");
|
||||
receiver.afterPropertiesSet();
|
||||
Log logger = spy(TestUtils.getPropertyValue(receiver, "logger", Log.class));
|
||||
new DirectFieldAccessor(receiver).setPropertyValue("logger", logger);
|
||||
@@ -167,6 +179,7 @@ public class ImapMailReceiverTests {
|
||||
assertNull(channel.receive(10000)); // no new message after second and third idle
|
||||
verify(logger).debug("Canceling IDLE");
|
||||
taskScheduler.shutdown();
|
||||
assertTrue(imapIdleServer.assertReceived("storeUserFlag"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -464,9 +477,9 @@ public class ImapMailReceiverTests {
|
||||
doAnswer(new Answer<Object>() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
DirectFieldAccessor accesor = new DirectFieldAccessor((invocation.getMock()));
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor((invocation.getMock()));
|
||||
IMAPFolder folder = mock(IMAPFolder.class);
|
||||
accesor.setPropertyValue("folder", folder);
|
||||
accessor.setPropertyValue("folder", folder);
|
||||
when(folder.hasNewMessages()).thenReturn(true);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -21,6 +21,7 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.mail.Flags;
|
||||
@@ -45,7 +46,21 @@ public class ImapMailSearchTermsTests {
|
||||
|
||||
@Test
|
||||
public void validateSearchTermsWhenShouldMarkAsReadNoExistingFlags() throws Exception {
|
||||
String userFlag = AbstractMailReceiver.DEFAULT_SI_USER_FLAG;
|
||||
ImapMailReceiver receiver = new ImapMailReceiver();
|
||||
validateSearchTermsWhenShouldMarkAsReadNoExistingFlagsGuts(userFlag, receiver);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSearchTermsWhenShouldMarkAsReadNoExistingFlagsCustom() throws Exception {
|
||||
String userFlag = "foo";
|
||||
ImapMailReceiver receiver = new ImapMailReceiver();
|
||||
receiver.setUserFlag(userFlag);
|
||||
validateSearchTermsWhenShouldMarkAsReadNoExistingFlagsGuts(userFlag, receiver);
|
||||
}
|
||||
|
||||
public void validateSearchTermsWhenShouldMarkAsReadNoExistingFlagsGuts(String userFlag, ImapMailReceiver receiver)
|
||||
throws NoSuchFieldException, IllegalAccessException, InvocationTargetException {
|
||||
receiver.setShouldMarkMessagesAsRead(true);
|
||||
receiver.setBeanFactory(mock(BeanFactory.class));
|
||||
|
||||
@@ -62,9 +77,10 @@ public class ImapMailSearchTermsTests {
|
||||
assertTrue(searchTerms instanceof NotTerm);
|
||||
NotTerm notTerm = (NotTerm) searchTerms;
|
||||
Flags siFlags = new Flags();
|
||||
siFlags.add(AbstractMailReceiver.SI_USER_FLAG);
|
||||
notTerm.getTerm().equals(siFlags);
|
||||
siFlags.add(userFlag);
|
||||
assertEquals(siFlags, ((FlagTerm)notTerm.getTerm()).getFlags());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSearchTermsWhenShouldMarkAsReadWithExistingFlags() throws Exception {
|
||||
ImapMailReceiver receiver = new ImapMailReceiver();
|
||||
@@ -91,7 +107,7 @@ public class ImapMailSearchTermsTests {
|
||||
assertTrue(((FlagTerm)notTerm.getTerm()).getFlags().contains(Flag.ANSWERED));
|
||||
notTerm = (NotTerm) terms[1];
|
||||
Flags siFlags = new Flags();
|
||||
siFlags.add(AbstractMailReceiver.SI_USER_FLAG);
|
||||
siFlags.add(AbstractMailReceiver.DEFAULT_SI_USER_FLAG);
|
||||
assertTrue(((FlagTerm)notTerm.getTerm()).getFlags().contains(siFlags));
|
||||
}
|
||||
|
||||
@@ -114,4 +130,5 @@ public class ImapMailSearchTermsTests {
|
||||
SearchTerm searchTerms = (SearchTerm) compileSearchTerms.invoke(receiver, flags);
|
||||
assertTrue(searchTerms instanceof NotTerm);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2015 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.
|
||||
@@ -23,7 +23,9 @@ import java.io.OutputStreamWriter;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@@ -209,6 +211,13 @@ public class PoorMansMailServer {
|
||||
super(port);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetServer() {
|
||||
super.resetServer();
|
||||
this.seen = false;
|
||||
this.idled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MailHandler mailHandler(Socket socket) {
|
||||
return new ImapHandler(socket);
|
||||
@@ -255,19 +264,18 @@ public class PoorMansMailServer {
|
||||
else {
|
||||
write("* OK");
|
||||
}
|
||||
write("* OK [PERMANENTFLAGS (\\Deleted \\Seen \\*)]"); // \* - user flags allowed
|
||||
write(tag + "OK SELECT completed");
|
||||
}
|
||||
else if (line.endsWith("EXAMINE INBOX")) {
|
||||
write(tag + "OK");
|
||||
}
|
||||
else if (line.endsWith("SEARCH FROM bar@baz UNSEEN ALL")) {
|
||||
if (seen) {
|
||||
write("* SEARCH");
|
||||
}
|
||||
else {
|
||||
write("* SEARCH 1");
|
||||
}
|
||||
write(tag + "OK SEARCH completed");
|
||||
searchReply(tag);
|
||||
}
|
||||
else if (line.endsWith("SEARCH NOT (DELETED) NOT (SEEN) NOT (KEYWORD testSIUserFlag) ALL")) {
|
||||
searchReply(tag);
|
||||
assertions.add("searchWithUserFlag");
|
||||
}
|
||||
else if (line.contains("FETCH 1 (ENVELOPE")) {
|
||||
write("* 1 FETCH (RFC822.SIZE 6909 INTERNALDATE \"27-May-2013 09:45:41 +0000\" "
|
||||
@@ -312,6 +320,10 @@ public class PoorMansMailServer {
|
||||
else if (line.contains("NOOP")) {
|
||||
write(tag + "OK NOOP completed");
|
||||
}
|
||||
else if(line.endsWith("STORE 1 +FLAGS (testSIUserFlag)")) {
|
||||
write(tag + "OK STORE completed");
|
||||
assertions.add("storeUserFlag");
|
||||
}
|
||||
else if (line.endsWith("IDLE")) {
|
||||
write("+ idling");
|
||||
idleTag = tag;
|
||||
@@ -341,6 +353,16 @@ public class PoorMansMailServer {
|
||||
}
|
||||
}
|
||||
|
||||
public void searchReply(String tag) throws IOException {
|
||||
if (seen) {
|
||||
write("* SEARCH");
|
||||
}
|
||||
else {
|
||||
write("* SEARCH 1");
|
||||
}
|
||||
write(tag + "OK SEARCH completed");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -351,6 +373,8 @@ public class PoorMansMailServer {
|
||||
|
||||
private final ExecutorService exec = Executors.newCachedThreadPool();
|
||||
|
||||
protected final Set<String> assertions = new HashSet<String>();
|
||||
|
||||
protected final List<String> messages = new ArrayList<String>();
|
||||
|
||||
private volatile boolean listening;
|
||||
@@ -361,6 +385,10 @@ public class PoorMansMailServer {
|
||||
exec.execute(this);
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return this.socket.getLocalPort();
|
||||
}
|
||||
|
||||
public boolean isListening() {
|
||||
return listening;
|
||||
}
|
||||
@@ -369,6 +397,14 @@ public class PoorMansMailServer {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public void resetServer() {
|
||||
this.assertions.clear();
|
||||
}
|
||||
|
||||
public boolean assertReceived(String assertion) {
|
||||
return this.assertions.contains(assertion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
|
||||
@@ -64,6 +64,7 @@ public class ImapIdleIntegrationTests {
|
||||
doAnswer(new Answer<Object>() { // ensures that waitFornewMessages call blocks after a first execution
|
||||
// to emulate the behavior of IDLE
|
||||
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
if (block.get()) {
|
||||
Thread.sleep(5000);
|
||||
@@ -103,7 +104,7 @@ public class ImapIdleIntegrationTests {
|
||||
assertTrue(txProcessorLatch.await(10, TimeUnit.SECONDS));
|
||||
|
||||
adapter.stop();
|
||||
context.destroy();
|
||||
context.close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user