BATCH-910: A new job has been added to showcase the JobParametersIncrementer usage of JobOperator, and the non-sequential step was updated to use a file name coming from JobParameters.
This commit is contained in:
@@ -10,7 +10,7 @@ import org.springframework.batch.repeat.RepeatStatus;
|
||||
import org.springframework.core.AttributeAccessor;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
|
||||
public class ErrorLogWriter implements Tasklet {
|
||||
public class ErrorLogTasklet implements Tasklet {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
private SimpleJdbcTemplate simpleJdbcTemplate;
|
||||
@@ -0,0 +1,20 @@
|
||||
AbduKa00,Abdul-Jabbar,Karim,rb,1974,1996
|
||||
AbduRa00,Abdullah,Rabih,rb,1975,1999
|
||||
AberWa00,Abercrombie,Walter,rb,1959,1982
|
||||
AbraDa00,Abramowicz,Danny,wr,1945,1967
|
||||
AdamBo00,Adams,Bob,te,1946,1969
|
||||
AdamCh00,Adams,Charlie,wr,1979,2003
|
||||
AdamCu00,Adams,Curtis,rb,1962
|
||||
AdamGe00,Adams,George,rb,1962,1985
|
||||
AdamGr00,Adams,Grant,2000,2005
|
||||
AdamJo00,Adams,John,rb,1937,1959
|
||||
Adams,Michael,wr,1974,1997
|
||||
AdamMi01,Adamle,Mike,rb,1949,1971
|
||||
AdamTo00,Adams,Tony,qb,1950,1975
|
||||
AdamTo01,Adams,Tom,wr,1940,1962
|
||||
AdamTo02,Adamle,Tony,rb,,1950
|
||||
AdamWi00,Adams,Willie,wr,1956,1979
|
||||
AddaJo00,Addai,Joseph,1983,2006,rb
|
||||
AdkiJa00,Adkisson,James,te,1980,2005
|
||||
AdkiMa00,Adkins,Margene,wr,1947,1970
|
||||
AdkiSa00,Adkins,Sam,qb,1955,1977
|
||||
|
@@ -1,5 +0,0 @@
|
||||
AbduKa00,Abdul-Jabbar,Karim,rb,1974,1996
|
||||
AbduRa00,Abdullah,Rabih,rb,1975,1999
|
||||
AberWa00,Abercrombie,Walter,rb,1959,1982
|
||||
AbraDa00,Abramowicz,Danny,wr,1945,1967
|
||||
AdamBo00,Adams,Bob,te,1946,1969
|
||||
|
@@ -0,0 +1,20 @@
|
||||
AbduKa00,Abdul-Jabbar,Karim,rb,1974,1996
|
||||
AbduRa00,Abdullah,Rabih,rb,1975,1999
|
||||
AberWa00,Abercrombie,Walter,rb,1959,1982
|
||||
AbraDa00,Abramowicz,Danny,wr,1945,1967
|
||||
AdamBo00,Adams,Bob,te,1946,1969
|
||||
AdamCh00,Adams,Charlie,wr,1979,2003
|
||||
AdamCu00,Adams,Curtis,rb,1962,1985
|
||||
AdamGe00,Adams,George,rb,1962,1985
|
||||
AdamGr00,Adams,Grant,wr,2000,2005
|
||||
AdamJo00,Adams,John,rb,1937,1959
|
||||
AdamMi00,Adams,Michael,wr,1974,1997
|
||||
AdamMi01,Adamle,Mike,rb,1949,1971
|
||||
AdamTo00,Adams,Tony,qb,1950,1975
|
||||
AdamTo01,Adams,Tom,wr,1940,1962
|
||||
AdamTo02,Adamle,Tony,rb,1924,1950
|
||||
AdamWi00,Adams,Willie,wr,1956,1979
|
||||
AddaJo00,Addai,Joseph,rb,1983,2006
|
||||
AdkiJa00,Adkisson,James,te,1980,2005
|
||||
AdkiMa00,Adkins,Margene,wr,1947,1970
|
||||
AdkiSa00,Adkins,Sam,qb,1955,1977
|
||||
|
@@ -0,0 +1,20 @@
|
||||
AffhEr00,Affholter,Erik,wr,1966,1991
|
||||
AgeeTo00,Agee,Tommie,rb,1964,1988
|
||||
AikeSa00,Aiken,Sam,wr,1980,2003
|
||||
AikmTr00,Aikman,Troy,qb,1966,1989
|
||||
AkinFr00,Akins,Frank,rb,1919,1943
|
||||
AlbeFr00,Albert,Frankie,qb,1920,1950
|
||||
AldrBe00,Aldridge,Bennie,rb,1926,1950
|
||||
AlexCh00,Alexander,Charles,rb,1957,1979
|
||||
AlexDe00,Alexander,Derrick,wr,1971,1994
|
||||
AlexGl00,Alexander,Glenn,wr,1947,1970
|
||||
AlexJe00,Alexander,Jeff,rb,1965,1989
|
||||
AlexKe00,Alexander,Kevin,wr,1975,1996
|
||||
AlexMi00,Alexander,Mike,wr,1965,1989
|
||||
AlexRa00,Alexander,Ray,wr,1962,1984
|
||||
AlexRi00,Alexis,Rich,rb,1981,2005
|
||||
AlexSh00,Alexander,Shaun,rb,1977,2000
|
||||
AlexSt00,Alexander,Stephen,te,1975,1998
|
||||
AlfoBr00,Alford,Brian,wr,1975,1998
|
||||
AlfoBr01,Alford,Bruce,wr,1922,1950
|
||||
AlleAn00,Allen,Anthony,wr,1959,1985
|
||||
|
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:batch="http://www.springframework.org/schema/batch"
|
||||
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/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.5.xsd">
|
||||
|
||||
<import resource="data-source-context.xml" />
|
||||
<import resource="classpath:/org/springframework/batch/sample/config/common-context.xml" />
|
||||
|
||||
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
|
||||
<property name="jobRepository" ref="jobRepository" />
|
||||
</bean>
|
||||
|
||||
<!-- use p:databaseType="${environment}" below if auto-detection does not work -->
|
||||
<bean id="jobRepository"
|
||||
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
|
||||
p:dataSource-ref="dataSource" p:transactionManager-ref="transactionManager" />
|
||||
|
||||
<bean id="mapJobRepository"
|
||||
class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"
|
||||
lazy-init="true" autowire-candidate="false" />
|
||||
|
||||
<bean id="jobOperator" class="org.springframework.batch.core.launch.support.SimpleJobOperator"
|
||||
p:jobLauncher-ref="jobLauncher" p:jobExplorer-ref="jobExplorer" p:jobRepository-ref="jobRepository"
|
||||
p:jobRegistry-ref="jobRegistry" />
|
||||
|
||||
<bean id="jobExplorer" class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean"
|
||||
p:databaseType="${environment}" p:dataSource-ref="dataSource" />
|
||||
|
||||
<bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.ClassPathXmlJobRegistry" >
|
||||
<constructor-arg value="jobs/incrementerJob.xml" />
|
||||
</bean>
|
||||
|
||||
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
</bean>
|
||||
|
||||
<bean id="logAdvice" class="org.springframework.batch.sample.common.LogAdvice" />
|
||||
</beans>
|
||||
@@ -143,7 +143,7 @@
|
||||
<property name="properties">
|
||||
<value>
|
||||
games.file.name=games-small.csv
|
||||
player.file.name=player-small.csv
|
||||
player.file.name=player-small1.csv
|
||||
job.commit.interval=2
|
||||
</value>
|
||||
</property>
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:batch="http://www.springframework.org/schema/batch"
|
||||
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/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.5.xsd">
|
||||
|
||||
<bean id="incrementerJob" parent="simpleJob">
|
||||
<property name="steps">
|
||||
<bean id="step1" parent="skipLimitStep">
|
||||
<property name="transactionManager" ref="transactionManager" />
|
||||
<property name="jobRepository" ref="jobRepository" />
|
||||
<property name="commitInterval" value="1" />
|
||||
<property name="startLimit" value="100" />
|
||||
<property name="skipLimit" value="3" />
|
||||
<property name="itemReader">
|
||||
<bean id="playerFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
|
||||
<property name="resource" ref="playerInputResource"/>
|
||||
<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="names" value="ID,lastName,firstName,position,birthYear,debutYear" />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="fieldSetMapper">
|
||||
<bean class="org.springframework.batch.sample.domain.football.internal.PlayerFieldSetMapper" />
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
<property name="itemWriter">
|
||||
<bean class="org.springframework.batch.sample.domain.football.internal.PlayerItemWriter">
|
||||
<property name="playerDao">
|
||||
<bean class="org.springframework.batch.sample.domain.football.internal.JdbcPlayerDao">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
<property name="listeners">
|
||||
<list>
|
||||
<ref bean="playerInputResource"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
|
||||
<property name="jobParametersIncrementer">
|
||||
<bean class="org.springframework.batch.sample.common.InfiniteLoopIncrementer"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="playerInputResource" class="org.springframework.batch.core.resource.StepExecutionResourceProxy">
|
||||
<property name="filePattern" value="classpath:data/footballJob/input/player-small%run.id(long)%.csv"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -1,49 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:batch="http://www.springframework.org/schema/batch"
|
||||
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/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.5.xsd">
|
||||
|
||||
<import resource="nonSequentialJob-base.xml" />
|
||||
|
||||
<bean id="skipCheckingDecider" class="org.springframework.batch.sample.domain.football.internal.SkipCheckingDecider"/>
|
||||
|
||||
<batch:job id="nonSequentialDecisionJob">
|
||||
<batch:step name="playerload">
|
||||
<batch:next on="*" to="skipCheckingDecision" />
|
||||
</batch:step>
|
||||
<batch:decision id="skipCheckingDecision" decider="skipCheckingDecider">
|
||||
<batch:end on="FAILED" status="FAILED"/>
|
||||
<batch:next on="COMPLETED WITH SKIPS" to="errorPrint" />
|
||||
<batch:next on="*" to="gameLoad" />
|
||||
</batch:decision>
|
||||
<batch:step name="errorPrint">
|
||||
<batch:next on="*" to="gameLoad" />
|
||||
</batch:step>
|
||||
<batch:step name="gameLoad">
|
||||
<batch:next on="*" to="playerSummarization" />
|
||||
</batch:step>
|
||||
<batch:step name="playerSummarization"/>
|
||||
</batch:job>
|
||||
|
||||
<bean id="footballProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
<property name="properties">
|
||||
<value>
|
||||
games.file.name=games-small.csv
|
||||
<!-- player.file.name=player-small.csv-->
|
||||
player.file.name=player-containsBadRecords.csv
|
||||
job.commit.interval=2
|
||||
</value>
|
||||
</property>
|
||||
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
|
||||
<property name="ignoreUnresolvablePlaceholders" value="true" />
|
||||
<property name="order" value="1" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:batch="http://www.springframework.org/schema/batch"
|
||||
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/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.5.xsd">
|
||||
|
||||
<import resource="nonSequentialJob-base.xml" />
|
||||
|
||||
<bean id="skipCheckingDecider" class="org.springframework.batch.sample.domain.football.internal.SkipCheckingDecider"/>
|
||||
|
||||
<batch:job id="nonSequentialDecisionJob">
|
||||
<batch:step name="playerload">
|
||||
<batch:next on="*" to="skipCheckingDecision" />
|
||||
</batch:step>
|
||||
<batch:decision id="skipCheckingDecision" decider="skipCheckingDecider">
|
||||
<batch:end on="FAILED" status="FAILED"/>
|
||||
<batch:next on="COMPLETED WITH SKIPS" to="errorPrint" />
|
||||
<batch:next on="*" to="gameLoad" />
|
||||
</batch:decision>
|
||||
<batch:step name="errorPrint">
|
||||
<batch:next on="*" to="gameLoad" />
|
||||
</batch:step>
|
||||
<batch:step name="gameLoad">
|
||||
<batch:next on="*" to="playerSummarization" />
|
||||
</batch:step>
|
||||
<batch:step name="playerSummarization"/>
|
||||
</batch:job>
|
||||
</beans>
|
||||
|
||||
@@ -25,15 +25,16 @@
|
||||
</bean>
|
||||
</property>
|
||||
<property name="listeners">
|
||||
<list>
|
||||
<list>
|
||||
<bean class="org.springframework.batch.sample.domain.football.internal.SkipCheckingListener"/>
|
||||
<ref bean="playerInputResource"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="errorPrint" parent="taskletStep">
|
||||
<property name="tasklet">
|
||||
<bean class="org.springframework.batch.sample.domain.football.internal.ErrorLogWriter">
|
||||
<bean class="org.springframework.batch.sample.domain.football.internal.ErrorLogTasklet">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
</property>
|
||||
@@ -59,8 +60,12 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="playerInputResource" class="org.springframework.batch.core.resource.StepExecutionResourceProxy">
|
||||
<property name="filePattern" value="classpath:data/footballJob/input/%player.file.name%"/>
|
||||
</bean>
|
||||
|
||||
<bean id="playerFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
|
||||
<property name="resource" value="classpath:data/nonSequentialJob/input/${player.file.name}" />
|
||||
<property name="resource" ref="playerInputResource"/>
|
||||
<property name="lineMapper">
|
||||
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
|
||||
<property name="lineTokenizer">
|
||||
@@ -76,7 +81,7 @@
|
||||
</bean>
|
||||
|
||||
<bean id="gameFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
|
||||
<property name="resource" value="classpath:data/nonSequentialJob/input/${games.file.name}" />
|
||||
<property name="resource" value="classpath:data/footballJob/input/${games.file.name}" />
|
||||
<property name="lineMapper">
|
||||
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
|
||||
<property name="lineTokenizer">
|
||||
@@ -112,8 +117,6 @@
|
||||
<property name="properties">
|
||||
<value>
|
||||
games.file.name=games-small.csv
|
||||
<!-- player.file.name=player-small.csv-->
|
||||
player.file.name=player-containsBadRecords.csv
|
||||
job.commit.interval=2
|
||||
</value>
|
||||
</property>
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
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/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.5.xsd">
|
||||
xsi:schemaLocation="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.5.xsd">
|
||||
|
||||
<import resource="nonSequentialJob-base.xml" />
|
||||
|
||||
@@ -25,18 +27,4 @@
|
||||
<batch:step name="playerSummarization"/>
|
||||
</batch:job>
|
||||
|
||||
<bean id="footballProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
<property name="properties">
|
||||
<value>
|
||||
games.file.name=games-small.csv
|
||||
<!-- player.file.name=player-small.csv-->
|
||||
player.file.name=player-containsBadRecords.csv
|
||||
job.commit.interval=2
|
||||
</value>
|
||||
</property>
|
||||
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
|
||||
<property name="ignoreUnresolvablePlaceholders" value="true" />
|
||||
<property name="order" value="1" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
package org.springframework.batch.sample;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.core.launch.JobOperator;
|
||||
import org.springframework.batch.core.launch.JobParametersNotFoundException;
|
||||
import org.springframework.batch.core.launch.NoSuchJobException;
|
||||
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
||||
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
|
||||
import org.springframework.batch.core.repository.JobRestartException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.jdbc.SimpleJdbcTestUtils;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = { "/incrementer-job-launcher-context.xml" })
|
||||
public class IncrementerJobFunctionalTests {
|
||||
|
||||
private SimpleJdbcTemplate simpleJdbcTemplate;
|
||||
|
||||
@Autowired
|
||||
private JobOperator jobOperator;
|
||||
|
||||
/**
|
||||
* This test calls the same job twice. However, using a job incrementer, the
|
||||
* second launching is a separate job instance.<br>
|
||||
* <br>
|
||||
* Conditions:
|
||||
* <ul>
|
||||
* <li>Two flat files, each containing 20 player records
|
||||
* <li>Job is started twice, using the job incrementer to chose the input
|
||||
* file.
|
||||
* </ul>
|
||||
* Expected Results:
|
||||
* <ul>
|
||||
* <li>First run completes with 20 players in the database
|
||||
* <li>Second run completes with 40 players in the database.
|
||||
* </ul>
|
||||
*/
|
||||
@Test
|
||||
public void testWithSkips() throws Exception {
|
||||
simpleJdbcTemplate.update("DELETE from PLAYERS");
|
||||
|
||||
long id1 = this.launchJob();
|
||||
Map<String, Object> execution1 = this.getJobExecution(id1);
|
||||
assertEquals("COMPLETED", execution1.get("STATUS"));
|
||||
assertEquals(20, this.countPlayers());
|
||||
|
||||
long id2 = this.launchJob();
|
||||
Map<String, Object> execution2 = this.getJobExecution(id2);
|
||||
assertEquals("COMPLETED", execution2.get("STATUS"));
|
||||
assertEquals(40, this.countPlayers());
|
||||
|
||||
assertTrue(id1 != id2);
|
||||
assertTrue(!execution1.get("JOB_INSTANCE_ID").equals(execution2.get("JOB_INSTANCE_ID")));
|
||||
}
|
||||
|
||||
private Map<String, Object> getJobExecution(long jobExecutionId) {
|
||||
return simpleJdbcTemplate.queryForMap("SELECT * from BATCH_JOB_EXECUTION where JOB_EXECUTION_ID = ?",
|
||||
jobExecutionId);
|
||||
}
|
||||
|
||||
private int countPlayers() {
|
||||
return SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "PLAYERS");
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the entire job, including all steps, in order.
|
||||
*
|
||||
* @return JobExecution, so that the test may validate the exit status
|
||||
*/
|
||||
public long launchJob() {
|
||||
try {
|
||||
return this.jobOperator.startNextInstance("incrementerJob");
|
||||
}
|
||||
catch (NoSuchJobException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (JobExecutionAlreadyRunningException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (JobParametersNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (JobRestartException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (JobInstanceAlreadyCompleteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
|
||||
}
|
||||
}
|
||||
@@ -1,40 +1,10 @@
|
||||
package org.springframework.batch.sample;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.test.AbstractJobTests;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.jdbc.SimpleJdbcTestUtils;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = { "/simple-job-launcher-context.xml", "/jobs/nonSequentialDecisionJob.xml" })
|
||||
public class NonSequentialDecisionJobFunctionalTests extends AbstractJobTests {
|
||||
|
||||
private SimpleJdbcTemplate simpleJdbcTemplate;
|
||||
|
||||
@Test
|
||||
public void testWithSkips() throws Exception {
|
||||
simpleJdbcTemplate.update("DELETE from ERROR_LOG");
|
||||
simpleJdbcTemplate.update("DELETE from PLAYER_SUMMARY");
|
||||
simpleJdbcTemplate.update("DELETE from PLAYERS");
|
||||
simpleJdbcTemplate.update("DELETE from GAMES");
|
||||
|
||||
assertEquals(BatchStatus.COMPLETED, this.launchJob().getStatus());
|
||||
|
||||
assertEquals(1, SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "ERROR_LOG"));
|
||||
assertEquals(9, SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "PLAYER_SUMMARY"));
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
|
||||
}
|
||||
public class NonSequentialDecisionJobFunctionalTests extends NonSequentialJobFunctionalTestsBase {
|
||||
}
|
||||
|
||||
@@ -1,41 +1,10 @@
|
||||
package org.springframework.batch.sample;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.test.AbstractJobTests;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.jdbc.SimpleJdbcTestUtils;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = { "/simple-job-launcher-context.xml", "/jobs/nonSequentialJob.xml" })
|
||||
public class NonSequentialJobFunctionalTests extends AbstractJobTests {
|
||||
|
||||
private SimpleJdbcTemplate simpleJdbcTemplate;
|
||||
|
||||
@Test
|
||||
public void testWithSkips() throws Exception {
|
||||
|
||||
simpleJdbcTemplate.update("DELETE from ERROR_LOG");
|
||||
simpleJdbcTemplate.update("DELETE from PLAYER_SUMMARY");
|
||||
simpleJdbcTemplate.update("DELETE from PLAYERS");
|
||||
simpleJdbcTemplate.update("DELETE from GAMES");
|
||||
|
||||
assertEquals(BatchStatus.COMPLETED, this.launchJob().getStatus());
|
||||
|
||||
assertEquals(1, SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "ERROR_LOG"));
|
||||
assertEquals(9, SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "PLAYER_SUMMARY"));
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
|
||||
}
|
||||
public class NonSequentialJobFunctionalTests extends NonSequentialJobFunctionalTestsBase {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package org.springframework.batch.sample;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.JobParameter;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.test.AbstractJobTests;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
import org.springframework.test.jdbc.SimpleJdbcTestUtils;
|
||||
|
||||
public abstract class NonSequentialJobFunctionalTestsBase extends AbstractJobTests {
|
||||
|
||||
private SimpleJdbcTemplate simpleJdbcTemplate;
|
||||
|
||||
/**
|
||||
* This test processes a file that contains bad records. Those records will
|
||||
* skip. The step execution listener will detect that skips have occurred,
|
||||
* and return an exit status that directs the flow job to the error logging
|
||||
* step. The error logging step will log an error. <br>
|
||||
* <br>
|
||||
* Conditions:
|
||||
* <ul>
|
||||
* <li>Flat file containing 20 player records, 5 are invalid
|
||||
* <li>Skipping is allowed
|
||||
* </ul>
|
||||
* Expected Results:
|
||||
* <ul>
|
||||
* <li>15 player records written to the database
|
||||
* <li>1 error logged to the database
|
||||
* </ul>
|
||||
*/
|
||||
@Test
|
||||
public void testWithSkips() throws Exception {
|
||||
launchTest("player-containsBadRecords.csv");
|
||||
assertEquals(1, SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "ERROR_LOG"));
|
||||
assertEquals(15, SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "PLAYERS"));
|
||||
}
|
||||
|
||||
/**
|
||||
* This test processes a file that contains all valid record. The step
|
||||
* execution listener will detect that NO skips have occurred, and return an
|
||||
* exit status that direct the flow job to bypass the error logging step.<br>
|
||||
* <br>
|
||||
* Conditions:
|
||||
* <ul>
|
||||
* <li>Flat file containing 20 player records, all are valid
|
||||
* <li>Skipping is allowed
|
||||
* </ul>
|
||||
* Expected Results:
|
||||
* <ul>
|
||||
* <li>20 player records written to the database
|
||||
* <li>NO errors logged to the database
|
||||
* </ul>
|
||||
*/
|
||||
@Test
|
||||
public void testWithoutSkips() throws Exception {
|
||||
launchTest("player-small1.csv");
|
||||
assertEquals(0, SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "ERROR_LOG"));
|
||||
assertEquals(20, SimpleJdbcTestUtils.countRowsInTable(simpleJdbcTemplate, "PLAYERS"));
|
||||
}
|
||||
|
||||
private void launchTest(String playerInputfile) throws Exception {
|
||||
simpleJdbcTemplate.update("DELETE from ERROR_LOG");
|
||||
simpleJdbcTemplate.update("DELETE from PLAYER_SUMMARY");
|
||||
simpleJdbcTemplate.update("DELETE from PLAYERS");
|
||||
simpleJdbcTemplate.update("DELETE from GAMES");
|
||||
|
||||
Map<String, JobParameter> parameters = new HashMap<String, JobParameter>();
|
||||
parameters.put("timestamp", new JobParameter(new Date().getTime()));
|
||||
parameters.put("player.file.name", new JobParameter(playerInputfile));
|
||||
JobParameters jobParameters = new JobParameters(parameters);
|
||||
|
||||
assertEquals(BatchStatus.COMPLETED, this.launchJob(jobParameters).getStatus());
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user