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,11 +2,13 @@
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
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">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
|
||||
|
||||
<channel id="input"/>
|
||||
|
||||
@@ -34,10 +36,37 @@
|
||||
default-delay="0"
|
||||
message-store="testMessageStore"/>
|
||||
|
||||
<delayer id="delayerWithTransactional"
|
||||
input-channel="input"
|
||||
output-channel="output"
|
||||
default-delay="0">
|
||||
<transactional/>
|
||||
</delayer>
|
||||
|
||||
<delayer id="delayerWithAdviceChain"
|
||||
input-channel="input"
|
||||
output-channel="output"
|
||||
default-delay="0">
|
||||
<advice-chain>
|
||||
<ref bean="testAdviceBean"/>
|
||||
<tx:advice>
|
||||
<tx:attributes>
|
||||
<tx:method name="*" read-only="true" propagation="REQUIRES_NEW"/>
|
||||
</tx:attributes>
|
||||
</tx:advice>
|
||||
</advice-chain>
|
||||
</delayer>
|
||||
|
||||
<beans:bean id="testScheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler"
|
||||
p:poolSize="7"
|
||||
p:waitForTasksToCompleteOnShutdown="true"/>
|
||||
|
||||
<beans:bean id="testMessageStore" class="org.springframework.integration.store.SimpleMessageStore"/>
|
||||
|
||||
<beans:bean id="testAdviceBean" class="org.springframework.integration.config.xml.TestAdviceBean">
|
||||
<beans:constructor-arg value="-1"/>
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="transactionManager" class="org.springframework.integration.util.TestTransactionManager"/>
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -17,12 +17,17 @@
|
||||
package org.springframework.integration.config.xml;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -32,6 +37,11 @@ import org.springframework.integration.handler.DelayHandler;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource;
|
||||
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
|
||||
import org.springframework.transaction.interceptor.TransactionAttributeSource;
|
||||
import org.springframework.transaction.interceptor.TransactionInterceptor;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
@@ -45,7 +55,6 @@ public class DelayerParserTests {
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
|
||||
@Test
|
||||
public void defaultScheduler() {
|
||||
Object endpoint = context.getBean("delayerWithDefaultScheduler");
|
||||
@@ -91,4 +100,37 @@ public class DelayerParserTests {
|
||||
assertEquals(context.getBean("testMessageStore"), accessor.getPropertyValue("messageStore"));
|
||||
}
|
||||
|
||||
@Test //INT-2649
|
||||
public void transactionalSubElement() {
|
||||
Object endpoint = context.getBean("delayerWithTransactional");
|
||||
DelayHandler delayHandler = TestUtils.getPropertyValue(endpoint, "handler", DelayHandler.class);
|
||||
List adviceChain = TestUtils.getPropertyValue(delayHandler, "delayedAdviceChain", List.class);
|
||||
assertEquals(1, adviceChain.size());
|
||||
Object advice = adviceChain.get(0);
|
||||
assertTrue(advice instanceof TransactionInterceptor);
|
||||
TransactionAttributeSource transactionAttributeSource = ((TransactionInterceptor) advice).getTransactionAttributeSource();
|
||||
assertTrue(transactionAttributeSource instanceof MatchAlwaysTransactionAttributeSource);
|
||||
TransactionDefinition definition = transactionAttributeSource.getTransactionAttribute(null, null);
|
||||
assertEquals(TransactionDefinition.PROPAGATION_REQUIRED, definition.getPropagationBehavior());
|
||||
assertEquals(TransactionDefinition.ISOLATION_DEFAULT, definition.getIsolationLevel());
|
||||
assertEquals(TransactionDefinition.TIMEOUT_DEFAULT, definition.getTimeout());
|
||||
assertFalse(definition.isReadOnly());
|
||||
}
|
||||
|
||||
@Test //INT-2649
|
||||
public void adviceChainSubElement() {
|
||||
Object endpoint = context.getBean("delayerWithAdviceChain");
|
||||
DelayHandler delayHandler = TestUtils.getPropertyValue(endpoint, "handler", DelayHandler.class);
|
||||
List adviceChain = TestUtils.getPropertyValue(delayHandler, "delayedAdviceChain", List.class);
|
||||
assertEquals(2, adviceChain.size());
|
||||
assertSame(context.getBean("testAdviceBean"), adviceChain.get(0));
|
||||
|
||||
Object txAdvice = adviceChain.get(1);
|
||||
assertEquals(TransactionInterceptor.class, txAdvice.getClass());
|
||||
TransactionAttributeSource transactionAttributeSource = ((TransactionInterceptor) txAdvice).getTransactionAttributeSource();
|
||||
assertEquals(NameMatchTransactionAttributeSource.class, transactionAttributeSource.getClass());
|
||||
HashMap nameMap = TestUtils.getPropertyValue(transactionAttributeSource, "nameMap", HashMap.class);
|
||||
assertEquals("{*=PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT,readOnly}", nameMap.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,13 @@
|
||||
|
||||
<chain input-channel="delayerInsideChain" output-channel="outputA">
|
||||
<transformer expression="payload.toUpperCase()"/>
|
||||
<delayer id="delayerInsideChain" default-delay="1000"/>
|
||||
<delayer id="delayerInsideChain" default-delay="1000">
|
||||
<advice-chain>
|
||||
<beans:bean class="org.springframework.integration.config.xml.TestAdviceBean">
|
||||
<beans:constructor-arg value="0"/>
|
||||
</beans:bean>
|
||||
</advice-chain>
|
||||
</delayer>
|
||||
<transformer expression="payload.toLowerCase()"/>
|
||||
</chain>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user