IN PROGRESS - issue BATCH-7: Remove transaction synchronization and state management from input/output sources (formerly buffering)

http://jira.springframework.org/browse/BATCH-7

Lazy-initialisation solution to the "who's in step scope" issue
This commit is contained in:
dsyer
2008-01-31 09:54:38 +00:00
parent 9d1ebb42c7
commit 15cffeb925
66 changed files with 653 additions and 761 deletions

View File

@@ -76,7 +76,7 @@ public class DrivingQueryItemReaderTests extends TestCase {
Foo foo2 = (Foo) source.read();
assertEquals(2, foo2.getValue());
StreamContext streamContext = getAsRestartable(source).getRestartData();
StreamContext streamContext = getAsRestartable(source).getStreamContext();
// create new input source
source = createItemReader();
@@ -98,7 +98,7 @@ public class DrivingQueryItemReaderTests extends TestCase {
Foo foo2 = (Foo) source.read();
assertEquals(2, foo2.getValue());
StreamContext streamContext = getAsRestartable(source).getRestartData();
StreamContext streamContext = getAsRestartable(source).getStreamContext();
// create new input source
source = createItemReader();
@@ -198,7 +198,7 @@ public class DrivingQueryItemReaderTests extends TestCase {
restartKeys.add(new Foo(5, "5", 5));
}
public StreamContext getKeyAsRestartData(Object key) {
public StreamContext getKeyAsStreamContext(Object key) {
return streamContext;
}

View File

@@ -27,8 +27,8 @@ class FooItemReader extends AbstractItemReader implements ItemStream, ItemReader
}
}
public StreamContext getRestartData() {
return inputSource.getRestartData();
public StreamContext getStreamContext() {
return inputSource.getStreamContext();
}
public void restoreFrom(StreamContext data) {
@@ -46,6 +46,9 @@ class FooItemReader extends AbstractItemReader implements ItemStream, ItemReader
public void afterPropertiesSet() throws Exception {
}
public void open() throws Exception {
public void open() {
};
public void close() {
};
}

View File

@@ -22,9 +22,9 @@ import org.springframework.util.ClassUtils;
*/
public class ColumnMapRestartDataRowMapperTests extends TestCase {
private static final String KEY = ClassUtils.getQualifiedName(ColumnMapRestartDataRowMapper.class) + ".KEY.";
private static final String KEY = ClassUtils.getQualifiedName(ColumnMapStreamContextRowMapper.class) + ".KEY.";
ColumnMapRestartDataRowMapper mapper;
ColumnMapStreamContextRowMapper mapper;
Map key;
@@ -34,7 +34,7 @@ public class ColumnMapRestartDataRowMapperTests extends TestCase {
protected void setUp() throws Exception {
super.setUp();
mapper = new ColumnMapRestartDataRowMapper();
mapper = new ColumnMapStreamContextRowMapper();
key = CollectionFactory.createLinkedCaseInsensitiveMapIfPossible(2);
key.put("1", new Integer(1));

View File

@@ -47,8 +47,8 @@ public class MultipleColumnJdbcKeyGeneratorIntegrationTests extends AbstractTran
public void testRestoreKeys(){
Properties props = new Properties();
props.setProperty(ColumnMapRestartDataRowMapper.KEY + "0", "3");
props.setProperty(ColumnMapRestartDataRowMapper.KEY + "1", "3");
props.setProperty(ColumnMapStreamContextRowMapper.KEY + "0", "3");
props.setProperty(ColumnMapStreamContextRowMapper.KEY + "1", "3");
StreamContext streamContext = new GenericStreamContext(props);
List keys = keyStrategy.restoreKeys(streamContext);
@@ -68,18 +68,18 @@ public class MultipleColumnJdbcKeyGeneratorIntegrationTests extends AbstractTran
key.put("ID", new Long(3));
key.put("VALUE", new Integer(3));
StreamContext streamContext = keyStrategy.getKeyAsRestartData(key);
StreamContext streamContext = keyStrategy.getKeyAsStreamContext(key);
Properties props = streamContext.getProperties();
assertEquals(2, props.size());
assertEquals("3", props.get(ColumnMapRestartDataRowMapper.KEY + "0"));
assertEquals("3", props.get(ColumnMapRestartDataRowMapper.KEY + "1"));
assertEquals("3", props.get(ColumnMapStreamContextRowMapper.KEY + "0"));
assertEquals("3", props.get(ColumnMapStreamContextRowMapper.KEY + "1"));
}
public void testGetNullKeyAsRestartData(){
public void testGetNullKeyAsStreamContext(){
try{
keyStrategy.getKeyAsRestartData(null);
keyStrategy.getKeyAsStreamContext(null);
fail();
}catch(IllegalArgumentException ex){
//expected
@@ -89,7 +89,7 @@ public class MultipleColumnJdbcKeyGeneratorIntegrationTests extends AbstractTran
public void testRestoreKeysFromNull(){
try{
keyStrategy.getKeyAsRestartData(null);
keyStrategy.getKeyAsStreamContext(null);
}catch(IllegalArgumentException ex){
//expected
}

View File

@@ -53,19 +53,19 @@ public class SingleColumnJdbcKeyGeneratorIntegrationTests extends AbstractTransa
assertEquals(new Long(5), keys.get(1));
}
public void testGetKeyAsRestartData(){
public void testGetKeyAsStreamContext(){
StreamContext streamContext = keyStrategy.getKeyAsRestartData(new Long(3));
StreamContext streamContext = keyStrategy.getKeyAsStreamContext(new Long(3));
Properties props = streamContext.getProperties();
assertEquals(1, props.size());
assertEquals("3", props.get(SingleColumnJdbcKeyGenerator.RESTART_KEY));
}
public void testGetNullKeyAsRestartData(){
public void testGetNullKeyAsStreamContext(){
try{
keyStrategy.getKeyAsRestartData(null);
keyStrategy.getKeyAsStreamContext(null);
fail();
}catch(IllegalArgumentException ex){
//expected
@@ -75,7 +75,7 @@ public class SingleColumnJdbcKeyGeneratorIntegrationTests extends AbstractTransa
public void testRestoreKeysFromNull(){
try{
keyStrategy.getKeyAsRestartData(null);
keyStrategy.getKeyAsStreamContext(null);
}catch(IllegalArgumentException ex){
//expected
}

View File

@@ -184,7 +184,7 @@ public class DefaultFlatFileItemReaderTests extends TestCase {
inputSource.setResource(getInputResource(TEST_STRING));
inputSource.setFieldSetMapper(fieldSetMapper);
// do not open the template...
inputSource.restoreFrom(inputSource.getRestartData());
inputSource.restoreFrom(inputSource.getStreamContext());
assertEquals("[FlatFileInputTemplate-TestData]", inputSource.read().toString());
}
@@ -204,7 +204,7 @@ public class DefaultFlatFileItemReaderTests extends TestCase {
inputSource.read();
// get restart data
StreamContext streamContext = inputSource.getRestartData();
StreamContext streamContext = inputSource.getStreamContext();
assertEquals("4", (String) streamContext.getProperties().getProperty(
DefaultFlatFileItemReader.READ_STATISTICS_NAME));
// close input

View File

@@ -320,7 +320,7 @@ public class FlatFileItemWriterTests extends TestCase {
commit();
// get restart data
StreamContext restartData = inputSource.getRestartData();
StreamContext streamContext = inputSource.getStreamContext();
// close template
inputSource.close();
@@ -338,7 +338,7 @@ public class FlatFileItemWriterTests extends TestCase {
}
// init with correct data
inputSource.restoreFrom(restartData);
inputSource.restoreFrom(streamContext);
// write more lines
inputSource.write("testLine6");
@@ -371,9 +371,9 @@ public class FlatFileItemWriterTests extends TestCase {
}
}
public void testDefaultRestartData() throws Exception {
public void testDefaultStreamContext() throws Exception {
inputSource = new FlatFileItemWriter();
StreamContext streamContext = inputSource.getRestartData();
StreamContext streamContext = inputSource.getStreamContext();
assertNotNull(streamContext);
assertEquals(1, streamContext.getProperties().size());
assertEquals("0", streamContext.getProperties().getProperty(FlatFileItemWriter.RESTART_DATA_NAME));

View File

@@ -85,7 +85,7 @@ public abstract class AbstractJdbcItemReaderIntegrationTests extends AbstractTra
Foo foo2 = (Foo) source.read();
assertEquals(2, foo2.getValue());
StreamContext streamContext = getAsRestartable(source).getRestartData();
StreamContext streamContext = getAsRestartable(source).getStreamContext();
// create new input source
source = createItemReader();
@@ -107,7 +107,7 @@ public abstract class AbstractJdbcItemReaderIntegrationTests extends AbstractTra
Foo foo2 = (Foo) source.read();
assertEquals(2, foo2.getValue());
StreamContext streamContext = getAsRestartable(source).getRestartData();
StreamContext streamContext = getAsRestartable(source).getStreamContext();
// create new input source
source = createItemReader();

View File

@@ -92,7 +92,7 @@ public abstract class AbstractDataSourceItemReaderIntegrationTests extends Abstr
Foo foo2 = (Foo) source.read();
assertEquals(2, foo2.getValue());
StreamContext streamContext = getAsRestartable(source).getRestartData();
StreamContext streamContext = getAsRestartable(source).getStreamContext();
// create new input source
source = createItemReader();
@@ -114,7 +114,7 @@ public abstract class AbstractDataSourceItemReaderIntegrationTests extends Abstr
Foo foo2 = (Foo) source.read();
assertEquals(2, foo2.getValue());
StreamContext streamContext = getAsRestartable(source).getRestartData();
StreamContext streamContext = getAsRestartable(source).getStreamContext();
// create new input source
source = createItemReader();
@@ -217,7 +217,7 @@ public abstract class AbstractDataSourceItemReaderIntegrationTests extends Abstr
rollback();
StreamContext streamContext = getAsRestartable(source).getRestartData();
StreamContext streamContext = getAsRestartable(source).getStreamContext();
// create new input source
source = createItemReader();

View File

@@ -117,7 +117,7 @@ public class StaxEventReaderItemReaderTests extends TestCase {
*/
public void testRestart() {
source.read();
StreamContext streamContext = source.getRestartData();
StreamContext streamContext = source.getStreamContext();
assertEquals("1", streamContext.getProperties().
getProperty("StaxEventReaderItemReader.recordcount"));
List expectedAfterRestart = (List) source.read();

View File

@@ -92,7 +92,7 @@ public class StaxEventWriterItemWriterTests extends TestCase {
// write records
writer.write(record);
writer.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
StreamContext streamContext = writer.getRestartData();
StreamContext streamContext = writer.getStreamContext();
// create new writer from saved restart data and continue writing
writer = createItemWriter();

View File

@@ -75,8 +75,8 @@ public class DelegatingItemReaderTests extends TestCase {
/**
* Gets restart data from the input template
*/
public void testGetRestartData() {
Properties props = itemProvider.getRestartData().getProperties();
public void testGetStreamContext() {
Properties props = itemProvider.getStreamContext().getProperties();
assertEquals("foo", props.getProperty("value"));
}
@@ -102,7 +102,7 @@ public class DelegatingItemReaderTests extends TestCase {
return PropertiesConverter.stringToProperties("a=b");
}
public StreamContext getRestartData() {
public StreamContext getStreamContext() {
return new GenericStreamContext(PropertiesConverter.stringToProperties("value=foo"));
}

View File

@@ -3,17 +3,11 @@ package org.springframework.batch.item.writer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.StreamContext;
import org.springframework.batch.item.stream.GenericStreamContext;
import org.springframework.batch.item.writer.CompositeItemWriter;
import org.springframework.batch.statistics.StatisticsProvider;
/**
* Tests for {@link CompositeItemWriter}
@@ -57,37 +51,7 @@ public class CompositeItemWriterTests extends TestCase {
control.verify();
}
}
/**
* All Restartable processors should be restarted, not-Restartable processors should be ignored.
*/
public void testRestart() {
//this mock with undefined behaviour makes sure not-Restartable processor is ignored
MockControl p1c = MockControl.createStrictControl(ItemWriter.class);
final ItemWriter p1 = (ItemWriter) p1c.getMock();
final ItemWriter p2 = new StubItemWriter();
final ItemWriter p3 = new StubItemWriter();
List itemProcessors = new ArrayList(){{
add(p1);
add(p2);
add(p3);
}};
itemProcessor.setDelegates(itemProcessors);
StreamContext rd = itemProcessor.getRestartData();
itemProcessor.restoreFrom(rd);
for (Iterator iterator = itemProcessors.iterator(); iterator.hasNext();) {
ItemWriter processor = (ItemWriter) iterator.next();
if (processor instanceof StubItemWriter) {
assertTrue("Injected processors are restarted",
((StubItemWriter)processor).restarted);
}
}
}
public void testClose() throws Exception {
final int NUMBER_OF_PROCESSORS = 10;
@@ -115,49 +79,4 @@ public class CompositeItemWriterTests extends TestCase {
}
/**
* Stub for testing restart. Checks the restart data received is the same that was returned by
* <code>getRestartData()</code>
*/
private static class StubItemWriter implements ItemWriter, ItemStream, StatisticsProvider {
private static final String RESTART_KEY = "restartData";
private static final String STATS_KEY = "stats";
private boolean restarted = false;
private final int hashCode = this.hashCode();
public StreamContext getRestartData() {
Properties props = new Properties(){{
setProperty(RESTART_KEY, String.valueOf(hashCode));
}};
return new GenericStreamContext(props);
}
public void restoreFrom(StreamContext data) {
if (Integer.valueOf(data.getProperties().getProperty(RESTART_KEY)).intValue() != hashCode()) {
fail("received restart data is not the same which was saved");
}
restarted = true;
}
public void write(Object data) throws Exception {
// do nothing
}
public Properties getStatistics() {
return new Properties() {{
setProperty(STATS_KEY, String.valueOf(hashCode));
}};
}
public void close() throws Exception {
}
public void open() throws Exception {
}
}
}

View File

@@ -59,8 +59,8 @@ public class ItemWriterItemProcessorTests extends TestCase {
/**
* Gets restart data from the input template
*/
public void testGetRestartData() {
Properties props = processor.getRestartData().getProperties();
public void testGetStreamContext() {
Properties props = processor.getStreamContext().getProperties();
assertEquals("foo", props.getProperty("value"));
}
@@ -78,10 +78,10 @@ public class ItemWriterItemProcessorTests extends TestCase {
* Forward restart data to input template
* @throws Exception
*/
public void testGetRestartDataWithoutRestartable() throws Exception {
public void testGetStreamContextWithoutItemStream() throws Exception {
processor.setDelegate(null);
try {
processor.getRestartData();
processor.getStreamContext();
fail("Expected IllegalStateException");
}
catch (IllegalStateException e) {
@@ -152,7 +152,7 @@ public class ItemWriterItemProcessorTests extends TestCase {
return PropertiesConverter.stringToProperties("a=b");
}
public StreamContext getRestartData() {
public StreamContext getStreamContext() {
return new GenericStreamContext(PropertiesConverter.stringToProperties("value=foo"));
}