RESOLVED - issue BATCH-1420: Late Binding only happens first time when using inner bean definition with collection property

This commit is contained in:
dsyer
2009-10-16 19:15:17 +00:00
parent db1351f7ab
commit 232d739dbd
16 changed files with 585 additions and 30 deletions

View File

@@ -30,6 +30,8 @@ import org.springframework.beans.PropertyEditorRegistrySupport;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.TypeMismatchException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.BeanDefinitionVisitor;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
@@ -266,7 +268,7 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I
private Object getPropertyFromContext(String key) {
Object context = contextFactory.getContext();
if (context==null) {
if (context == null) {
throw new IllegalStateException("No context available while replacing placeholders.");
}
BeanWrapper wrapper = new BeanWrapperImpl(context);
@@ -334,30 +336,47 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I
}
}
} else if (value instanceof Map) {
}
else if (value instanceof Map) {
Map map = (Map) value;
Map newValue = new ManagedMap(map.size());
newValue.putAll(map);
super.visitMap(newValue);
value = newValue;
} else if (value instanceof List) {
}
else if (value instanceof List) {
List list = (List) value;
List newValue = new ManagedList(list.size());
newValue.addAll(list);
super.visitList(newValue);
value = newValue;
} else if (value instanceof Set) {
}
else if (value instanceof Set) {
Set list = (Set) value;
Set newValue = new ManagedSet(list.size());
newValue.addAll(list);
super.visitSet(newValue);
value = newValue;
}
else if (value instanceof BeanDefinition) {
BeanDefinition newValue = new GenericBeanDefinition((BeanDefinition) value);
visitBeanDefinition((BeanDefinition) newValue);
value = newValue;
}
else if (value instanceof BeanDefinitionHolder) {
BeanDefinition newValue = new GenericBeanDefinition(((BeanDefinitionHolder) value).getBeanDefinition());
visitBeanDefinition((BeanDefinition) newValue);
value = newValue;
}
else {

View File

@@ -7,6 +7,7 @@ import static org.junit.Assert.fail;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import org.junit.Before;
import org.junit.Test;
@@ -26,6 +27,8 @@ public class TaskExecutorPartitionHandlerTests {
private TaskExecutorPartitionHandler handler = new TaskExecutorPartitionHandler();
private int count = 0;
private Collection<String> stepExecutions = new TreeSet<String>();
private StepExecution stepExecution = new StepExecution("step", new JobExecution(1L));
@@ -50,6 +53,7 @@ public class TaskExecutorPartitionHandlerTests {
@Override
public void execute(StepExecution stepExecution) throws JobInterruptedException {
count++;
stepExecutions.add(stepExecution.getStepName());
}
});
handler.afterPropertiesSet();
@@ -74,6 +78,7 @@ public class TaskExecutorPartitionHandlerTests {
handler.setGridSize(2);
handler.handle(stepExecutionSplitter, stepExecution);
assertEquals(2, count);
assertEquals("[foo0, foo1]", stepExecutions.toString());
}
@Test

View File

@@ -61,6 +61,10 @@ public class MultipleContextPlaceholderTargetSourceTests {
@Qualifier("list")
private TestBean list;
@Autowired
@Qualifier("nestedList")
private TestBean nestedList;
@Autowired
@Qualifier("map")
private TestBean map;
@@ -120,6 +124,23 @@ public class MultipleContextPlaceholderTargetSourceTests {
}
@Test
public void testMultipleValueInNestedList() throws Exception {
for (int i = 0; i < 4; i++) {
final String value = "foo" + i;
contextFactory.setContext(this);
attributes = Collections.singletonMap("foo", value);
try {
assertEquals("foo" + i, nestedList.getParent().getNames().get(0));
}
finally {
contextFactory.clearContext();
}
}
}
@Test
public void testMultipleValueInMap() throws Exception {
@@ -144,10 +165,20 @@ public class MultipleContextPlaceholderTargetSourceTests {
public static class TestBean {
private String name;
private TestBean parent;
private List<String> names = new ArrayList<String>();
private Map<String, String> map = new HashMap<String, String>();
public TestBean getParent() {
return parent;
}
public void setParent(TestBean parent) {
this.parent = parent;
}
public String getName() {
return name;

View File

@@ -36,6 +36,16 @@
</property>
</bean>
<bean id="nestedList" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="targetSource">
<bean
class="org.springframework.batch.core.scope.util.PlaceholderTargetSource">
<property name="contextFactory" ref="context" />
<property name="targetBeanName" value="nestedListTarget" />
</bean>
</property>
</bean>
<bean id="map" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="targetSource">
<bean
@@ -60,7 +70,22 @@
class="org.springframework.batch.core.scope.util.MultipleContextPlaceholderTargetSourceTests$TestBean">
<property name="names">
<list>
<value>%{attributes[foo]}</value></list>
<value>%{attributes[foo]}</value>
</list>
</property>
</bean>
<bean id="nestedListTarget"
class="org.springframework.batch.core.scope.util.MultipleContextPlaceholderTargetSourceTests$TestBean">
<property name="parent">
<bean
class="org.springframework.batch.core.scope.util.MultipleContextPlaceholderTargetSourceTests$TestBean">
<property name="names">
<list>
<value>%{attributes[foo]}</value>
</list>
</property>
</bean>
</property>
</bean>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<beansProjectDescription>
<version>1</version>
<pluginVersion><![CDATA[2.2.7.200909172100-CI-R3407-B467]]></pluginVersion>
<pluginVersion><![CDATA[2.2.7.200909182116-CI-R3408-B468]]></pluginVersion>
<configSuffixes>
<configSuffix><![CDATA[xml]]></configSuffix>
</configSuffixes>
@@ -60,13 +60,11 @@
<config>src/test/resources/org/springframework/batch/sample/MultilineJobFunctionalTests-context.xml</config>
<config>src/test/resources/org/springframework/batch/sample/MultilineOrderJobFunctionalTests-context.xml</config>
<config>src/test/resources/org/springframework/batch/sample/ParallelJobFunctionalTests-context.xml</config>
<config>src/main/resources/jobs/partitionJob.xml</config>
<config>src/test/resources/org/springframework/batch/sample/RestartFunctionalTests-context.xml</config>
<config>src/test/resources/org/springframework/batch/sample/RetrySampleFunctionalTests-context.xml</config>
<config>src/test/resources/org/springframework/batch/sample/common/StagingItemReaderTests-context.xml</config>
<config>src/test/resources/org/springframework/batch/sample/common/StagingItemWriterTests-context.xml</config>
<config>src/test/resources/org/springframework/batch/sample/TradeJobFunctionalTests-context.xml</config>
<config>src/test/resources/org/springframework/batch/sample/PartitionJobFunctionalTests-context.xml</config>
<config>src/main/resources/jobs/multilineOrderValidator.xml</config>
<config>src/main/resources/jobs/restartFileSampleJob.xml</config>
<config>src/main/resources/jobs/taskletJob.xml</config>
@@ -75,6 +73,7 @@
<config>src/main/resources/jobs/iosample/jdbcPaging.xml</config>
<config>src/test/resources/org/springframework/batch/sample/GroovyJobFunctionalTests-context.xml</config>
<config>src/test/resources/org/springframework/batch/sample/TaskletJobFunctionalTests-context.xml</config>
<config>src/main/resources/jobs/partitionJdbcJob.xml</config>
</configs>
<configSets>
<configSet>
@@ -395,7 +394,6 @@
<incomplete>false</incomplete>
<configs>
<config>src/main/resources/data-source-context.xml</config>
<config>src/main/resources/jobs/partitionJob.xml</config>
<config>src/main/resources/simple-job-launcher-context.xml</config>
</configs>
</configSet>

View File

@@ -0,0 +1,93 @@
package org.springframework.batch.sample.common;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.batch.core.partition.support.Partitioner;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
/**
* Simple minded partitioner for a range of values of a column in a database
* table. Works best if the values are uniformly distributed (e.g.
* auto-generated primary key values).
*
* @author Dave Syer
*
*/
public class ColumnRangePartitioner implements Partitioner {
private SimpleJdbcTemplate jdbcTemplate;
private String table;
private String column;
/**
* The name of the SQL table the data are in.
*
* @param table the name of the table
*/
public void setTable(String table) {
this.table = table;
}
/**
* The name of the column to partition.
*
* @param column the column name.
*/
public void setColumn(String column) {
this.column = column;
}
/**
* The data source for connecting to the database.
*
* @param dataSource a {@link DataSource}
*/
public void setDataSource(DataSource dataSource) {
jdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
/**
* Partition a database table assuming that the data in the column specified
* are uniformly distributed. The execution context values will have keys
* <code>minValue</code> and <code>maxValue</code> specifying the range of
* values to consider in each partition.
*
* @see Partitioner#partition(int)
*/
public Map<String, ExecutionContext> partition(int gridSize) {
int min = jdbcTemplate.queryForInt("SELECT MIN(" + column + ") from " + table);
int max = jdbcTemplate.queryForInt("SELECT MAX(" + column + ") from " + table);
int targetSize = (max - min) / gridSize + 1;
Map<String, ExecutionContext> result = new HashMap<String, ExecutionContext>();
int number = 0;
int start = min;
int end = start + targetSize - 1;
while (start <= max) {
ExecutionContext value = new ExecutionContext();
result.put("partition" + number, value);
if (end >= max) {
end = max;
}
value.putInt("minValue", start);
value.putInt("maxValue", end);
start += targetSize;
end += targetSize;
number++;
}
return result;
}
}

View File

@@ -30,6 +30,12 @@ public class OutputFileListener {
private String inputKeyName = "fileName";
private String path = "file:./target/output/";
public void setPath(String path) {
this.path = path;
}
public void setOutputKeyName(String outputKeyName) {
this.outputKeyName = outputKeyName;
}
@@ -39,11 +45,15 @@ public class OutputFileListener {
}
@BeforeStep
public void CreateOutputNameFromInput(StepExecution stepExecution) {
public void createOutputNameFromInput(StepExecution stepExecution) {
ExecutionContext executionContext = stepExecution.getExecutionContext();
if (executionContext.containsKey(inputKeyName) && !executionContext.containsKey(outputKeyName)) {
String inputName = executionContext.getString(inputKeyName);
executionContext.putString(outputKeyName, "file:./target/output/" + FilenameUtils.getBaseName(inputName) + ".csv");
String inputName = stepExecution.getStepName().replace(":", "-");
if (executionContext.containsKey(inputKeyName)) {
inputName = executionContext.getString(inputKeyName);
}
if (!executionContext.containsKey(outputKeyName)) {
executionContext.putString(outputKeyName, path + FilenameUtils.getBaseName(inputName)
+ ".csv");
}
}

View File

@@ -29,6 +29,7 @@
<bean class="org.springframework.core.task.SyncTaskExecutor" />
</property>
<property name="step" ref="step1" />
<property name="gridSize" value="2"/>
</bean>
</property>
</bean>
@@ -42,7 +43,10 @@
</tasklet>
</step>
<bean id="fileNameListener" class="org.springframework.batch.sample.common.OutputFileListener" scope="step"/>
<bean id="fileNameListener" class="org.springframework.batch.sample.common.OutputFileListener" scope="step">
<property name="path" value="file:./target/output/file/"/>
</bean>
<bean id="itemReader" scope="step" autowire-candidate="false" parent="itemReaderParent">
<property name="resource" value="#{stepExecutionContext[fileName]}" />
@@ -54,7 +58,7 @@
</bean>
<bean id="outputTestReader" class="org.springframework.batch.item.file.MultiResourceItemReader" scope="prototype">
<property name="resources" value="file:target/output/delimited*.csv" />
<property name="resources" value="file:target/output/file/delimited*.csv" />
<property name="delegate" ref="testItemReader" />
</bean>

View File

@@ -0,0 +1,146 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<job id="partitionJdbcJob" xmlns="http://www.springframework.org/schema/batch">
<step id="step" parent="step1:master" />
</job>
<bean name="step1:master"
class="org.springframework.batch.core.partition.support.PartitionStep">
<property name="jobRepository" ref="jobRepository" />
<property name="stepExecutionSplitter">
<bean
class="org.springframework.batch.core.partition.support.SimpleStepExecutionSplitter">
<constructor-arg ref="jobRepository" />
<constructor-arg ref="step1" />
<constructor-arg>
<bean
class="org.springframework.batch.sample.common.ColumnRangePartitioner">
<property name="dataSource" ref="dataSource" />
<property name="table" value="CUSTOMER" />
<property name="column" value="ID" />
</bean>
</constructor-arg>
</bean>
</property>
<property name="partitionHandler">
<bean
class="org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler">
<property name="taskExecutor">
<bean class="org.springframework.core.task.SyncTaskExecutor" />
</property>
<property name="step" ref="step1" />
<property name="gridSize" value="2"/>
</bean>
</property>
</bean>
<step id="step1" xmlns="http://www.springframework.org/schema/batch">
<tasklet job-repository="jobRepository" transaction-manager="transactionManager">
<chunk writer="itemWriter" reader="itemReader" processor="itemProcessor"
commit-interval="5" />
<listeners>
<listener ref="fileNameListener" />
</listeners>
</tasklet>
</step>
<bean id="fileNameListener"
class="org.springframework.batch.sample.common.OutputFileListener"
scope="step">
<property name="path" value="file:./target/output/jdbc/"/>
</bean>
<bean id="itemReader" scope="step" autowire-candidate="false"
parent="itemReaderParent">
<property name="sql">
<value>
<![CDATA[
select ID,NAME,CREDIT from CUSTOMER where ID >= ? and ID <= ?
]]>
</value>
</property>
<property name="preparedStatementSetter">
<bean
class="org.springframework.batch.core.resource.ListPreparedStatementSetter">
<property name="parameters">
<list>
<value>#{stepExecutionContext[minValue]}</value>
<value>#{stepExecutionContext[maxValue]}</value>
</list>
</property>
</bean>
</property>
</bean>
<bean id="outputTestReader"
class="org.springframework.batch.item.file.MultiResourceItemReader"
scope="prototype">
<property name="resources" value="file:target/output/jdbc/*.csv" />
<property name="delegate" ref="testItemReader" />
</bean>
<bean id="testItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="delimiter" value="," />
<property name="names" value="id,name,credit" />
</bean>
</property>
<property name="fieldSetMapper">
<bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="targetType" value="org.springframework.batch.sample.domain.trade.CustomerCredit" />
</bean>
</property>
</bean>
</property>
</bean>
<bean id="inputTestReader" parent="itemReaderParent">
<property name="sql">
<value>
<![CDATA[
select ID,NAME,CREDIT from CUSTOMER
]]>
</value>
</property>
</bean>
<bean id="itemReaderParent"
class="org.springframework.batch.item.database.JdbcCursorItemReader"
abstract="true">
<property name="dataSource" ref="dataSource" />
<property name="rowMapper">
<bean
class="org.springframework.batch.sample.domain.trade.internal.CustomerCreditRowMapper" />
</property>
</bean>
<bean id="itemProcessor"
class="org.springframework.batch.sample.domain.trade.internal.CustomerCreditIncreaseProcessor" />
<bean id="itemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter"
scope="step">
<property name="resource" value="#{stepExecutionContext[outputFile]}" />
<property name="lineAggregator">
<bean
class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
<property name="delimiter" value="," />
<property name="fieldExtractor">
<bean
class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
<property name="names" value="id,name,credit" />
</bean>
</property>
</bean>
</property>
</bean>
</beans>

View File

@@ -0,0 +1,118 @@
/*
* Copyright 2006-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.sample;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.sample.domain.trade.CustomerCredit;
import org.springframework.batch.sample.domain.trade.internal.CustomerCreditIncreaseProcessor;
import org.springframework.batch.test.AbstractJobTests;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration()
public class PartitionFileJobFunctionalTests extends AbstractJobTests {
@Autowired
@Qualifier("inputTestReader")
private ItemReader<CustomerCredit> inputReader;
@Autowired
@Qualifier("outputTestReader")
private ItemReader<CustomerCredit> outputReader;
/**
* Check the resulting credits correspond to inputs increased by fixed
* amount.
*/
@Test
public void testUpdateCredit() throws Exception {
assertTrue("Define a prototype bean called 'outputTestReader' to check the output", getApplicationContext()
.containsBeanDefinition("outputTestReader"));
open(inputReader);
List<CustomerCredit> inputs = new ArrayList<CustomerCredit>(getCredits(inputReader));
close(inputReader);
JobExecution jobExecution = this.launchJob();
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
open(outputReader);
List<CustomerCredit> outputs = new ArrayList<CustomerCredit>(getCredits(outputReader));
close(outputReader);
assertEquals(inputs.size(), outputs.size());
int itemCount = inputs.size();
assertTrue(itemCount > 0);
inputs.iterator();
for (int i = 0; i < itemCount; i++) {
assertEquals(inputs.get(i).getCredit().add(CustomerCreditIncreaseProcessor.FIXED_AMOUNT).intValue(),
outputs.get(i).getCredit().intValue());
}
}
/**
* Read all credits using the provided reader.
*/
private Set<CustomerCredit> getCredits(ItemReader<CustomerCredit> reader) throws Exception {
CustomerCredit credit;
Set<CustomerCredit> result = new LinkedHashSet<CustomerCredit>();
while ((credit = reader.read()) != null) {
result.add(credit);
}
return result;
}
/**
* Open the reader if applicable.
*/
private void open(ItemReader<?> reader) {
if (reader instanceof ItemStream) {
((ItemStream) reader).open(new ExecutionContext());
}
}
/**
* Close the reader if applicable.
*/
private void close(ItemReader<?> reader) {
if (reader instanceof ItemStream) {
((ItemStream) reader).close();
}
}
}

View File

@@ -20,7 +20,9 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -39,12 +41,16 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration()
public class PartitionJobFunctionalTests extends AbstractJobTests {
public class PartitionJdbcJobFunctionalTests extends AbstractJobTests {
@Autowired
@Qualifier("inputTestReader")
private ItemReader<CustomerCredit> inputReader;
@Autowired
@Qualifier("outputTestReader")
private ItemReader<CustomerCredit> outputReader;
/**
* Check the resulting credits correspond to inputs increased by fixed
* amount.
@@ -56,23 +62,21 @@ public class PartitionJobFunctionalTests extends AbstractJobTests {
.containsBeanDefinition("outputTestReader"));
open(inputReader);
List<CustomerCredit> inputs = getCredits(inputReader);
List<CustomerCredit> inputs = new ArrayList<CustomerCredit>(getCredits(inputReader));
close(inputReader);
JobExecution jobExecution = this.launchJob();
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
@SuppressWarnings("unchecked")
ItemReader<CustomerCredit> outputReader = (ItemReader<CustomerCredit>) getApplicationContext().getBean(
"outputTestReader");
open(outputReader);
List<CustomerCredit> outputs = getCredits(outputReader);
List<CustomerCredit> outputs = new ArrayList<CustomerCredit>(getCredits(outputReader));
close(outputReader);
assertEquals(inputs.size(), outputs.size());
int itemCount = inputs.size();
assertTrue(itemCount > 0);
inputs.iterator();
for (int i = 0; i < itemCount; i++) {
assertEquals(inputs.get(i).getCredit().add(CustomerCreditIncreaseProcessor.FIXED_AMOUNT).intValue(),
outputs.get(i).getCredit().intValue());
@@ -83,9 +87,9 @@ public class PartitionJobFunctionalTests extends AbstractJobTests {
/**
* Read all credits using the provided reader.
*/
private List<CustomerCredit> getCredits(ItemReader<CustomerCredit> reader) throws Exception {
private Set<CustomerCredit> getCredits(ItemReader<CustomerCredit> reader) throws Exception {
CustomerCredit credit;
List<CustomerCredit> result = new ArrayList<CustomerCredit>();
Set<CustomerCredit> result = new LinkedHashSet<CustomerCredit>();
while ((credit = reader.read()) != null) {
result.add(credit);
}

View File

@@ -0,0 +1,38 @@
package org.springframework.batch.sample.common;
import static org.junit.Assert.assertEquals;
import java.util.Map;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class ColumnRangePartitionerTests {
private DataSource dataSource;
@Autowired
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
private ColumnRangePartitioner partitioner = new ColumnRangePartitioner();
@Test
public void testPartition() {
partitioner.setDataSource(dataSource);
partitioner.setTable("CUSTOMER");
partitioner.setColumn("ID");
Map<String, ExecutionContext> partition = partitioner.partition(2);
assertEquals(2, partition.size());
}
}

View File

@@ -0,0 +1,44 @@
package org.springframework.batch.sample.common;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.StepExecution;
public class OutputFileListenerTests {
private OutputFileListener listener = new OutputFileListener();
private StepExecution stepExecution = new StepExecution("foo", new JobExecution(0L), 1L);
@Test
public void testCreateOutputNameFromInput() {
listener.createOutputNameFromInput(stepExecution);
assertEquals("{outputFile=file:./target/output/foo.csv}", stepExecution.getExecutionContext().toString());
}
@Test
public void testSetPath() {
listener.setPath("spam/");
listener.createOutputNameFromInput(stepExecution);
assertEquals("{outputFile=spam/foo.csv}", stepExecution.getExecutionContext().toString());
}
@Test
public void testSetOutputKeyName() {
listener.setPath("");
listener.setOutputKeyName("spam");
listener.createOutputNameFromInput(stepExecution);
assertEquals("{spam=foo.csv}", stepExecution.getExecutionContext().toString());
}
@Test
public void testSetInputKeyName() {
listener.setPath("");
listener.setInputKeyName("spam");
stepExecution.getExecutionContext().putString("spam", "bar");
listener.createOutputNameFromInput(stepExecution);
assertEquals("{outputFile=bar.csv, spam=bar}", stepExecution.getExecutionContext().toString());
}
}

View File

@@ -5,6 +5,6 @@
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<import resource="classpath:/simple-job-launcher-context.xml" />
<import resource="classpath:/jobs/partitionJob.xml" />
<import resource="classpath:/jobs/partitionFileJob.xml" />
</beans>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<import resource="classpath:/simple-job-launcher-context.xml" />
<import resource="classpath:/jobs/partitionJdbcJob.xml" />
</beans>

View File

@@ -0,0 +1,10 @@
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">
<import resource="classpath:data-source-context.xml"/>
</beans>