Fix retry tests in integration project

This commit is contained in:
dsyer
2008-07-14 07:45:45 +00:00
parent 5321f74e40
commit cae3dabff1
3 changed files with 278 additions and 246 deletions

View File

@@ -176,7 +176,7 @@ public class RetryTemplate implements RetryOperations {
retryPolicy.registerThrowable(context, throwable);
if (retryPolicy.shouldRethrow(context)) {
logger.debug("Abort retry for policy: count=" + context.getRetryCount());
logger.debug("Rethrow in retry for policy: count=" + context.getRetryCount());
rethrow(throwable);
}

View File

@@ -1,218 +1,206 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-batch-integration</artifactId>
<name>Enterprise Integration</name>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch</artifactId>
<version>1.1.0.DEV-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<properties>
<spring.integration.version>1.0.0.CI-SNAPSHOT</spring.integration.version>
</properties>
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<!-- run tests during the integration-test phase, not
the normal test phase -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>test</id>
<build>
<plugins>
<!-- run tests during the integration-test phase, not
the normal test phase -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>javax.jms</groupId>
<artifactId>com.springsource.javax.jms</artifactId>
<version>1.1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>org.springframework.integration</artifactId>
<version>${spring.integration.version}</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.context</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.aop</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.transaction</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>org.springframework.integration.adapter</artifactId>
<version>${spring.integration.version}</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.web</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.aop</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.context</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.context.support</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.jms</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.transaction</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.commons</groupId>
<artifactId>com.springsource.org.apache.commons.net</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.oro</groupId>
<artifactId>com.springsource.org.apache.oro</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.framework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.framework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.framework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.framework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>springsource-external</id>
<url>http://repository.springsource.com/maven/bundles/external</url>
</repository>
<repository>
<id>springsource-release</id>
<url>http://repository.springsource.com/maven/bundles/release</url>
</repository>
<repository>
<id>springsource-milestone</id>
<url>http://repository.springsource.com/maven/bundles/milestone</url>
</repository>
<repository>
<!-- Browse: http://s3browse.com/explore/repository.springsource.com/maven/bundles/snapshot -->
<id>springsource-snapshot</id>
<url>http://repository.springsource.com/maven/bundles/snapshot</url>
</repository>
</repositories>
</project>
<?xml version="1.0" encoding="UTF-8"?><project>
<parent>
<artifactId>spring-batch</artifactId>
<groupId>org.springframework.batch</groupId>
<version>1.1.0.DEV-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-batch-integration</artifactId>
<name>Enterprise Integration</name>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>test</id>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<repositories>
<repository>
<id>springsource-external</id>
<url>http://repository.springsource.com/maven/bundles/external</url>
</repository>
<repository>
<id>springsource-release</id>
<url>http://repository.springsource.com/maven/bundles/release</url>
</repository>
<repository>
<id>springsource-milestone</id>
<url>http://repository.springsource.com/maven/bundles/milestone</url>
</repository>
<repository>
<id>springsource-snapshot</id>
<url>http://repository.springsource.com/maven/bundles/snapshot</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>javax.jms</groupId>
<artifactId>com.springsource.javax.jms</artifactId>
<version>1.1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>org.springframework.integration</artifactId>
<version>${spring.integration.version}</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>org.springframework.context</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>org.springframework.aop</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>org.springframework.transaction</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>org.springframework.integration.adapter</artifactId>
<version>${spring.integration.version}</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>org.springframework.web</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>org.springframework.aop</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>org.springframework.context</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>org.springframework.context.support</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>org.springframework.jms</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>org.springframework.transaction</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>com.springsource.org.apache.commons.net</artifactId>
<groupId>org.apache.commons</groupId>
</exclusion>
<exclusion>
<artifactId>com.springsource.org.apache.oro</artifactId>
<groupId>org.apache.oro</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.framework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.framework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.framework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.framework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>spring-context</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-beans</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-core</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-aop</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<properties>
<spring.integration.version>1.0.0.CI-SNAPSHOT</spring.integration.version>
</properties>
</project>

View File

@@ -19,6 +19,9 @@ import org.springframework.batch.item.ItemKeyGenerator;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemRecoverer;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatCallback;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.interceptor.RepeatOperationsInterceptor;
import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
import org.springframework.batch.repeat.support.RepeatTemplate;
@@ -31,6 +34,7 @@ import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.dispatcher.DirectChannel;
import org.springframework.integration.endpoint.EndpointTrigger;
import org.springframework.integration.endpoint.SourceEndpoint;
import org.springframework.integration.endpoint.interceptor.EndpointInterceptorAdapter;
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageSource;
@@ -38,7 +42,7 @@ import org.springframework.integration.message.MessageTarget;
import org.springframework.integration.scheduling.PollingSchedule;
import org.springframework.integration.scheduling.SimpleTaskScheduler;
import org.springframework.integration.scheduling.TaskScheduler;
import org.springframework.integration.util.ErrorHandler;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.util.StringUtils;
@@ -68,6 +72,8 @@ public class PollableSourceRetryTests {
}
};
private PlatformTransactionManager transactionManager = new ResourcelessTransactionManager();;
@SuppressWarnings("unchecked")
@Test
public void testSimpleTransactionalPolling() throws Exception {
@@ -86,10 +92,10 @@ public class PollableSourceRetryTests {
MessageSource<Object> source = getPollableSource(list);
DirectChannel channel = getChannel(handler, source);
SourceEndpoint endpoint = getSourceEndpoint(source, channel);
MessageTarget target = (MessageTarget) getProxy(endpoint, MessageTarget.class, new Advice[] {getTransactionInterceptor()}, "poll");
addTransactionInterceptor(endpoint);
endpoint.afterPropertiesSet();
EndpointTrigger trigger = new EndpointTrigger(endpoint.getSchedule());
trigger.addTarget(target);
trigger.addTarget(endpoint);
TaskScheduler scheduler = getSchedulerWithErrorHandler(trigger);
waitForResults(scheduler, 2, 40);
@@ -155,10 +161,10 @@ public class PollableSourceRetryTests {
MessageSource<Object> source = getPollableSource(list);
DirectChannel channel = getChannel(handler, source);
SourceEndpoint endpoint = getSourceEndpoint(source, channel);
MessageTarget target = (MessageTarget) getProxy(endpoint, MessageTarget.class, new Advice[] {getTransactionInterceptor()}, "poll");
addTransactionInterceptor(endpoint);
endpoint.afterPropertiesSet();
EndpointTrigger trigger = new EndpointTrigger(endpoint.getSchedule());
trigger.addTarget(target);
trigger.addTarget(endpoint);
TaskScheduler scheduler = getSchedulerWithErrorHandler(trigger);
waitForResults(scheduler, 2, 20);
@@ -197,13 +203,13 @@ public class PollableSourceRetryTests {
MessageSource<Object> source = getPollableSource(list);
DirectChannel channel = getChannel(handler, source);
SourceEndpoint endpoint = getSourceEndpoint(source, channel);
MessageTarget target = (MessageTarget) getProxy(endpoint, MessageTarget.class, new Advice[] {getTransactionInterceptor()}, "poll");
addTransactionInterceptor(endpoint);
endpoint.afterPropertiesSet();
EndpointTrigger trigger = new EndpointTrigger(endpoint.getSchedule());
trigger.addTarget(target);
trigger.addTarget(endpoint);
TaskScheduler scheduler = getSchedulerWithErrorHandler(trigger);
waitForResults(scheduler, 5, 20);
waitForResults(scheduler, 5, 30);
assertEquals(5, processed.size());
assertFalse("No messages got to processor", processed.isEmpty());
@@ -243,10 +249,11 @@ public class PollableSourceRetryTests {
DirectChannel channel = getChannel(handler, source);
SourceEndpoint endpoint = getSourceEndpoint(source, channel);
// endpoint.addInterceptor(getTransactionInterceptor());
MessageTarget target = (MessageTarget) getProxy(endpoint, MessageTarget.class, new Advice[] {getRepeatOperationsInterceptor(3), getTransactionInterceptor()}, "poll");
addTransactionInterceptor(endpoint);
addRepeatInterceptor(endpoint, 3);
endpoint.afterPropertiesSet();
EndpointTrigger trigger = new EndpointTrigger(endpoint.getSchedule());
trigger.addTarget(target);
trigger.addTarget(endpoint);
TaskScheduler scheduler = getSchedulerWithErrorHandler(trigger);
waitForResults(scheduler, 6, 100);
@@ -292,17 +299,17 @@ public class PollableSourceRetryTests {
MessageSource<Object> source = getPollableSource(list);
MessageChannel channel = getChannel(handler, source);
SourceEndpoint endpoint = getSourceEndpoint(source, channel);
MessageTarget target = (MessageTarget) getProxy(endpoint, MessageTarget.class, new Advice[] {getTransactionInterceptor()}, "poll");
// this was the old dispatch advice chain
channel = (MessageChannel) getProxy(channel, MessageChannel.class,
new Advice[] { getRetryOperationsInterceptor(itemKeyGenerator) }, "send");
SourceEndpoint endpoint = getSourceEndpoint(source, channel);
addTransactionInterceptor(endpoint);
endpoint.afterPropertiesSet();
EndpointTrigger trigger = new EndpointTrigger(endpoint.getSchedule());
trigger.addTarget(target);
trigger.addTarget(endpoint);
TaskScheduler scheduler = getSchedulerWithErrorHandler(trigger);
waitForResults(scheduler, 4, 20);
waitForResults(scheduler, 4, 40);
assertEquals(4, processed.size());
assertEquals(1, recovered.size());
@@ -340,14 +347,15 @@ public class PollableSourceRetryTests {
MessageSource<Object> source = getPollableSource(list);
MessageChannel channel = getChannel(handler, source);
SourceEndpoint endpoint = getSourceEndpoint(source, channel);
MessageTarget target = (MessageTarget) getProxy(endpoint, MessageTarget.class, new Advice[] {getRepeatOperationsInterceptor(3), getTransactionInterceptor()}, "poll");
// this was the old dispatch advice chain
channel = (MessageChannel) getProxy(channel, MessageChannel.class,
new Advice[] { getRetryOperationsInterceptor(itemKeyGenerator) }, "send");
SourceEndpoint endpoint = getSourceEndpoint(source, channel);
addTransactionInterceptor(endpoint);
addRepeatInterceptor(endpoint, 3);
endpoint.afterPropertiesSet();
EndpointTrigger trigger = new EndpointTrigger(endpoint.getSchedule());
trigger.addTarget(target);
trigger.addTarget(endpoint);
TaskScheduler scheduler = getSchedulerWithErrorHandler(trigger);
waitForResults(scheduler, 6, 100);
@@ -373,7 +381,7 @@ public class PollableSourceRetryTests {
* @return
*/
private SourceEndpoint getSourceEndpoint(MessageSource<Object> source, MessageChannel channel) {
PollingSchedule schedule = new PollingSchedule(50);
PollingSchedule schedule = new PollingSchedule(100);
schedule.setFixedRate(true); // used to be the default
SourceEndpoint endpoint = new SourceEndpoint(source);
endpoint.setOutputChannel(channel);
@@ -426,15 +434,15 @@ public class PollableSourceRetryTests {
return source;
}
// Workaround for INT-182
private TaskScheduler getSchedulerWithErrorHandler(Runnable task) {
SimpleTaskScheduler scheduler = new SimpleTaskScheduler(Executors.newSingleThreadScheduledExecutor());
scheduler.setErrorHandler(new ErrorHandler() {
public void handle(Throwable t) {
logger.error("Exception in scheduler", t);
// throw (RuntimeException)t;
}
});
// Workaround for INT-182
// scheduler.setErrorHandler(new ErrorHandler() {
// public void handle(Throwable t) {
// logger.error("Exception in scheduler", t);
// // throw (RuntimeException)t;
// }
// });
scheduler.schedule(task);
return scheduler;
}
@@ -454,7 +462,9 @@ public class PollableSourceRetryTests {
if (data.getClass().isArray()) {
data = ((Object[]) data)[0];
}
recovered.add(((Message<String>) data).getPayload());
String payload = ((Message<String>) data).getPayload();
logger.debug("Recovering: "+payload);
recovered.add(payload);
return true;
}
});
@@ -462,11 +472,45 @@ public class PollableSourceRetryTests {
return advice;
}
/**
* @param endpoint
*/
private void addTransactionInterceptor(SourceEndpoint endpoint) {
org.springframework.integration.endpoint.interceptor.TransactionInterceptor transactionInterceptor = new org.springframework.integration.endpoint.interceptor.TransactionInterceptor(transactionManager);
transactionInterceptor.afterPropertiesSet();
endpoint.addInterceptor(transactionInterceptor);
}
/**
* @return
*/
private TransactionInterceptor getTransactionInterceptor() {
return new TransactionInterceptor(new ResourcelessTransactionManager(), PropertiesConverter.stringToProperties("*=PROPAGATION_REQUIRED"));
return new TransactionInterceptor(transactionManager, PropertiesConverter.stringToProperties("*=PROPAGATION_REQUIRED"));
}
/**
* @param endpoint
* @param commitInterval
*/
private void addRepeatInterceptor(SourceEndpoint endpoint, int commitInterval) {
final RepeatTemplate repeatTemplate = new RepeatTemplate();
repeatTemplate.setCompletionPolicy(new SimpleCompletionPolicy(commitInterval));
endpoint.addInterceptor(new EndpointInterceptorAdapter() {
private boolean value;
@Override
public boolean aroundSend(final Message<?> message, final MessageTarget endpoint) {
repeatTemplate.iterate(new RepeatCallback() {
public ExitStatus doInIteration(RepeatContext context) throws Exception {
doAroundSend(message, endpoint);
return ExitStatus.CONTINUABLE;
}
});
return value;
}
private void doAroundSend(Message<?> message, MessageTarget endpoint) {
value = super.aroundSend(message, endpoint);
}
});
}
/**