IN PROGRESS - issue BATCH-244: Repeated processing of items does not work
http://opensource.atlassian.com/projects/spring/browse/BATCH-244 Fixed bug in ResourceLinereader that causes first chunk to be lost if it fails.
This commit is contained in:
@@ -23,7 +23,6 @@
|
||||
|
||||
<menu name="Spring Batch Core">
|
||||
<item name="${project.name}" href="index.html"/>
|
||||
<item name="Changelog" href="changelog.html"/>
|
||||
</menu>
|
||||
<menu ref="reports"/>
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
<menu name="Spring Batch Execution">
|
||||
<item name="${project.name}" href="index.html"/>
|
||||
<item name="Changelog" href="changelog.html"/>
|
||||
</menu>
|
||||
<menu ref="reports"/>
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ public class IbatisDrivingQueryInputSource extends DrivingQueryInputSource {
|
||||
private SqlMapClientTemplate sqlMapClientTemplate;
|
||||
|
||||
/**
|
||||
* Overriden read that uses the returned key as arguments to the details query.
|
||||
* Overridden read() that uses the returned key as arguments to the details query.
|
||||
*
|
||||
* @see org.springframework.batch.io.driving.DrivingQueryInputSource#read()
|
||||
*/
|
||||
|
||||
@@ -291,6 +291,7 @@ class ResourceLineReader implements ResourceLifecycle, InputSource,
|
||||
try {
|
||||
reader = new BufferedReader(new InputStreamReader(resource
|
||||
.getInputStream(), encoding));
|
||||
mark();
|
||||
} catch (IOException e) {
|
||||
throw new BatchEnvironmentException("Could not open resource",
|
||||
e);
|
||||
|
||||
@@ -28,11 +28,10 @@
|
||||
|
||||
<menu name="Reference Material">
|
||||
<item name="${project.name}" href="index.html"/>
|
||||
<item name="Changelog" href="changelog.html"/>
|
||||
</menu>
|
||||
|
||||
<menu ref="reports"/>
|
||||
|
||||
</body>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -151,7 +151,17 @@ public class ResourceLineReaderTests extends TestCase {
|
||||
reader.read();
|
||||
assertEquals(2, reader.getCurrentLineCount());
|
||||
}
|
||||
|
||||
|
||||
public void testMarkOnFirstRead() throws Exception {
|
||||
Resource resource = new ByteArrayResource("1\n# 2\n3".getBytes());
|
||||
ResourceLineReader reader = new ResourceLineReader(resource);
|
||||
reader.read();
|
||||
// The first read should do a mark() so the reset goes back to the beginning.
|
||||
reader.reset();
|
||||
String line = (String) reader.read();
|
||||
assertEquals("1", line);
|
||||
}
|
||||
|
||||
public void testNonDefaultRecordSeparatorPolicy() throws Exception {
|
||||
Resource resource = new ByteArrayResource("1\n\"4\n5\"; \n6".getBytes());
|
||||
ResourceLineReader reader = new ResourceLineReader(resource);
|
||||
|
||||
@@ -27,6 +27,19 @@ import org.springframework.batch.sample.domain.Trade;
|
||||
public class TradeProcessor implements ItemProcessor {
|
||||
private static Log log = LogFactory.getLog(TradeProcessor.class);
|
||||
private TradeWriter writer;
|
||||
|
||||
private int failure = -1;
|
||||
|
||||
private int index = 0;
|
||||
|
||||
/**
|
||||
* Public setter for the {@link int} property.
|
||||
*
|
||||
* @param failure the failure to set
|
||||
*/
|
||||
public void setFailure(int failure) {
|
||||
this.failure = failure;
|
||||
}
|
||||
|
||||
public void process(Object data) {
|
||||
if (!(data instanceof Trade)) {
|
||||
@@ -40,6 +53,12 @@ public class TradeProcessor implements ItemProcessor {
|
||||
|
||||
//TODO put some processing of the trade object here
|
||||
writer.writeTrade(trade);
|
||||
|
||||
if(index++ == failure) {
|
||||
throw new RuntimeException("Something unexpected happened!");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void setWriter(TradeWriter dao) {
|
||||
|
||||
122
samples/src/main/resources/jobs/rollbackJob.xml
Normal file
122
samples/src/main/resources/jobs/rollbackJob.xml
Normal file
@@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
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">
|
||||
|
||||
<import resource="tradeJobIo.xml" />
|
||||
<!--import resource="tradeJobAop.xml" /-->
|
||||
|
||||
<bean parent="stepScope" />
|
||||
<bean parent="jobConfigurationRegistryBeanPostProcessor" />
|
||||
|
||||
<bean id="tradeJob" parent="simpleJob">
|
||||
<property name="steps">
|
||||
<list>
|
||||
<bean id="step1"
|
||||
class="org.springframework.batch.execution.step.RepeatOperationsStepConfiguration">
|
||||
<property name="chunkOperations">
|
||||
<bean
|
||||
class="org.springframework.batch.repeat.support.RepeatTemplate">
|
||||
<property name="completionPolicy">
|
||||
<bean
|
||||
class="org.springframework.batch.repeat.policy.SimpleCompletionPolicy">
|
||||
<property name="chunkSize"
|
||||
value="50" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
<property name="stepOperations">
|
||||
<bean
|
||||
class="org.springframework.batch.repeat.support.RepeatTemplate">
|
||||
<property name="exceptionHandler">
|
||||
<bean
|
||||
class="org.springframework.batch.repeat.exception.handler.SimpleLimitExceptionHandler"
|
||||
p:limit="5" p:type="java.lang.Exception"/>
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
<property name="tasklet">
|
||||
<bean
|
||||
class="org.springframework.batch.execution.tasklet.RestartableItemProviderTasklet">
|
||||
<property name="itemProvider">
|
||||
<bean
|
||||
class="org.springframework.batch.item.provider.ValidatingItemProvider">
|
||||
<property name="inputSource"
|
||||
ref="fileInputTemplate" />
|
||||
<property name="validator"
|
||||
ref="tradeValidator" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="itemProcessor">
|
||||
<bean
|
||||
class="org.springframework.batch.sample.item.processor.TradeProcessor"
|
||||
p:writer-ref="tradeDao" p:failure="3"/>
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
<bean id="step2" parent="simpleStep">
|
||||
<property name="tasklet">
|
||||
<bean
|
||||
class="org.springframework.batch.execution.tasklet.RestartableItemProviderTasklet">
|
||||
<property name="itemProvider">
|
||||
<bean
|
||||
class="org.springframework.batch.item.provider.InputSourceItemProvider"
|
||||
p:input-source-ref="tradeSqlInputSource" />
|
||||
</property>
|
||||
<property name="itemProcessor">
|
||||
<bean
|
||||
class="org.springframework.batch.sample.item.processor.DummyProcessor" />
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="tradeSqlInputSource"
|
||||
class="org.springframework.batch.io.cursor.JdbcCursorInputSource"
|
||||
scope="step">
|
||||
<aop:scoped-proxy />
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
<property name="sql"
|
||||
value="SELECT id, quantity, price, customer from TRADE" />
|
||||
<property name="mapper">
|
||||
<bean
|
||||
class="org.springframework.batch.sample.mapping.TradeRowMapper" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="customerSqlInputSource"
|
||||
class="org.springframework.batch.io.cursor.JdbcCursorInputSource"
|
||||
scope="step">
|
||||
<aop:scoped-proxy />
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
<property name="sql"
|
||||
value="SELECT id, name, credit FROM customer " />
|
||||
<property name="mapper">
|
||||
<bean
|
||||
class="org.springframework.batch.sample.mapping.CustomerCreditRowMapper" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="fileLocator"
|
||||
class="org.springframework.core.io.ClassPathResource">
|
||||
<constructor-arg type="java.lang.String"
|
||||
value="data/tradeJob/input/20070122.teststream.ImportTradeDataStep.txt" />
|
||||
</bean>
|
||||
|
||||
<bean id="customerFileLocator"
|
||||
class="org.springframework.core.io.FileSystemResource">
|
||||
<constructor-arg type="java.lang.String"
|
||||
value="target/test-outputs/20070122.testStream.CustomerReportStep.TEMP.txt" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -28,11 +28,10 @@
|
||||
|
||||
<menu name="Reference Material">
|
||||
<item name="${project.name}" href="index.html"/>
|
||||
<item name="Changelog" href="changelog.html"/>
|
||||
</menu>
|
||||
|
||||
<menu ref="reports"/>
|
||||
|
||||
</body>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.springframework.batch.sample;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
/**
|
||||
* Test for job that rolls back a trade that is processed.
|
||||
*
|
||||
* @author Robert Kasanicky
|
||||
*/
|
||||
public class RollbackJobFunctionalTests extends AbstractValidatingBatchLauncherTests {
|
||||
|
||||
int before = -1;
|
||||
|
||||
JdbcTemplate jdbcTemplate;
|
||||
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
return new String[] {"jobs/rollbackJob.xml"};
|
||||
}
|
||||
|
||||
protected void onSetUp() throws Exception {
|
||||
before = jdbcTemplate.queryForInt("SELECT COUNT(*) from TRADE");
|
||||
}
|
||||
|
||||
protected void validatePostConditions() throws Exception {
|
||||
int after = jdbcTemplate.queryForInt("SELECT COUNT(*) from TRADE");
|
||||
assertEquals(before+4, after);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -28,8 +28,9 @@
|
||||
<item name="Batch Processing Strategies" href="batch-processing-strategies.html"/>
|
||||
<item name="General Batch Principles and Guidelines" href="batch-principles-guidelines.html"/>
|
||||
<item name="Building" href="building.html"/>
|
||||
<item name="Getting Started" href="getting-started.html"/>
|
||||
<item name="FAQ" href="faq.html"/>
|
||||
<item name="Changelog" href="changelog.html"/>
|
||||
<item name="Recent Changes" href="http://opensource.atlassian.com/projects/spring/secure/IssueNavigator.jspa?reset=true&mode=hide&pid=10090&status=5&status=6&updated:previous=-1w&sorter/field=updated&sorter/order=DESC"/>
|
||||
<item name="Downloads" href="downloads.html"/>
|
||||
</menu>
|
||||
<menu ref="modules"/>
|
||||
|
||||
Reference in New Issue
Block a user