OPEN - issue BATCH-903: Create test project
http://jira.springframework.org/browse/BATCH-903 Added a new test project, with some basic implementation to help enable end to end testing of jobs and steps.
This commit is contained in:
10
spring-batch-test/.classpath
Executable file
10
spring-batch-test/.classpath
Executable file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry including="**/*.java" kind="src" output="target/test-classes" path="src/test/java"/>
|
||||
<classpathentry kind="src" path="src/test/resources"/>
|
||||
<classpathentry kind="src" path="src/main/resources"/>
|
||||
<classpathentry including="**/*.java" kind="src" path="src/main/java"/>
|
||||
<classpathentry kind="con" path="org.devzuz.q.maven.jdt.core.mavenClasspathContainer"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
29
spring-batch-test/.project
Executable file
29
spring-batch-test/.project
Executable file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>spring-batch-test</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.devzuz.q.maven.jdt.core.mavenIncrementalBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.springframework.ide.eclipse.core.springbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.springframework.ide.eclipse.core.springnature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.devzuz.q.maven.jdt.core.mavenNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
30
spring-batch-test/.springBeans
Normal file
30
spring-batch-test/.springBeans
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beansProjectDescription>
|
||||
<version>1</version>
|
||||
<pluginVersion><![CDATA[2.2.0.v200809261800]]></pluginVersion>
|
||||
<configSuffixes>
|
||||
<configSuffix><![CDATA[xml]]></configSuffix>
|
||||
</configSuffixes>
|
||||
<enableImports><![CDATA[false]]></enableImports>
|
||||
<configs>
|
||||
<config>src/test/resources/data-source-context-init.xml</config>
|
||||
<config>src/test/resources/data-source-context.xml</config>
|
||||
<config>src/test/resources/simple-job-launcher-context.xml</config>
|
||||
<config>src/test/resources/jobs/sampleJob.xml</config>
|
||||
<config>src/test/resources/org/springframework/batch/sample/config/common-context.xml</config>
|
||||
</configs>
|
||||
<configSets>
|
||||
<configSet>
|
||||
<name><![CDATA[SampleJob]]></name>
|
||||
<allowBeanDefinitionOverriding>true</allowBeanDefinitionOverriding>
|
||||
<incomplete>false</incomplete>
|
||||
<configs>
|
||||
<config>src/test/resources/data-source-context.xml</config>
|
||||
<config>src/test/resources/data-source-context-init.xml</config>
|
||||
<config>src/test/resources/jobs/sampleJob.xml</config>
|
||||
<config>src/test/resources/org/springframework/batch/sample/config/common-context.xml</config>
|
||||
<config>src/test/resources/simple-job-launcher-context.xml</config>
|
||||
</configs>
|
||||
</configSet>
|
||||
</configSets>
|
||||
</beansProjectDescription>
|
||||
86
spring-batch-test/pom.xml
Executable file
86
spring-batch-test/pom.xml
Executable file
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project>
|
||||
<parent>
|
||||
<artifactId>spring-batch</artifactId>
|
||||
<groupId>org.springframework.batch</groupId>
|
||||
<version>2.0.0.CI-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-batch-test</artifactId>
|
||||
<name>Core</name>
|
||||
<version>2.0.0.CI-SNAPSHOT</version>
|
||||
<description>Domain for batch job testing</description>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.springsource.bundlor</groupId>
|
||||
<artifactId>com.springsource.bundlor.maven
|
||||
</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>clover</id>
|
||||
<activation />
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-clover-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-clover-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
</profile>
|
||||
</profiles>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.batch</groupId>
|
||||
<artifactId>org.springframework.batch.core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-dbcp</groupId>
|
||||
<artifactId>commons-dbcp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>emma-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
</project>
|
||||
@@ -0,0 +1,154 @@
|
||||
package org.springframework.batch.test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameter;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.job.SimpleJob;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
||||
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.JobRestartException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* Base class for testing batch jobs using the SimpleJob implementation.
|
||||
* It provides methods for launching a Job, or individual Steps within a Job on their own,
|
||||
* allowing for end to end testing of individual steps, without having to run every step
|
||||
* in the job. Any test classes inheriting from this class should make sure they are part
|
||||
* of an ApplicationContext, which is generally expected to be done as part of the Spring
|
||||
* test framework. Furthermore, the ApplicationContext in which it is a part of is expected
|
||||
* to have one {@link JobLauncher}, {@link JobRepository}, and a single Job implementation.
|
||||
* It should be noted that using any of the methods that don't conain {@link JobParameters}
|
||||
* in their signature, will result in one being created with the current system time as a
|
||||
* parameter.
|
||||
*
|
||||
* @author Lucas Ward
|
||||
* @author Dan Garrette
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract class AbstractSimpleJobTests {
|
||||
|
||||
/** Logger */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private JobLauncher launcher;
|
||||
private JobRepository jobRepository;
|
||||
private SimpleJob job;
|
||||
private StepRunner stepRunner;
|
||||
|
||||
private Map<String, Step> stepMap = new HashMap<String, Step>();
|
||||
private List<Step> stepList = new ArrayList<Step>();
|
||||
|
||||
@Autowired
|
||||
public void setLauncher(JobLauncher bootstrap) {
|
||||
this.launcher = bootstrap;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setJobRepository(JobRepository jobRepository) {
|
||||
this.jobRepository = jobRepository;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setJob(SimpleJob job) {
|
||||
this.job = job;
|
||||
|
||||
for (Step step : job.getSteps()) {
|
||||
stepMap.put(step.getName(), step);
|
||||
stepList.add(step);
|
||||
}
|
||||
}
|
||||
|
||||
public StepRunner getStepRunner() {
|
||||
if(stepRunner == null){
|
||||
stepRunner = new StepRunner(launcher, jobRepository);
|
||||
}
|
||||
return stepRunner;
|
||||
}
|
||||
|
||||
public SimpleJob getJob() {
|
||||
return job;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public getter for the launcher.
|
||||
*
|
||||
* @return the launcher
|
||||
*/
|
||||
protected JobLauncher getLauncher() {
|
||||
return launcher;
|
||||
}
|
||||
|
||||
public Step getStep(String stepName){
|
||||
|
||||
if(!stepMap.containsKey(stepName)){
|
||||
throw new IllegalStateException("No Step found with name: [" + stepName + "]");
|
||||
}
|
||||
return stepMap.get(stepName);
|
||||
}
|
||||
/**
|
||||
* Launch the entire job, including all steps, in order.
|
||||
*
|
||||
* @return JobExecution, so that the test may validate the exit status
|
||||
*/
|
||||
public JobExecution launchJob() {
|
||||
return this.launchJob(this.makeUniqueJobParameters());
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the entire job, including all steps, in order.
|
||||
*
|
||||
* @param jobParameters
|
||||
* @return JobExecution, so that the test may validate the exit status
|
||||
*/
|
||||
public JobExecution launchJob(JobParameters jobParameters) {
|
||||
try {
|
||||
return getLauncher().run(job, jobParameters);
|
||||
} catch (JobExecutionAlreadyRunningException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (JobRestartException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (JobInstanceAlreadyCompleteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch just the specified step in the job.
|
||||
*
|
||||
* @param stepName
|
||||
*/
|
||||
public JobExecution launchStep(String stepName) {
|
||||
return getStepRunner().launchStep(getStep(stepName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch just the specified step in the job.
|
||||
*
|
||||
* @param stepName
|
||||
* @param jobParameters
|
||||
*/
|
||||
public JobExecution launchStep(String stepName, JobParameters jobParameters) {
|
||||
return getStepRunner().launchStep(getStep(stepName), jobParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a new JobParameters object containing only a parameter for the
|
||||
* current timestamp, to ensure that the job instance will be unique
|
||||
*/
|
||||
private JobParameters makeUniqueJobParameters() {
|
||||
Map<String, JobParameter> parameters = new HashMap<String, JobParameter>();
|
||||
parameters.put("timestamp", new JobParameter(new Date().getTime()));
|
||||
return new JobParameters(parameters);
|
||||
}
|
||||
}
|
||||
117
spring-batch-test/src/main/java/org/springframework/batch/test/StepRunner.java
Executable file
117
spring-batch-test/src/main/java/org/springframework/batch/test/StepRunner.java
Executable file
@@ -0,0 +1,117 @@
|
||||
package org.springframework.batch.test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameter;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.job.SimpleJob;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
||||
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.JobRestartException;
|
||||
|
||||
/**
|
||||
* Utility class for executing steps outside of a {@link Job}. This is useful
|
||||
* in end to end testing in order to allow for the testing of a step individually
|
||||
* without running every Step in a job.
|
||||
*
|
||||
* <ul>
|
||||
* <li><b>launchStep(Step step)</b>: Launch the step with new parameters each time. (The current system
|
||||
* time will be used)
|
||||
* <li><b>launchStep(Step step, JobParameters jobParameters)</b>: Launch the specified step with the provided
|
||||
* JobParameters. This may be useful if your step requires a certain parameter during runtime.
|
||||
* </ul>
|
||||
*
|
||||
* It should be noted that any checked exceptions encountered while running the Step will wrapped with
|
||||
* RuntimeException. Any checked exception thrown will be due to a framework error, not the logic of the
|
||||
* step, and thus requiring a throws declaration in clients of this class is unnecessary.
|
||||
*
|
||||
* @author Dan Garrette
|
||||
* @author Lucas Ward
|
||||
* @since 2.0
|
||||
* @see SimpleJob
|
||||
*/
|
||||
public class StepRunner{
|
||||
|
||||
/** Logger */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private JobLauncher launcher;
|
||||
private JobRepository jobRepository;
|
||||
|
||||
public StepRunner(JobLauncher launcher, JobRepository jobRepository) {
|
||||
this.launcher = launcher;
|
||||
this.jobRepository = jobRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launcher
|
||||
*
|
||||
* @param stepName
|
||||
*/
|
||||
public JobExecution launchStep(Step step) {
|
||||
return this.launchStep(step, this.makeUniqueJobParameters());
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch just the specified step in the job.
|
||||
*
|
||||
* @param stepName
|
||||
* @param jobParameters
|
||||
*/
|
||||
public JobExecution launchStep(Step step, JobParameters jobParameters) {
|
||||
//
|
||||
// Create a fake job
|
||||
//
|
||||
SimpleJob job = new SimpleJob();
|
||||
job.setName("TestJob");
|
||||
job.setJobRepository(this.jobRepository);
|
||||
|
||||
List<Step> stepsToExecute = new ArrayList<Step>();
|
||||
stepsToExecute.add(step);
|
||||
job.setSteps(stepsToExecute);
|
||||
|
||||
//
|
||||
// Launch the job
|
||||
//
|
||||
return this.launchJob(job, jobParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the given job
|
||||
*
|
||||
* @param job
|
||||
* @param jobParameters
|
||||
*/
|
||||
private JobExecution launchJob(Job job, JobParameters jobParameters) {
|
||||
try {
|
||||
return this.launcher.run(job, jobParameters);
|
||||
} catch (JobExecutionAlreadyRunningException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (JobRestartException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (JobInstanceAlreadyCompleteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a new JobParameters object containing only a parameter for the
|
||||
* current timestamp, to ensure that the job instance will be unique
|
||||
*/
|
||||
private JobParameters makeUniqueJobParameters() {
|
||||
Map<String, JobParameter> parameters = new HashMap<String, JobParameter>();
|
||||
parameters.put("timestamp", new JobParameter(new Date().getTime()));
|
||||
return new JobParameters(parameters);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package org.springframework.batch.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
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;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = { "/simple-job-launcher-context.xml", "/jobs/sampleJob.xml" })
|
||||
public class SampleJobTests extends AbstractSimpleJobTests {
|
||||
|
||||
private SimpleJdbcTemplate jdbcTemplate;
|
||||
|
||||
@Autowired
|
||||
public void setJdbcTemplate(SimpleJdbcTemplate jdbcTemplate) {
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.jdbcTemplate.update("create table TESTS (ID integer, NAME varchar(40))");
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
this.jdbcTemplate.update("drop table TESTS");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
assertEquals(BatchStatus.COMPLETED, this.launchStep("step1").getStatus());
|
||||
this.verifyTasklet(1);
|
||||
}
|
||||
|
||||
private void verifyTasklet(int id) {
|
||||
assertEquals(id, jdbcTemplate.queryForInt("SELECT ID from TESTS where NAME = 'SampleTasklet" + id + "'"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJob() {
|
||||
assertEquals(BatchStatus.COMPLETED,this.launchJob().getStatus());
|
||||
this.verifyTasklet(1);
|
||||
this.verifyTasklet(2);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void voidTestNonExistentStep(){
|
||||
launchStep("nonExistent");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
assertEquals(BatchStatus.COMPLETED, this.launchStep("step2").getStatus());
|
||||
this.verifyTasklet(2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package org.springframework.batch.test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = { "/simple-job-launcher-context.xml", "/jobs/sampleJob.xml" })
|
||||
public class SampleStepTests implements ApplicationContextAware{
|
||||
|
||||
@Autowired
|
||||
private SimpleJdbcTemplate jdbcTemplate;
|
||||
|
||||
private StepRunner stepRunner;
|
||||
private ApplicationContext context;
|
||||
|
||||
@Autowired
|
||||
private JobLauncher jobLauncher;
|
||||
|
||||
@Autowired
|
||||
private JobRepository jobRepository;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
jdbcTemplate.update("create table TESTS (ID integer, NAME varchar(40))");
|
||||
stepRunner = new StepRunner(jobLauncher, jobRepository);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
this.jdbcTemplate.update("drop table TESTS");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTasklet() {
|
||||
Step step = (Step)context.getBean("step2");
|
||||
assertEquals(BatchStatus.COMPLETED, stepRunner.launchStep(step).getStatus());
|
||||
assertEquals(2, jdbcTemplate.queryForInt("SELECT ID from TESTS where NAME = 'SampleTasklet2'"));
|
||||
}
|
||||
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.context = applicationContext;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.test.common;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
|
||||
|
||||
/**
|
||||
* Wraps calls for 'Processing' methods which output a single Object to write
|
||||
* the string representation of the object to the log.
|
||||
*
|
||||
* @author Lucas Ward
|
||||
*/
|
||||
public class LogAdvice {
|
||||
|
||||
private static Log log = LogFactory.getLog(LogAdvice.class);
|
||||
|
||||
/*
|
||||
* Wraps original method and adds logging both before and after method
|
||||
*/
|
||||
public void doBasicLogging(JoinPoint pjp) throws Throwable {
|
||||
Object[] args = pjp.getArgs();
|
||||
StringBuffer output = new StringBuffer();
|
||||
|
||||
output.append(pjp.getTarget().getClass().getName()).append(": ");
|
||||
output.append(pjp.toShortString()).append(": ");
|
||||
|
||||
for (Object arg : args) {
|
||||
output.append(arg).append(" ");
|
||||
}
|
||||
|
||||
|
||||
log.info("Basic: " + output.toString());
|
||||
}
|
||||
|
||||
public void doStronglyTypedLogging(Object item){
|
||||
log.info("Processed: " + item);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.test.jmx;
|
||||
|
||||
import javax.management.Notification;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.jmx.export.notification.NotificationPublisher;
|
||||
import org.springframework.jmx.export.notification.NotificationPublisherAware;
|
||||
|
||||
/**
|
||||
* JMX notification broadcaster
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @since 1.0
|
||||
*/
|
||||
public class JobExecutionNotificationPublisher implements ApplicationListener, NotificationPublisherAware {
|
||||
|
||||
protected static final Log logger = LogFactory.getLog(JobExecutionNotificationPublisher.class);
|
||||
|
||||
private NotificationPublisher notificationPublisher;
|
||||
|
||||
private int notificationCount = 0;
|
||||
|
||||
/**
|
||||
* Injection setter.
|
||||
*
|
||||
* @see org.springframework.jmx.export.notification.NotificationPublisherAware#setNotificationPublisher(org.springframework.jmx.export.notification.NotificationPublisher)
|
||||
*/
|
||||
public void setNotificationPublisher(NotificationPublisher notificationPublisher) {
|
||||
this.notificationPublisher = notificationPublisher;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the event is a {@link SimpleMessageApplicationEvent} for open and
|
||||
* close we log the event at INFO level and send a JMX notification if we
|
||||
* are also an MBean.
|
||||
*
|
||||
* @see ApplicationListener#onApplicationEvent(ApplicationEvent)
|
||||
*/
|
||||
public void onApplicationEvent(ApplicationEvent applicationEvent) {
|
||||
if (applicationEvent instanceof SimpleMessageApplicationEvent) {
|
||||
String message = applicationEvent.toString();
|
||||
logger.info(message);
|
||||
publish(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish the provided message to an external listener if there is one.
|
||||
*
|
||||
* @param message the message to publish
|
||||
*/
|
||||
private void publish(String message) {
|
||||
if (notificationPublisher != null) {
|
||||
Notification notification = new Notification("JobExecutionApplicationEvent", this, notificationCount++,
|
||||
message);
|
||||
/*
|
||||
* We can't create a notification with a null source, but we can set
|
||||
* it to null after creation(!). We want it to be null so that
|
||||
* Spring will replace it automatically with the ObjectName (in
|
||||
* ModelMBeanNotificationPublisher).
|
||||
*/
|
||||
notification.setSource(null);
|
||||
notificationPublisher.sendNotification(notification);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.springframework.batch.test.jmx;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class SimpleMessageApplicationEvent extends ApplicationEvent {
|
||||
|
||||
private String message;
|
||||
|
||||
public SimpleMessageApplicationEvent(Object source, String message) {
|
||||
super(source);
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.util.EventObject#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return "message=["+message+"], " + super.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.test.jmx;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
|
||||
/**
|
||||
* Wraps calls for methods taking {@link StepExecution} as an argument and
|
||||
* publishes notifications in the form of {@link ApplicationEvent}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class StepExecutionApplicationEventAdvice implements ApplicationEventPublisherAware {
|
||||
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher(org.springframework.context.ApplicationEventPublisher)
|
||||
*/
|
||||
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
||||
this.applicationEventPublisher = applicationEventPublisher;
|
||||
}
|
||||
|
||||
public void before(JoinPoint jp, StepExecution stepExecution) {
|
||||
String msg = "Before: " + jp.toShortString() + " with: " + stepExecution;
|
||||
publish(jp.getTarget(), msg);
|
||||
}
|
||||
|
||||
public void after(JoinPoint jp, StepExecution stepExecution) {
|
||||
String msg = "After: " + jp.toShortString() + " with: " + stepExecution;
|
||||
publish(jp.getTarget(), msg);
|
||||
}
|
||||
|
||||
public void onError(JoinPoint jp, StepExecution stepExecution, Throwable t) {
|
||||
String msg = "Error in: " + jp.toShortString() + " with: " + stepExecution + " (" + t.getClass() + ":" + t.getMessage() + ")";
|
||||
publish(jp.getTarget(), msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Publish a {@link SimpleMessageApplicationEvent} with the given
|
||||
* parameters.
|
||||
*/
|
||||
private void publish(Object source, String message) {
|
||||
applicationEventPublisher.publishEvent(new SimpleMessageApplicationEvent(source, message));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.springframework.batch.test.sample;
|
||||
|
||||
import org.springframework.batch.core.StepContribution;
|
||||
import org.springframework.batch.core.step.tasklet.Tasklet;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.AttributeAccessor;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
|
||||
public class SampleTasklet implements Tasklet {
|
||||
|
||||
@Autowired
|
||||
private SimpleJdbcTemplate jdbcTemplate;
|
||||
private int id = 0;
|
||||
|
||||
public SampleTasklet(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public ExitStatus execute(StepContribution contribution, AttributeAccessor attributes) throws Exception {
|
||||
System.err.println("SampleTasklet1.execute()");
|
||||
this.jdbcTemplate.update("insert into TESTS(ID, NAME) values (?, 'SampleTasklet" + id + "')", id);
|
||||
|
||||
return ExitStatus.FINISHED;
|
||||
}
|
||||
}
|
||||
191
spring-batch-test/src/test/java/test/jdbc/datasource/DataSourceInitializer.java
Executable file
191
spring-batch-test/src/test/java/test/jdbc/datasource/DataSourceInitializer.java
Executable file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* 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 test.jdbc.datasource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Wrapper for a {@link DataSource} that can run scripts on start up and shut
|
||||
* down. Us as a bean definition <br/><br/>
|
||||
*
|
||||
* Run this class to initialize a database in a running server process.
|
||||
* Make sure the server is running first by launching the "hsql-server" from the
|
||||
* <code>hsql.server</code> project. Then you can right click in Eclipse and
|
||||
* Run As -> Java Application. Do the same any time you want to wipe the
|
||||
* database and start again.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class DataSourceInitializer implements InitializingBean, DisposableBean {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(DataSourceInitializer.class);
|
||||
|
||||
private Resource[] initScripts;
|
||||
|
||||
private Resource[] destroyScripts;
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
private boolean ignoreFailedDrop = true;
|
||||
|
||||
private static boolean initialized = false;
|
||||
|
||||
/**
|
||||
* Main method as convenient entry point.
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String... args) {
|
||||
new ClassPathXmlApplicationContext(ClassUtils.addResourcePathToPackagePath(DataSourceInitializer.class,
|
||||
DataSourceInitializer.class.getSimpleName() + "-context.xml"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
* @see java.lang.Object#finalize()
|
||||
*/
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
initialized = false;
|
||||
logger.debug("finalize called");
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (destroyScripts==null) return;
|
||||
for (int i = 0; i < destroyScripts.length; i++) {
|
||||
Resource destroyScript = initScripts[i];
|
||||
try {
|
||||
doExecuteScript(destroyScript);
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.warn("Could not execute destroy script [" + destroyScript + "]", e);
|
||||
}
|
||||
else {
|
||||
logger.warn("Could not execute destroy script [" + destroyScript + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(dataSource);
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
if (!initialized) {
|
||||
destroy();
|
||||
if (initScripts != null) {
|
||||
for (int i = 0; i < initScripts.length; i++) {
|
||||
Resource initScript = initScripts[i];
|
||||
doExecuteScript(initScript);
|
||||
}
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void doExecuteScript(final Resource scriptResource) {
|
||||
if (scriptResource == null || !scriptResource.exists())
|
||||
return;
|
||||
TransactionTemplate transactionTemplate = new TransactionTemplate(new DataSourceTransactionManager(dataSource));
|
||||
transactionTemplate.execute(new TransactionCallback() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object doInTransaction(TransactionStatus status) {
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
String[] scripts;
|
||||
try {
|
||||
scripts = StringUtils.delimitedListToStringArray(stripComments(IOUtils.readLines(scriptResource
|
||||
.getInputStream())), ";");
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new BeanInitializationException("Cannot load script from [" + scriptResource + "]", e);
|
||||
}
|
||||
for (int i = 0; i < scripts.length; i++) {
|
||||
String script = scripts[i].trim();
|
||||
if (StringUtils.hasText(script)) {
|
||||
try {
|
||||
jdbcTemplate.execute(script);
|
||||
}
|
||||
catch (DataAccessException e) {
|
||||
if (ignoreFailedDrop && script.toLowerCase().startsWith("drop")) {
|
||||
logger.debug("DROP script failed (ignoring): " + script);
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private String stripComments(List<String> list) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (String line : list) {
|
||||
if (!line.startsWith("//") && !line.startsWith("--")) {
|
||||
buffer.append(line + "\n");
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public void setInitScripts(Resource[] initScripts) {
|
||||
this.initScripts = initScripts;
|
||||
}
|
||||
|
||||
public void setDestroyScripts(Resource[] destroyScripts) {
|
||||
this.destroyScripts = destroyScripts;
|
||||
}
|
||||
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
public void setIgnoreFailedDrop(boolean ignoreFailedDrop) {
|
||||
this.ignoreFailedDrop = ignoreFailedDrop;
|
||||
}
|
||||
|
||||
}
|
||||
21
spring-batch-test/src/test/resources/batch-hsql.properties
Executable file
21
spring-batch-test/src/test/resources/batch-hsql.properties
Executable file
@@ -0,0 +1,21 @@
|
||||
# Placeholders batch.*
|
||||
# for HSQLDB:
|
||||
batch.jdbc.driver=org.hsqldb.jdbcDriver
|
||||
batch.jdbc.url=jdbc:hsqldb:mem:testdb;sql.enforce_strict_size=true
|
||||
# use this one for a separate server process so you can inspect the results
|
||||
# (or add it to system properties with -D to override at run time).
|
||||
# batch.jdbc.url=jdbc:hsqldb:hsql://localhost:9005/samples
|
||||
batch.jdbc.user=sa
|
||||
batch.jdbc.password=
|
||||
batch.schema=
|
||||
batch.jndi.name=
|
||||
batch.naming.factory.initial=
|
||||
batch.naming.provider.url=
|
||||
batch.schema.script=schema-hsqldb.sql
|
||||
batch.business.schema.script=business-schema-hsqldb.sql
|
||||
batch.database.incrementer.class=org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer
|
||||
batch.lob.handler.class=org.springframework.jdbc.support.lob.DefaultLobHandler
|
||||
|
||||
# Bean Properties for override
|
||||
# when not using sequences:
|
||||
incrementerParent.columnName=ID
|
||||
16
spring-batch-test/src/test/resources/data-source-context-init.xml
Executable file
16
spring-batch-test/src/test/resources/data-source-context-init.xml
Executable file
@@ -0,0 +1,16 @@
|
||||
<?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">
|
||||
|
||||
<bean id="dataSourceInitializer" class="test.jdbc.datasource.DataSourceInitializer">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="initScripts">
|
||||
<list>
|
||||
<value>${batch.schema.script}</value>
|
||||
<value>${batch.business.schema.script}</value>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
64
spring-batch-test/src/test/resources/data-source-context.xml
Executable file
64
spring-batch-test/src/test/resources/data-source-context.xml
Executable file
@@ -0,0 +1,64 @@
|
||||
<?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">
|
||||
|
||||
<!-- Initialise the database before every test case: -->
|
||||
<import resource="data-source-context-init.xml" />
|
||||
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
|
||||
<property name="driverClassName" value="${batch.jdbc.driver}" />
|
||||
<property name="url" value="${batch.jdbc.url}" />
|
||||
<property name="username" value="${batch.jdbc.user}" />
|
||||
<property name="password" value="${batch.jdbc.password}" />
|
||||
</bean>
|
||||
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" lazy-init="true">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
</bean>
|
||||
<!-- Set up or detect a System property called "environment" used to construct a properties file on the classpath. The default is "hsql". -->
|
||||
<bean id="environment" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
<property name="targetClass" value="java.lang.System" />
|
||||
<property name="targetMethod" value="setProperty" />
|
||||
<property name="arguments">
|
||||
<list>
|
||||
<value>environment</value>
|
||||
<bean class="java.lang.System" factory-method="getProperty">
|
||||
<constructor-arg>
|
||||
<value>environment</value>
|
||||
</constructor-arg>
|
||||
<!-- The default value of the environment property -->
|
||||
<constructor-arg>
|
||||
<value>hsql</value>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Use this to set additional properties on beans at run time -->
|
||||
<bean id="overrideProperties" class="org.springframework.beans.factory.config.PropertyOverrideConfigurer"
|
||||
depends-on="environment">
|
||||
<property name="location" value="classpath:batch-${environment}.properties" />
|
||||
<!-- Allow system properties (-D) to override those from file -->
|
||||
<property name="localOverride" value="true" />
|
||||
<property name="properties">
|
||||
<bean class="java.lang.System" factory-method="getProperties" />
|
||||
</property>
|
||||
<property name="ignoreInvalidKeys" value="true" />
|
||||
<property name="order" value="2" />
|
||||
</bean>
|
||||
<bean id="placeholderProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
|
||||
depends-on="environment">
|
||||
<property name="location" value="classpath:batch-${environment}.properties" />
|
||||
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
|
||||
<property name="ignoreUnresolvablePlaceholders" value="true" />
|
||||
<property name="order" value="1" />
|
||||
</bean>
|
||||
<bean id="lobHandler" class="${batch.lob.handler.class}" />
|
||||
<bean id="incrementerParent" class="${batch.database.incrementer.class}">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
<property name="incrementerName" value="ID" />
|
||||
</bean>
|
||||
|
||||
<!--import resource="alt-data-source-context.xml" /-->
|
||||
</beans>
|
||||
33
spring-batch-test/src/test/resources/jobs/sampleJob.xml
Executable file
33
spring-batch-test/src/test/resources/jobs/sampleJob.xml
Executable file
@@ -0,0 +1,33 @@
|
||||
<?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 id="sampleJob" parent="simpleJob">
|
||||
<property name="steps">
|
||||
<list>
|
||||
<bean id="step1" parent="taskletStep">
|
||||
<property name="tasklet">
|
||||
<bean class="org.springframework.batch.test.sample.SampleTasklet">
|
||||
<constructor-arg value="1" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
<ref bean="step2" />
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="step2" parent="taskletStep">
|
||||
<property name="tasklet">
|
||||
<bean class="org.springframework.batch.test.sample.SampleTasklet">
|
||||
<constructor-arg value="2" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,57 @@
|
||||
<?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.5.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
|
||||
|
||||
<bean id="simpleJob" class="org.springframework.batch.core.job.SimpleJob" abstract="true">
|
||||
<property name="jobRepository" ref="jobRepository" />
|
||||
<property name="restartable" value="true" />
|
||||
</bean>
|
||||
|
||||
<bean id="taskletStep" class="org.springframework.batch.core.step.tasklet.TaskletStep" abstract="true">
|
||||
<property name="transactionManager" ref="transactionManager" />
|
||||
<property name="jobRepository" ref="jobRepository" />
|
||||
<property name="allowStartIfComplete" value="true" />
|
||||
</bean>
|
||||
|
||||
<bean id="simpleStep" class="org.springframework.batch.core.step.item.SimpleStepFactoryBean"
|
||||
abstract="true">
|
||||
<property name="transactionManager" ref="transactionManager" />
|
||||
<property name="jobRepository" ref="jobRepository" />
|
||||
<property name="startLimit" value="100" />
|
||||
<property name="commitInterval" value="1" />
|
||||
</bean>
|
||||
|
||||
<bean id="skipLimitStep" class="org.springframework.batch.core.step.item.FaultTolerantStepFactoryBean"
|
||||
parent="simpleStep" abstract="true">
|
||||
<property name="skipLimit" value="0" />
|
||||
</bean>
|
||||
|
||||
<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
|
||||
<property name="customEditors">
|
||||
<map>
|
||||
<entry key="int[]">
|
||||
<bean class="org.springframework.batch.support.IntArrayPropertyEditor" />
|
||||
</entry>
|
||||
<entry key="org.springframework.batch.item.file.transform.Range[]">
|
||||
<bean class="org.springframework.batch.item.file.transform.RangeArrayPropertyEditor" />
|
||||
</entry>
|
||||
<entry key="java.util.Date">
|
||||
<bean class="org.springframework.beans.propertyeditors.CustomDateEditor">
|
||||
<constructor-arg>
|
||||
<bean class="java.text.SimpleDateFormat">
|
||||
<constructor-arg value="yyyyMMdd" />
|
||||
</bean>
|
||||
</constructor-arg>
|
||||
<constructor-arg value="false" />
|
||||
</bean>
|
||||
</entry>
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
66
spring-batch-test/src/test/resources/simple-job-launcher-context.xml
Executable file
66
spring-batch-test/src/test/resources/simple-job-launcher-context.xml
Executable file
@@ -0,0 +1,66 @@
|
||||
<?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.5.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
|
||||
|
||||
<import resource="classpath:/data-source-context.xml" />
|
||||
|
||||
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
|
||||
<constructor-arg ref="dataSource" />
|
||||
</bean>
|
||||
|
||||
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
|
||||
<property name="jobRepository" ref="jobRepository" />
|
||||
</bean>
|
||||
|
||||
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
<property name="transactionManager" ref="transactionManager" />
|
||||
<property name="databaseType" value="hsql" />
|
||||
</bean>
|
||||
|
||||
<bean id="simpleJob" class="org.springframework.batch.core.job.SimpleJob" abstract="true">
|
||||
<property name="jobRepository" ref="jobRepository" />
|
||||
<property name="restartable" value="true" />
|
||||
</bean>
|
||||
|
||||
<bean id="taskletStep" class="org.springframework.batch.core.step.tasklet.TaskletStep" abstract="true">
|
||||
<property name="transactionManager" ref="transactionManager" />
|
||||
<property name="jobRepository" ref="jobRepository" />
|
||||
<property name="allowStartIfComplete" value="true" />
|
||||
</bean>
|
||||
|
||||
<bean id="itemOrientedStep" class="org.springframework.batch.core.step.item.FaultTolerantStepFactoryBean" abstract="true">
|
||||
<property name="transactionManager" ref="transactionManager" />
|
||||
<property name="jobRepository" ref="jobRepository" />
|
||||
</bean>
|
||||
|
||||
<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
|
||||
<property name="customEditors">
|
||||
<map>
|
||||
<entry key="int[]">
|
||||
<bean class="org.springframework.batch.support.IntArrayPropertyEditor" />
|
||||
</entry>
|
||||
<entry key="org.springframework.batch.item.file.transform.Range[]">
|
||||
<bean class="org.springframework.batch.item.file.transform.RangeArrayPropertyEditor" />
|
||||
</entry>
|
||||
<entry key="java.util.Date">
|
||||
<bean class="org.springframework.beans.propertyeditors.CustomDateEditor">
|
||||
<constructor-arg>
|
||||
<bean class="java.text.SimpleDateFormat">
|
||||
<constructor-arg value="yyyyMMdd" />
|
||||
</bean>
|
||||
</constructor-arg>
|
||||
<constructor-arg value="false" />
|
||||
</bean>
|
||||
</entry>
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
</beans>
|
||||
Reference in New Issue
Block a user