INT-1849/INT-2606 Pseudo Transactional Message Src

Initial commit.

Tested with POP3 and IMAP (James) with Sample app.

Essentially moved all the flagging and deleting code
from receive() to closeContextAfterSuccess().

For non-transactional cases, this new method is
called immediately after receiving the message(s),
essentially working as before.

When run from a <transactional/> poller it is
called using TransactionSynchronization after
the transaction commits.

This behavior can be changed by setting
'symchronized="false"' on the poller, which
removes the synchronization and the update
is called immediately after the receive().

Polishing

PR Comments

Update Reference
This commit is contained in:
Gary Russell
2012-06-12 13:31:21 -04:00
committed by Oleg Zhurakousky
parent 4e9a393983
commit 9bc9867d31
27 changed files with 998 additions and 263 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 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.
@@ -17,6 +17,7 @@ package org.springframework.integration.mail;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -24,8 +25,9 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.lang.reflect.Field;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.mail.Flags;
@@ -42,7 +44,6 @@ 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;
@@ -51,6 +52,7 @@ import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.core.PollableChannel;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
import org.springframework.integration.history.MessageHistory;
import org.springframework.integration.mail.MailReceiver.MailReceiverContext;
import org.springframework.integration.mail.config.ImapIdleChannelAdapterParserTests;
import org.springframework.integration.test.util.TestUtils;
@@ -71,11 +73,9 @@ public class ImapMailReceiverTests {
((ImapMailReceiver)receiver).setShouldMarkMessagesAsRead(true);
receiver = spy(receiver);
receiver.afterPropertiesSet();
Field folderField = AbstractMailReceiver.class.getDeclaredField("folder");
folderField.setAccessible(true);
Folder folder = mock(Folder.class);
MailReceiverContext context = MailTestsHelper.setupContextHolder(receiver);
Folder folder = context.getFolder();
when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER));
folderField.set(receiver, folder);
Message msg1 = mock(MimeMessage.class);
Message msg2 = mock(MimeMessage.class);
@@ -105,6 +105,7 @@ public class ImapMailReceiverTests {
}
}).when(receiver).fetchMessages(messages);
receiver.receive();
receiver.closeContextAfterSuccess(context);
verify(msg1, times(1)).setFlag(Flag.SEEN, true);
verify(msg2, times(1)).setFlag(Flag.SEEN, true);
verify(receiver, times(0)).deleteMessages((Message[]) Mockito.any());
@@ -117,11 +118,9 @@ public class ImapMailReceiverTests {
receiver = spy(receiver);
receiver.afterPropertiesSet();
Field folderField = AbstractMailReceiver.class.getDeclaredField("folder");
folderField.setAccessible(true);
Folder folder = mock(Folder.class);
MailReceiverContext context = MailTestsHelper.setupContextHolder(receiver);
Folder folder = context.getFolder();
when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER));
folderField.set(receiver, folder);
Message msg1 = mock(MimeMessage.class);
Message msg2 = mock(MimeMessage.class);
@@ -149,6 +148,7 @@ public class ImapMailReceiverTests {
}
}).when(receiver).fetchMessages(messages);
receiver.receive();
receiver.closeContextAfterSuccess(context);
verify(msg1, times(1)).setFlag(Flag.SEEN, true);
verify(msg2, times(1)).setFlag(Flag.SEEN, true);
verify(receiver, times(1)).deleteMessages((Message[]) Mockito.any());
@@ -160,11 +160,9 @@ public class ImapMailReceiverTests {
receiver = spy(receiver);
receiver.afterPropertiesSet();
Field folderField = AbstractMailReceiver.class.getDeclaredField("folder");
folderField.setAccessible(true);
Folder folder = mock(Folder.class);
MailReceiverContext context = MailTestsHelper.setupContextHolder(receiver);
Folder folder = context.getFolder();
when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER));
folderField.set(receiver, folder);
Message msg1 = mock(MimeMessage.class);
@@ -189,6 +187,7 @@ public class ImapMailReceiverTests {
}).when(receiver).fetchMessages(messages);
receiver.afterPropertiesSet();
receiver.receive();
receiver.closeContextAfterFailure(context);
verify(msg1, times(0)).setFlag(Flag.SEEN, true);
verify(msg2, times(0)).setFlag(Flag.SEEN, true);
}
@@ -200,11 +199,9 @@ public class ImapMailReceiverTests {
receiver = spy(receiver);
receiver.afterPropertiesSet();
Field folderField = AbstractMailReceiver.class.getDeclaredField("folder");
folderField.setAccessible(true);
Folder folder = mock(Folder.class);
MailReceiverContext context = MailTestsHelper.setupContextHolder(receiver);
Folder folder = context.getFolder();
when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER));
folderField.set(receiver, folder);
Message msg1 = mock(MimeMessage.class);
Message msg2 = mock(MimeMessage.class);
@@ -233,6 +230,7 @@ public class ImapMailReceiverTests {
}).when(receiver).fetchMessages(messages);
receiver.afterPropertiesSet();
receiver.receive();
receiver.closeContextAfterSuccess(context);
verify(msg1, times(0)).setFlag(Flag.SEEN, true);
verify(msg2, times(0)).setFlag(Flag.SEEN, true);
verify(msg1, times(1)).setFlag(Flag.DELETED, true);
@@ -244,11 +242,9 @@ public class ImapMailReceiverTests {
receiver = spy(receiver);
receiver.afterPropertiesSet();
Field folderField = AbstractMailReceiver.class.getDeclaredField("folder");
folderField.setAccessible(true);
Folder folder = mock(Folder.class);
MailReceiverContext context = MailTestsHelper.setupContextHolder(receiver);
Folder folder = context.getFolder();
when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER));
folderField.set(receiver, folder);
Message msg1 = mock(MimeMessage.class);
Message msg2 = mock(MimeMessage.class);
@@ -276,6 +272,7 @@ public class ImapMailReceiverTests {
}
}).when(receiver).fetchMessages(messages);
receiver.receive();
receiver.closeContextAfterSuccess(context);
verify(msg1, times(1)).setFlag(Flag.SEEN, true);
verify(msg2, times(1)).setFlag(Flag.SEEN, true);
verify(receiver, times(0)).deleteMessages((Message[]) Mockito.any());
@@ -357,11 +354,10 @@ public class ImapMailReceiverTests {
receiver = spy(receiver);
receiver.afterPropertiesSet();
Field folderField = AbstractMailReceiver.class.getDeclaredField("folder");
folderField.setAccessible(true);
Folder folder = mock(IMAPFolder.class);
@SuppressWarnings("unchecked")
final ThreadLocal<MailReceiverContext> contextHolder = TestUtils.getPropertyValue(receiver, "contextHolder", ThreadLocal.class);
final Folder folder = mock(IMAPFolder.class);
when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER));
folderField.set(receiver, folder);
doAnswer(new Answer<Object>() {
public Object answer(InvocationOnMock invocation) throws Throwable {
@@ -371,6 +367,7 @@ public class ImapMailReceiverTests {
doAnswer(new Answer<Object>() {
public Object answer(InvocationOnMock invocation) throws Throwable {
contextHolder.set(new MailReceiverContext(folder));
return null;
}
}).when(receiver).openFolder();
@@ -404,7 +401,12 @@ public class ImapMailReceiverTests {
@Test // see INT-1801
public void testImapLifecycleForRaceCondition() throws Exception{
for (int i = 0; i < 1000; i++) {
int count = 1000;
final CountDownLatch receiveLatch = new CountDownLatch(count);
final CountDownLatch destroyLatch = new CountDownLatch(count);
final AtomicInteger receiveCount = new AtomicInteger();
final AtomicInteger destroyCount = new AtomicInteger();
for (int i = 0; i < count; i++) {
final ImapMailReceiver receiver = new ImapMailReceiver("imap://foo");
Store store = mock(Store.class);
Folder folder = mock(Folder.class);
@@ -429,7 +431,8 @@ public class ImapMailReceiverTests {
failed.getAndIncrement();
}
}
receiveCount.incrementAndGet();
receiveLatch.countDown();
}
}).start();
@@ -441,9 +444,13 @@ public class ImapMailReceiverTests {
// ignore
ignore.printStackTrace();
}
destroyCount.incrementAndGet();
destroyLatch.countDown();
}
}).start();
}
assertTrue("Only " + receiveCount.get() + " receive() calls", receiveLatch.await(10, TimeUnit.SECONDS));
assertTrue("Only " + receiveCount.get() + " destroy() calls", destroyLatch.await(10, TimeUnit.SECONDS));
assertEquals(0, failed.get());
}
@@ -455,4 +462,5 @@ public class ImapMailReceiverTests {
receiver.setSearchTermStrategy(stStrategy);
assertEquals(stStrategy, TestUtils.getPropertyValue(receiver, "searchTermStrategy"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 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.
@@ -17,10 +17,8 @@ package org.springframework.integration.mail;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.mail.Flags;
@@ -32,11 +30,12 @@ import javax.mail.search.NotTerm;
import javax.mail.search.SearchTerm;
import org.junit.Test;
import org.springframework.integration.mail.MailReceiver.MailReceiverContext;
import org.springframework.util.ReflectionUtils;
/**
* @author Oleg Zhurakousky
* @author Gary Russell
*
*/
public class ImapMailSearchTermsTests {
@@ -45,13 +44,12 @@ public class ImapMailSearchTermsTests {
public void validateSearchTermsWhenShouldMarkAsReadNoExistingFlags() throws Exception {
ImapMailReceiver receiver = new ImapMailReceiver();
receiver.setShouldMarkMessagesAsRead(true);
Field folderField = AbstractMailReceiver.class.getDeclaredField("folder");
folderField.setAccessible(true);
Folder folder = mock(Folder.class);
MailReceiverContext context = MailTestsHelper.setupContextHolder(receiver);
Folder folder = context.getFolder();
when(folder.isOpen()).thenReturn(true);
when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER));
folderField.set(receiver, folder);
Method compileSearchTerms = ReflectionUtils.findMethod(receiver.getClass(), "compileSearchTerms", Flags.class);
compileSearchTerms.setAccessible(true);
Flags flags = new Flags();
@@ -66,14 +64,13 @@ public class ImapMailSearchTermsTests {
public void validateSearchTermsWhenShouldMarkAsReadWithExistingFlags() throws Exception {
ImapMailReceiver receiver = new ImapMailReceiver();
receiver.setShouldMarkMessagesAsRead(true);
receiver.afterPropertiesSet();
Field folderField = AbstractMailReceiver.class.getDeclaredField("folder");
folderField.setAccessible(true);
Folder folder = mock(Folder.class);
MailReceiverContext context = MailTestsHelper.setupContextHolder(receiver);
Folder folder = context.getFolder();
when(folder.isOpen()).thenReturn(true);
when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER));
folderField.set(receiver, folder);
Method compileSearchTerms = ReflectionUtils.findMethod(receiver.getClass(), "compileSearchTerms", Flags.class);
compileSearchTerms.setAccessible(true);
Flags flags = new Flags();
@@ -90,19 +87,18 @@ public class ImapMailSearchTermsTests {
siFlags.add(AbstractMailReceiver.SI_USER_FLAG);
assertTrue(((FlagTerm)notTerm.getTerm()).getFlags().contains(siFlags));
}
@Test
public void validateSearchTermsWhenShouldNotMarkAsReadNoExistingFlags() throws Exception {
ImapMailReceiver receiver = new ImapMailReceiver();
receiver.setShouldMarkMessagesAsRead(false);
receiver.afterPropertiesSet();
Field folderField = AbstractMailReceiver.class.getDeclaredField("folder");
folderField.setAccessible(true);
Folder folder = mock(Folder.class);
MailReceiverContext context = MailTestsHelper.setupContextHolder(receiver);
Folder folder = context.getFolder();
when(folder.isOpen()).thenReturn(true);
when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER));
folderField.set(receiver, folder);
Method compileSearchTerms = ReflectionUtils.findMethod(receiver.getClass(), "compileSearchTerms", Flags.class);
compileSearchTerms.setAccessible(true);
Flags flags = new Flags();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 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.
@@ -29,6 +29,7 @@ import org.junit.Test;
/**
* @author Jonas Partner
* @author Mark Fisher
* @author Gary Russell
*/
public class MailReceivingMessageSourceTests {
@@ -71,6 +72,17 @@ public class MailReceivingMessageSourceTests {
public void stop() {
}
public MailReceiverContext getTransactionContext() {
return null;
}
public void closeContextAfterSuccess(MailReceiverContext context) {
}
public void closeContextAfterFailure(MailReceiverContext context) {
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2012 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.
@@ -16,12 +16,19 @@
package org.springframework.integration.mail;
import static org.mockito.Mockito.mock;
import javax.mail.Folder;
import org.springframework.integration.Message;
import org.springframework.integration.mail.MailReceiver.MailReceiverContext;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.mail.SimpleMailMessage;
/**
* @author Marius Bogoevici
* @author Gary Russell
*/
public class MailTestsHelper {
@@ -66,4 +73,13 @@ public class MailTestsHelper {
.build();
}
public static MailReceiverContext setupContextHolder(AbstractMailReceiver receiver) {
@SuppressWarnings("unchecked")
ThreadLocal<MailReceiverContext> contextHolder = TestUtils.getPropertyValue(receiver, "contextHolder",ThreadLocal.class);
Folder folder = mock(Folder.class);
MailReceiverContext context = new MailReceiverContext(folder);
contextHolder.set(context);
return context;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 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,10 +23,11 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicReference;
import javax.mail.Flags.Flag;
import javax.mail.Flags;
import javax.mail.Flags.Flag;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.internet.MimeMessage;
@@ -35,9 +36,18 @@ import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.mail.MailReceiver.MailReceiverContext;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionSynchronizationUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.MethodCallback;
/**
* @author Oleg Zhurakousky
* @author Gary Russell
*
*/
public class Pop3MailReceiverTests {
@@ -47,13 +57,11 @@ public class Pop3MailReceiverTests {
((Pop3MailReceiver)receiver).setShouldDeleteMessages(true);
receiver = spy(receiver);
receiver.afterPropertiesSet();
Field folderField = AbstractMailReceiver.class.getDeclaredField("folder");
folderField.setAccessible(true);
Folder folder = mock(Folder.class);
MailReceiverContext context = MailTestsHelper.setupContextHolder(receiver);
Folder folder = context.getFolder();
when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER));
folderField.set(receiver, folder);
Message msg1 = mock(MimeMessage.class);
Message msg2 = mock(MimeMessage.class);
final Message[] messages = new Message[]{msg1, msg2};
@@ -67,13 +75,13 @@ public class Pop3MailReceiverTests {
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;
@@ -81,6 +89,7 @@ public class Pop3MailReceiverTests {
}).when(receiver).fetchMessages(messages);
receiver.afterPropertiesSet();
receiver.receive();
receiver.closeContextAfterSuccess(context);
verify(msg1, times(1)).setFlag(Flag.DELETED, true);
verify(msg2, times(1)).setFlag(Flag.DELETED, true);
}
@@ -90,13 +99,11 @@ public class Pop3MailReceiverTests {
((Pop3MailReceiver)receiver).setShouldDeleteMessages(false);
receiver = spy(receiver);
receiver.afterPropertiesSet();
Field folderField = AbstractMailReceiver.class.getDeclaredField("folder");
folderField.setAccessible(true);
Folder folder = mock(Folder.class);
MailReceiverContext context = MailTestsHelper.setupContextHolder(receiver);
Folder folder = context.getFolder();
when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER));
folderField.set(receiver, folder);
Message msg1 = mock(MimeMessage.class);
Message msg2 = mock(MimeMessage.class);
final Message[] messages = new Message[]{msg1, msg2};
@@ -105,13 +112,13 @@ public class Pop3MailReceiverTests {
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;
@@ -119,6 +126,7 @@ public class Pop3MailReceiverTests {
}).when(receiver).fetchMessages(messages);
receiver.afterPropertiesSet();
receiver.receive();
receiver.closeContextAfterFailure(context);
verify(msg1, times(0)).setFlag(Flag.DELETED, true);
verify(msg2, times(0)).setFlag(Flag.DELETED, true);
}
@@ -127,13 +135,11 @@ public class Pop3MailReceiverTests {
AbstractMailReceiver receiver = new Pop3MailReceiver("pop3://some.host");
receiver = spy(receiver);
receiver.afterPropertiesSet();
Field folderField = AbstractMailReceiver.class.getDeclaredField("folder");
folderField.setAccessible(true);
Folder folder = mock(Folder.class);
MailReceiverContext context = MailTestsHelper.setupContextHolder(receiver);
Folder folder = context.getFolder();
when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER));
folderField.set(receiver, folder);
Message msg1 = mock(MimeMessage.class);
Message msg2 = mock(MimeMessage.class);
final Message[] messages = new Message[]{msg1, msg2};
@@ -142,13 +148,13 @@ public class Pop3MailReceiverTests {
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;
@@ -156,6 +162,7 @@ public class Pop3MailReceiverTests {
}).when(receiver).fetchMessages(messages);
receiver.afterPropertiesSet();
receiver.receive();
receiver.closeContextAfterFailure(context);
verify(msg1, times(0)).setFlag(Flag.DELETED, true);
verify(msg2, times(0)).setFlag(Flag.DELETED, true);
}
@@ -164,13 +171,11 @@ public class Pop3MailReceiverTests {
AbstractMailReceiver receiver = new Pop3MailReceiver();
receiver = spy(receiver);
receiver.afterPropertiesSet();
Field folderField = AbstractMailReceiver.class.getDeclaredField("folder");
folderField.setAccessible(true);
Folder folder = mock(Folder.class);
MailReceiverContext context = MailTestsHelper.setupContextHolder(receiver);
Folder folder = context.getFolder();
when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER));
folderField.set(receiver, folder);
Message msg1 = mock(MimeMessage.class);
Message msg2 = mock(MimeMessage.class);
final Message[] messages = new Message[]{msg1, msg2};
@@ -179,13 +184,13 @@ public class Pop3MailReceiverTests {
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;
@@ -193,7 +198,82 @@ public class Pop3MailReceiverTests {
}).when(receiver).fetchMessages(messages);
receiver.afterPropertiesSet();
receiver.receive();
receiver.closeContextAfterFailure(context);
verify(msg1, times(0)).setFlag(Flag.DELETED, true);
verify(msg2, times(0)).setFlag(Flag.DELETED, true);
}
@Test
public void testCommit() throws Exception {
SourcePollingChannelAdapter adapter = new SourcePollingChannelAdapter();
QueueChannel outputChannel = new QueueChannel();
adapter.setOutputChannel(outputChannel);
Pop3MailReceiver receiver = new Pop3MailReceiver("pop3://some.host");
receiver.setShouldDeleteMessages(true);
receiver = spy(receiver);
MailReceiverContext context = MailTestsHelper.setupContextHolder(receiver);
Folder folder = context.getFolder();
when(folder.isOpen()).thenReturn(true);
doAnswer(new Answer<Object>() {
public Object answer(InvocationOnMock invocation) throws Throwable {
return null;
}
}).when(receiver).openFolder();
adapter.setSource(new MailReceivingMessageSource(receiver));
TransactionSynchronizationManager.initSynchronization();
TransactionSynchronizationManager.setActualTransactionActive(true);
final AtomicReference<Method> doPollMethod = new AtomicReference<Method>();
ReflectionUtils.doWithMethods(SourcePollingChannelAdapter.class, new MethodCallback() {
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
if (method.getName() == "doPoll") {
doPollMethod.set(method);
method.setAccessible(true);
}
}
});
doPollMethod.get().invoke(adapter, (Object[]) null);
TransactionSynchronizationUtils.triggerAfterCommit();
TransactionSynchronizationUtils.triggerAfterCompletion(TransactionSynchronization.STATUS_COMMITTED);
TransactionSynchronizationManager.clearSynchronization();
verify(folder).close(true);
}
@Test
public void testRollback() throws Exception {
SourcePollingChannelAdapter adapter = new SourcePollingChannelAdapter();
QueueChannel outputChannel = new QueueChannel();
adapter.setOutputChannel(outputChannel);
Pop3MailReceiver receiver = new Pop3MailReceiver("pop3://some.host");
receiver.setShouldDeleteMessages(true);
receiver = spy(receiver);
MailReceiverContext context = MailTestsHelper.setupContextHolder(receiver);
Folder folder = context.getFolder();
when(folder.isOpen()).thenReturn(true);
doAnswer(new Answer<Object>() {
public Object answer(InvocationOnMock invocation) throws Throwable {
return null;
}
}).when(receiver).openFolder();
adapter.setSource(new MailReceivingMessageSource(receiver));
TransactionSynchronizationManager.initSynchronization();
TransactionSynchronizationManager.setActualTransactionActive(true);
final AtomicReference<Method> doPollMethod = new AtomicReference<Method>();
ReflectionUtils.doWithMethods(SourcePollingChannelAdapter.class, new MethodCallback() {
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
if (method.getName() == "doPoll") {
doPollMethod.set(method);
method.setAccessible(true);
}
}
});
doPollMethod.get().invoke(adapter, (Object[]) null);
TransactionSynchronizationUtils.triggerAfterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
TransactionSynchronizationManager.clearSynchronization();
verify(folder).close(false);
}
}