Fixes to get the codebase to compile successfully again, still a ways to go before all tests pass.
This commit is contained in:
@@ -17,36 +17,28 @@
|
||||
package org.springframework.batch.sample.tasklet;
|
||||
|
||||
|
||||
import org.springframework.batch.core.tasklet.Tasklet;
|
||||
import org.springframework.batch.execution.tasklet.ItemOrientedTasklet;
|
||||
import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
|
||||
/**
|
||||
* Hacked {@link Tasklet} that throws exception on a given record number
|
||||
* Hacked {@link ItemReader} that throws exception on a given record number
|
||||
* (useful for testing restart).
|
||||
*
|
||||
* @author Robert Kasanicky
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class ExceptionRestartableTasklet extends ItemOrientedTasklet {
|
||||
public class ExceptionThrowingItemReaderProxy implements ItemReader {
|
||||
|
||||
private int counter = 0;
|
||||
private int throwExceptionOnRecordNumber = 4;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see Tasklet#execute()
|
||||
*/
|
||||
public ExitStatus execute() throws Exception {
|
||||
|
||||
counter++;
|
||||
if (counter == throwExceptionOnRecordNumber) {
|
||||
throw new BatchCriticalException("Planned failure on count="+counter);
|
||||
}
|
||||
|
||||
return super.execute();
|
||||
private final ItemReader itemReader;
|
||||
|
||||
public ExceptionThrowingItemReaderProxy(ItemReader itemReader) {
|
||||
this.itemReader = itemReader;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param throwExceptionOnRecordNumber The number of record on which exception should be thrown
|
||||
*/
|
||||
@@ -58,4 +50,14 @@ public class ExceptionRestartableTasklet extends ItemOrientedTasklet {
|
||||
return throwExceptionOnRecordNumber;
|
||||
}
|
||||
|
||||
public Object read() throws Exception {
|
||||
|
||||
counter++;
|
||||
if (counter == throwExceptionOnRecordNumber) {
|
||||
throw new BatchCriticalException("Planned failure on count="+counter);
|
||||
}
|
||||
|
||||
return itemReader.read();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,13 +17,12 @@
|
||||
package org.springframework.batch.sample.tasklet;
|
||||
|
||||
import org.springframework.batch.core.tasklet.Tasklet;
|
||||
import org.springframework.batch.execution.tasklet.ItemOrientedTasklet;
|
||||
import org.springframework.batch.io.file.DefaultFlatFileItemReader;
|
||||
import org.springframework.batch.item.ExecutionAttributes;
|
||||
import org.springframework.batch.item.ExecutionAttributesProvider;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.sample.dao.TradeDao;
|
||||
import org.springframework.batch.sample.domain.Trade;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple implementation of a {@link Tasklet}, which illustrates the reading
|
||||
@@ -39,12 +38,7 @@ import org.springframework.batch.sample.domain.Trade;
|
||||
* @author Lucas Ward
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class SimpleTradeTasklet implements Tasklet, ExecutionAttributesProvider {
|
||||
|
||||
/*
|
||||
* reads the data from input file
|
||||
*/
|
||||
private DefaultFlatFileItemReader inputSource;
|
||||
public class SimpleTradeWriter implements ItemWriter, ExecutionAttributesProvider {
|
||||
|
||||
/*
|
||||
* writes a Trade object to output
|
||||
@@ -62,21 +56,10 @@ public class SimpleTradeTasklet implements Tasklet, ExecutionAttributesProvider
|
||||
* processed. Because this is a simple example job, the data is simply
|
||||
* written out without any processing.
|
||||
*/
|
||||
public ExitStatus execute() throws Exception {
|
||||
Trade trade = (Trade)inputSource.read();
|
||||
|
||||
if (trade == null) {
|
||||
// no Trade object returned, reading input is finished
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
|
||||
public void write(Object item) throws Exception {
|
||||
Assert.isInstanceOf(Trade.class, item, "Only items of type: [" + Trade.class + "] are supported by this writer");
|
||||
tradeCount++;
|
||||
tradeDao.writeTrade(trade);
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
|
||||
public void setItemReader(DefaultFlatFileItemReader inputTemplate) {
|
||||
this.inputSource = inputTemplate;
|
||||
tradeDao.writeTrade((Trade)item);
|
||||
}
|
||||
|
||||
public void setTradeDao(TradeDao tradeDao) {
|
||||
@@ -16,60 +16,50 @@
|
||||
<property name="steps">
|
||||
<list>
|
||||
<bean id="staging" parent="simpleStep">
|
||||
<property name="tasklet">
|
||||
<property name="itemReader">
|
||||
<bean
|
||||
class="org.springframework.batch.execution.tasklet.ItemOrientedTasklet">
|
||||
<property name="itemReader">
|
||||
<bean
|
||||
class="org.springframework.batch.item.reader.ValidatingItemReader">
|
||||
<property name="itemReader"
|
||||
ref="fileInputTemplate" />
|
||||
<property name="validator"
|
||||
ref="fixedValidator" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="itemWriter">
|
||||
<bean
|
||||
class="org.springframework.batch.sample.item.writer.StagingItemWriter"
|
||||
scope="step">
|
||||
<aop:scoped-proxy />
|
||||
<property name="dataSource"
|
||||
ref="dataSource" />
|
||||
<property name="incrementer">
|
||||
<bean
|
||||
parent="incrementerParent">
|
||||
<property
|
||||
name="incrementerName" value="BATCH_STAGING_SEQ" />
|
||||
</bean>
|
||||
</property>
|
||||
class="org.springframework.batch.item.reader.ValidatingItemReader">
|
||||
<property name="itemReader"
|
||||
ref="fileInputTemplate" />
|
||||
<property name="validator"
|
||||
ref="fixedValidator" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="itemWriter">
|
||||
<bean
|
||||
class="org.springframework.batch.sample.item.writer.StagingItemWriter"
|
||||
scope="step">
|
||||
<aop:scoped-proxy />
|
||||
<property name="dataSource"
|
||||
ref="dataSource" />
|
||||
<property name="incrementer">
|
||||
<bean parent="incrementerParent">
|
||||
<property name="incrementerName"
|
||||
value="BATCH_STAGING_SEQ" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
<property name="commitInterval" value="2" />
|
||||
<property name="startLimit" value="100" />
|
||||
<property name="saveExecutionAttributes" value="true" />
|
||||
<property name="saveExecutionAttributes"
|
||||
value="true" />
|
||||
<property name="allowStartIfComplete" value="false" />
|
||||
</bean>
|
||||
<bean id="loading" parent="repeatOperationsStep">
|
||||
<property name="tasklet">
|
||||
<property name="itemReader">
|
||||
<bean
|
||||
class="org.springframework.batch.execution.tasklet.ItemOrientedTasklet">
|
||||
<property name="itemReader">
|
||||
<bean
|
||||
class="org.springframework.batch.sample.item.reader.StagingItemReader"
|
||||
scope="step">
|
||||
<aop:scoped-proxy />
|
||||
<property name="dataSource"
|
||||
ref="dataSource" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="itemWriter">
|
||||
<bean
|
||||
class="org.springframework.batch.sample.item.writer.TradeWriter">
|
||||
<property name="dao" ref="tradeDao" />
|
||||
</bean>
|
||||
</property>
|
||||
class="org.springframework.batch.sample.item.reader.StagingItemReader"
|
||||
scope="step">
|
||||
<aop:scoped-proxy />
|
||||
<property name="dataSource"
|
||||
ref="dataSource" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="itemWriter">
|
||||
<bean
|
||||
class="org.springframework.batch.sample.item.writer.TradeWriter">
|
||||
<property name="dao" ref="tradeDao" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="chunkOperations">
|
||||
|
||||
@@ -1,60 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
|
||||
|
||||
<bean parent="stepScope"/>
|
||||
<bean parent="jobConfigurationRegistryBeanPostProcessor"/>
|
||||
<bean parent="customEditorConfigurer"/>
|
||||
<bean parent="stepScope" />
|
||||
<bean parent="jobConfigurationRegistryBeanPostProcessor" />
|
||||
<bean parent="customEditorConfigurer" />
|
||||
|
||||
<bean id="restartSampleJob" parent="simpleJob">
|
||||
<property name="steps">
|
||||
<bean id="step1" parent="simpleStep">
|
||||
<property name="tasklet">
|
||||
<bean class="org.springframework.batch.sample.tasklet.ExceptionRestartableTasklet">
|
||||
<property name="itemReader">
|
||||
<bean
|
||||
class="org.springframework.batch.item.reader.ValidatingItemReader">
|
||||
<property name="itemReader" ref="fileItemReader" />
|
||||
<property name="validator" ref="fixedValidator" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="itemWriter">
|
||||
<bean class="org.springframework.batch.sample.item.writer.TradeWriter">
|
||||
<property name="dao" ref="tradeDao" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
<property name="commitInterval" value="2" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- INFRASTRUCTURE SETUP -->
|
||||
|
||||
<bean id="fileItemReader" class="org.springframework.batch.io.file.DefaultFlatFileItemReader"
|
||||
scope="step" >
|
||||
<aop:scoped-proxy />
|
||||
<property name="resource" ref="fileLocator" />
|
||||
<property name="tokenizer" ref="fixedFileDescriptor" />
|
||||
<property name="fieldSetMapper" ref="fieldSetMapper" />
|
||||
</bean>
|
||||
|
||||
<bean id="fixedFileDescriptor" class="org.springframework.batch.io.file.transform.FixedLengthTokenizer">
|
||||
<property name="names" value="ISIN, Quantity, Price, Customer" />
|
||||
<property name="columns" value="1-12, 13-15, 16-20, 21-29" />
|
||||
</bean>
|
||||
|
||||
<bean id="fixedValidator" class="org.springframework.batch.item.validator.SpringValidator">
|
||||
<property name="validator">
|
||||
<bean id="tradeValidator" class="org.springmodules.validation.valang.ValangValidator">
|
||||
<property name="valang">
|
||||
<value>
|
||||
<property name="itemReader">
|
||||
<bean
|
||||
class="org.springframework.batch.item.reader.ValidatingItemReader">
|
||||
<property name="itemReader"
|
||||
ref="fileItemReader" />
|
||||
<property name="validator" ref="fixedValidator" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="itemWriter">
|
||||
<bean
|
||||
class="org.springframework.batch.sample.item.writer.TradeWriter">
|
||||
<property name="dao" ref="tradeDao" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="commitInterval" value="2" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- INFRASTRUCTURE SETUP -->
|
||||
|
||||
<bean id="fileItemReader"
|
||||
class="org.springframework.batch.io.file.DefaultFlatFileItemReader"
|
||||
scope="step">
|
||||
<aop:scoped-proxy />
|
||||
<property name="resource" ref="fileLocator" />
|
||||
<property name="tokenizer" ref="fixedFileDescriptor" />
|
||||
<property name="fieldSetMapper" ref="fieldSetMapper" />
|
||||
</bean>
|
||||
|
||||
<bean id="fixedFileDescriptor"
|
||||
class="org.springframework.batch.io.file.transform.FixedLengthTokenizer">
|
||||
<property name="names" value="ISIN, Quantity, Price, Customer" />
|
||||
<property name="columns" value="1-12, 13-15, 16-20, 21-29" />
|
||||
</bean>
|
||||
|
||||
<bean id="fixedValidator"
|
||||
class="org.springframework.batch.item.validator.SpringValidator">
|
||||
<property name="validator">
|
||||
<bean id="tradeValidator"
|
||||
class="org.springmodules.validation.valang.ValangValidator">
|
||||
<property name="valang">
|
||||
<value>
|
||||
<![CDATA[
|
||||
{ isin : length(?) < 13 : 'ISIN too long' : 'isin_length' : 12}
|
||||
]]>
|
||||
@@ -64,21 +68,24 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="tradeDao" class="org.springframework.batch.sample.dao.JdbcTradeDao">
|
||||
<property name="jdbcTemplate" ref="jdbcTemplate" />
|
||||
<property name="incrementer">
|
||||
<bean parent="incrementerParent">
|
||||
<property name="incrementerName" value="TRADE_SEQ" />
|
||||
</bean>
|
||||
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="fileLocator" class="org.springframework.core.io.ClassPathResource">
|
||||
<constructor-arg type="java.lang.String"
|
||||
value="data/fixedLengthImportJob/input/20070122.teststream.ImportTradeDataStep.txt" />
|
||||
</bean>
|
||||
|
||||
<bean id="fieldSetMapper" class="org.springframework.batch.sample.mapping.TradeFieldSetMapper" />
|
||||
|
||||
<bean id="tradeDao"
|
||||
class="org.springframework.batch.sample.dao.JdbcTradeDao">
|
||||
<property name="jdbcTemplate" ref="jdbcTemplate" />
|
||||
<property name="incrementer">
|
||||
<bean parent="incrementerParent">
|
||||
<property name="incrementerName" value="TRADE_SEQ" />
|
||||
</bean>
|
||||
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="fileLocator"
|
||||
class="org.springframework.core.io.ClassPathResource">
|
||||
<constructor-arg type="java.lang.String"
|
||||
value="data/fixedLengthImportJob/input/20070122.teststream.ImportTradeDataStep.txt" />
|
||||
</bean>
|
||||
|
||||
<bean id="fieldSetMapper"
|
||||
class="org.springframework.batch.sample.mapping.TradeFieldSetMapper" />
|
||||
|
||||
</beans>
|
||||
@@ -14,11 +14,10 @@
|
||||
<property name="steps">
|
||||
<list>
|
||||
<bean id="step1" parent="simpleStep">
|
||||
<property name="tasklet">
|
||||
<bean id="tradeTasklet"
|
||||
class="org.springframework.batch.sample.tasklet.SimpleTradeTasklet">
|
||||
<property name="itemReader"
|
||||
ref="fileItemReader" />
|
||||
<property name="itemReader" ref="fileItemReader" />
|
||||
<property name="itemWriter">
|
||||
<bean
|
||||
class="org.springframework.batch.sample.tasklet.SimpleTradeWriter">
|
||||
<property name="tradeDao" ref="tradeDao" />
|
||||
</bean>
|
||||
</property>
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.springframework.batch.item.reader.ListItemReader;
|
||||
import org.springframework.batch.repeat.context.RepeatContextSupport;
|
||||
import org.springframework.batch.repeat.synch.RepeatSynchronizationManager;
|
||||
|
||||
public class ExceptionRestartableTaskletTests extends TestCase {
|
||||
public class ExceptionThrowingItemReaderProxyTests extends TestCase {
|
||||
|
||||
//expected call count before exception is thrown (exception should be thrown in next iteration)
|
||||
private static final int ITER_COUNT = 5;
|
||||
@@ -21,23 +21,9 @@ public class ExceptionRestartableTaskletTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testProcess() throws Exception {
|
||||
|
||||
//create mock item processor which will be called by module.process() method
|
||||
MockControl processorControl = MockControl.createControl(ItemWriter.class);
|
||||
ItemWriter itemProcessor = (ItemWriter)processorControl.getMock();
|
||||
|
||||
//set expected call count and argument matcher
|
||||
itemProcessor.write(null);
|
||||
processorControl.setMatcher(MockControl.ALWAYS_MATCHER);
|
||||
processorControl.setVoidCallable(ITER_COUNT);
|
||||
processorControl.replay();
|
||||
|
||||
|
||||
//create module and set item processor and iteration count
|
||||
ExceptionRestartableTasklet module = new ExceptionRestartableTasklet();
|
||||
module.setItemWriter(itemProcessor);
|
||||
module.setThrowExceptionOnRecordNumber(ITER_COUNT + 1);
|
||||
|
||||
module.setItemReader(new ListItemReader(new ArrayList() {{
|
||||
ExceptionThrowingItemReaderProxy itemReader = new ExceptionThrowingItemReaderProxy(new ListItemReader(new ArrayList() {{
|
||||
add("a");
|
||||
add("b");
|
||||
add("c");
|
||||
@@ -45,20 +31,20 @@ public class ExceptionRestartableTaskletTests extends TestCase {
|
||||
add("e");
|
||||
add("f");
|
||||
}}));
|
||||
|
||||
itemReader.setThrowExceptionOnRecordNumber(ITER_COUNT + 1);
|
||||
|
||||
RepeatSynchronizationManager.register(new RepeatContextSupport(null));
|
||||
|
||||
//call process method multiple times and verify whether exception is thrown when expected
|
||||
for (int i = 0; i <= ITER_COUNT; i++) {
|
||||
try {
|
||||
module.execute();
|
||||
itemReader.read();
|
||||
assertTrue(i < ITER_COUNT);
|
||||
} catch (BatchCriticalException bce) {
|
||||
assertEquals(ITER_COUNT,i);
|
||||
}
|
||||
}
|
||||
|
||||
//verify method calls
|
||||
processorControl.verify();
|
||||
}
|
||||
}
|
||||
@@ -44,19 +44,14 @@ public class SimpleTradeTaskletTests extends TestCase {
|
||||
};
|
||||
|
||||
//create module
|
||||
SimpleTradeTasklet module = new SimpleTradeTasklet();
|
||||
module.setItemReader(input);
|
||||
SimpleTradeWriter module = new SimpleTradeWriter();
|
||||
module.setTradeDao(dao);
|
||||
|
||||
//call tested methods
|
||||
//read method should return true, because input returned fieldset
|
||||
assertTrue(module.execute().isContinuable());
|
||||
module.write(input.read());
|
||||
|
||||
//verify whether input and writer were called
|
||||
assertTrue(inputCalled);
|
||||
assertTrue(writerCalled);
|
||||
|
||||
//read should return false, because input returned null
|
||||
assertFalse(module.execute().isContinuable());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user