INT-2649: DelayHandler: tx & adviceChain support
* 'delayer-type' XSD: add `<transactional>` & `<advice-chain>` * move `PollerParser#configureAdviceChain` into `IntegrationNamespaceUtils` * DelayerParser: parsing `<transactional>` & `<advice-chain>` via `IntegrationNamespaceUtils#configureAdviceChain` * DelayHandler: add `adviceChain` property * DelayHandler: introduce `ReleaseMessageHandler` to apply `adviceChain` capabilities around `DelayHandler#doReleaseMessage` * DelayerParserTests: tests for introduced sub-elements * DelayerHandlerRescheduleIntegrationTests: test for transaction boundaries with intentional rollback in the message-flow after message release JIRA: https://jira.springsource.org/browse/INT-2649 Resolve conflicts; polishing.
This commit is contained in:
committed by
Gary Russell
parent
fc1417ed39
commit
d4e135b13d
@@ -2,12 +2,17 @@
|
||||
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<beans:bean id="messageStore"
|
||||
class="org.springframework.integration.jdbc.DelayerHandlerRescheduleIntegrationTests$TestJdbcMessageStore"/>
|
||||
|
||||
<beans:bean id="transactionManager"
|
||||
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
|
||||
p:dataSource="#{T (org.springframework.integration.jdbc.DelayerHandlerRescheduleIntegrationTests).dataSource}"/>
|
||||
|
||||
<channel id="output">
|
||||
<queue/>
|
||||
</channel>
|
||||
@@ -18,4 +23,19 @@
|
||||
default-delay="200"
|
||||
message-store="messageStore"/>
|
||||
|
||||
<channel id="transactionalDelayerOutput"/>
|
||||
|
||||
<delayer id="transactionalDelayer"
|
||||
input-channel="transactionalDelayerInput"
|
||||
output-channel="transactionalDelayerOutput"
|
||||
default-delay="10"
|
||||
message-store="messageStore">
|
||||
<transactional/>
|
||||
</delayer>
|
||||
|
||||
<service-activator input-channel="transactionalDelayerOutput" ref="exceptionHandler"/>
|
||||
|
||||
<beans:bean id="exceptionHandler"
|
||||
class="org.springframework.integration.jdbc.DelayerHandlerRescheduleIntegrationTests$ExceptionMessageHandler"/>
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -19,6 +19,9 @@ import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
@@ -26,6 +29,8 @@ import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessageChannel;
|
||||
import org.springframework.integration.MessagingException;
|
||||
import org.springframework.integration.core.MessageHandler;
|
||||
import org.springframework.integration.core.PollableChannel;
|
||||
import org.springframework.integration.store.MessageGroup;
|
||||
import org.springframework.integration.store.MessageGroupStore;
|
||||
@@ -35,17 +40,19 @@ import org.springframework.integration.util.UUIDConverter;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
* @author Artem Bilan
|
||||
* @author Gary Russell
|
||||
*/
|
||||
//INT-1132
|
||||
public class DelayerHandlerRescheduleIntegrationTests {
|
||||
|
||||
public static final String DELAYER_ID = "delayerWithJdbcMS";
|
||||
|
||||
private static EmbeddedDatabase dataSource;
|
||||
public static EmbeddedDatabase dataSource;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
@@ -60,7 +67,7 @@ public class DelayerHandlerRescheduleIntegrationTests {
|
||||
dataSource.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test //INT-1132
|
||||
public void testDelayerHandlerRescheduleWithJdbcMessageStore() throws Exception {
|
||||
AbstractApplicationContext context = new ClassPathXmlApplicationContext("DelayerHandlerRescheduleIntegrationTests-context.xml", this.getClass());
|
||||
MessageChannel input = context.getBean("input", MessageChannel.class);
|
||||
@@ -115,6 +122,31 @@ public class DelayerHandlerRescheduleIntegrationTests {
|
||||
|
||||
}
|
||||
|
||||
@Test //INT-2649
|
||||
public void testRollbackOnDelayerHandlerReleaseTask() throws Exception {
|
||||
AbstractApplicationContext context = new ClassPathXmlApplicationContext("DelayerHandlerRescheduleIntegrationTests-context.xml", this.getClass());
|
||||
MessageChannel input = context.getBean("transactionalDelayerInput", MessageChannel.class);
|
||||
|
||||
MessageGroupStore messageStore = context.getBean("messageStore", MessageGroupStore.class);
|
||||
String delayerMessageGroupId = UUIDConverter.getUUID("transactionalDelayer.messageGroupId").toString();
|
||||
assertEquals(0, messageStore.messageGroupSize(delayerMessageGroupId));
|
||||
|
||||
input.send(MessageBuilder.withPayload("test").build());
|
||||
|
||||
Thread.sleep(30);
|
||||
|
||||
assertEquals(1, messageStore.messageGroupSize(delayerMessageGroupId));
|
||||
|
||||
//To check that 'rescheduling' works in the transaction boundaries too
|
||||
context.destroy();
|
||||
context.refresh();
|
||||
|
||||
assertTrue(RollbackTxSync.latch.await(2, TimeUnit.SECONDS));
|
||||
|
||||
//On transaction rollback the delayed Message should remain in the persistent MessageStore
|
||||
assertEquals(1, messageStore.messageGroupSize(delayerMessageGroupId));
|
||||
}
|
||||
|
||||
private static class TestJdbcMessageStore extends JdbcMessageStore {
|
||||
|
||||
private TestJdbcMessageStore() {
|
||||
@@ -124,4 +156,26 @@ public class DelayerHandlerRescheduleIntegrationTests {
|
||||
|
||||
}
|
||||
|
||||
private static class ExceptionMessageHandler implements MessageHandler {
|
||||
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
TransactionSynchronizationManager.registerSynchronization(new RollbackTxSync());
|
||||
throw new RuntimeException("intentional");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class RollbackTxSync extends TransactionSynchronizationAdapter {
|
||||
|
||||
public static CountDownLatch latch = new CountDownLatch(2);
|
||||
|
||||
@Override
|
||||
public void afterCompletion(int status) {
|
||||
if (TransactionSynchronization.STATUS_ROLLED_BACK == status) {
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user