Remove the Map based job repository/explorer and their DAOs

This commit removes the deprecated Map-based job repository
and job explorer implementations with their respective DAOs.
Using the `EnableBatchProcessing` annotation now requires a
datasource bean to be defined in the application context.
This will be reviewed as part of #3942.

This commit is a first pass that updates related tests to use
the JDBC-based job repository/explorer with an embedded database.
A second pass should be done to improve tests by caching/reusing
embedded databases if possible.

Issue #3836
This commit is contained in:
Mahmoud Ben Hassine
2021-08-17 13:12:28 +02:00
parent d5509d2444
commit f8bdf5521e
115 changed files with 1428 additions and 3310 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2019 the original author or authors.
* Copyright 2006-2021 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.
@@ -39,6 +39,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.lang.Nullable;
/**
@@ -106,6 +108,7 @@ public class JobBuilderConfigurationTests {
@Configuration
@EnableBatchProcessing
@Import(DataSourceConfiguration.class)
public static class TestConfiguration {
@Autowired
@@ -147,6 +150,7 @@ public class JobBuilderConfigurationTests {
@Configuration
@EnableBatchProcessing
@Import(DataSourceConfiguration.class)
public static class AnotherConfiguration {
@Autowired
@@ -173,11 +177,16 @@ public class JobBuilderConfigurationTests {
@Configuration
@EnableBatchProcessing
@Import(DataSourceConfiguration.class)
public static class TestConfigurer extends DefaultBatchConfigurer {
@Autowired
private SimpleBatchConfiguration jobs;
public TestConfigurer(DataSource dataSource) {
super(dataSource);
}
@Bean
public Job testConfigurerJob() throws Exception {
SimpleJobBuilder builder = jobs.jobBuilders().get("configurer").start(step1());
@@ -201,6 +210,7 @@ public class JobBuilderConfigurationTests {
@Configuration
@EnableBatchProcessing
@Import(DataSourceConfiguration.class)
public static class BeansConfigurer {
@Autowired
@@ -235,4 +245,16 @@ public class JobBuilderConfigurationTests {
}
@Configuration
static class DataSourceConfiguration {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.generateUniqueName(true)
.build();
}
}
}

View File

@@ -1,163 +0,0 @@
/*
* Copyright 2014-2019 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
*
* https://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.core.configuration.annotation;
import static org.junit.Assert.assertEquals;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.PooledEmbeddedDataSource;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
public class MapJobRepositoryConfigurationTests {
JobLauncher jobLauncher;
JobRepository jobRepository;
Job job;
JobExplorer jobExplorer;
@Test
public void testRoseyScenario() throws Exception {
testConfigurationClass(MapRepositoryBatchConfiguration.class);
}
@Test
public void testOneDataSource() throws Exception {
testConfigurationClass(HsqlBatchConfiguration.class);
}
@Test(expected = UnsatisfiedDependencyException.class)
public void testMultipleDataSources_whenNoneOfThemIsPrimary() throws Exception {
testConfigurationClass(InvalidBatchConfiguration.class);
}
@Test
public void testMultipleDataSources_whenNoneOfThemIsPrimaryButOneOfThemIsNamed_dataSource_() throws Exception {
testConfigurationClass(ValidBatchConfigurationWithoutPrimaryDataSource.class);
}
@Test
public void testMultipleDataSources_whenOneOfThemIsPrimary() throws Exception {
testConfigurationClass(ValidBatchConfigurationWithPrimaryDataSource.class);
}
private void testConfigurationClass(Class<?> clazz) throws Exception {
GenericApplicationContext context = new AnnotationConfigApplicationContext(clazz);
this.jobLauncher = context.getBean(JobLauncher.class);
this.jobRepository = context.getBean(JobRepository.class);
this.job = context.getBean(Job.class);
this.jobExplorer = context.getBean(JobExplorer.class);
JobExecution jobExecution = jobLauncher.run(job, new JobParameters());
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
JobExecution repositoryJobExecution = jobRepository.getLastJobExecution(job.getName(), new JobParameters());
assertEquals(jobExecution.getId(), repositoryJobExecution.getId());
assertEquals("job", jobExplorer.getJobNames().iterator().next());
context.close();
}
public static class InvalidBatchConfiguration extends HsqlBatchConfiguration {
@Bean
DataSource dataSource2() {
return new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder().setName("badDatabase").build());
}
}
public static class ValidBatchConfigurationWithPrimaryDataSource extends HsqlBatchConfiguration {
@Primary
@Bean
DataSource dataSource2() {
return new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder().
setName("dataSource2").
addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql").
addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql").
build());
}
}
public static class ValidBatchConfigurationWithoutPrimaryDataSource extends HsqlBatchConfiguration {
@Bean
DataSource dataSource() { // will be autowired by name
return new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder().
setName("dataSource").
addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql").
addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql").
build());
}
}
public static class HsqlBatchConfiguration extends MapRepositoryBatchConfiguration {
@Bean
DataSource dataSource1() {
return new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder().
setName("dataSource1").
addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql").
addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql").
build());
}
}
@Component
@EnableBatchProcessing
public static class MapRepositoryBatchConfiguration {
@Autowired
JobBuilderFactory jobFactory;
@Autowired
StepBuilderFactory stepFactory;
@Bean
Step step1 () {
return stepFactory.get("step1").tasklet(new Tasklet() {
@Nullable
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
return RepeatStatus.FINISHED;
}
}).build();
}
@Bean
Job job() {
return jobFactory.get("job").start(step1()).build();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018 the original author or authors.
* Copyright 2018-2021 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.
@@ -21,8 +21,9 @@ import javax.sql.DataSource;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.batch.core.configuration.BatchConfigurationException;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -35,24 +36,9 @@ import org.springframework.transaction.PlatformTransactionManager;
*/
public class TransactionManagerConfigurationWithBatchConfigurerTests extends TransactionManagerConfigurationTests {
@Test
public void testConfigurationWithNoDataSourceAndNoTransactionManager() throws Exception {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BatchConfigurationWithNoDataSourceAndNoTransactionManager.class);
BatchConfigurer batchConfigurer = applicationContext.getBean(BatchConfigurer.class);
PlatformTransactionManager platformTransactionManager = batchConfigurer.getTransactionManager();
Assert.assertTrue(platformTransactionManager instanceof ResourcelessTransactionManager);
Assert.assertSame(getTransactionManagerSetOnJobRepository(applicationContext.getBean(JobRepository.class)), platformTransactionManager);
}
@Test
public void testConfigurationWithNoDataSourceAndTransactionManager() throws Exception {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BatchConfigurationWithNoDataSourceAndTransactionManager.class);
BatchConfigurer batchConfigurer = applicationContext.getBean(BatchConfigurer.class);
PlatformTransactionManager platformTransactionManager = batchConfigurer.getTransactionManager();
Assert.assertSame(transactionManager, platformTransactionManager);
Assert.assertSame(getTransactionManagerSetOnJobRepository(applicationContext.getBean(JobRepository.class)), transactionManager);
@Test(expected = UnsatisfiedDependencyException.class)
public void testConfigurationWithNoDataSourceAndNoTransactionManager() {
new AnnotationConfigApplicationContext(BatchConfigurationWithNoDataSourceAndNoTransactionManager.class);
}
@Test
@@ -79,29 +65,6 @@ public class TransactionManagerConfigurationWithBatchConfigurerTests extends Tra
@EnableBatchProcessing
public static class BatchConfigurationWithNoDataSourceAndNoTransactionManager {
@Bean
public BatchConfigurer batchConfigurer() {
return new DefaultBatchConfigurer();
}
}
@EnableBatchProcessing
public static class BatchConfigurationWithNoDataSourceAndTransactionManager {
@Bean
public PlatformTransactionManager transactionManager() {
return transactionManager;
}
@Bean
public BatchConfigurer batchConfigurer() {
return new DefaultBatchConfigurer() {
@Override
public PlatformTransactionManager getTransactionManager() {
return transactionManager();
}
};
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018 the original author or authors.
* Copyright 2018-2021 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.
@@ -23,6 +23,7 @@ import org.junit.Test;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -36,24 +37,14 @@ import org.springframework.transaction.PlatformTransactionManager;
*/
public class TransactionManagerConfigurationWithoutBatchConfigurerTests extends TransactionManagerConfigurationTests {
@Test
public void testConfigurationWithNoDataSourceAndNoTransactionManager() throws Exception {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BatchConfigurationWithNoDataSourceAndNoTransactionManager.class);
Assert.assertTrue(applicationContext.containsBean("transactionManager"));
PlatformTransactionManager platformTransactionManager = applicationContext.getBean(PlatformTransactionManager.class);
Object targetObject = AopTestUtils.getTargetObject(platformTransactionManager);
Assert.assertTrue(targetObject instanceof ResourcelessTransactionManager);
Assert.assertSame(getTransactionManagerSetOnJobRepository(applicationContext.getBean(JobRepository.class)), targetObject);
@Test(expected = UnsatisfiedDependencyException.class)
public void testConfigurationWithNoDataSourceAndNoTransactionManager() {
new AnnotationConfigApplicationContext(BatchConfigurationWithNoDataSourceAndNoTransactionManager.class);
}
@Test
public void testConfigurationWithNoDataSourceAndTransactionManager() throws Exception {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BatchConfigurationWithNoDataSourceAndTransactionManager.class);
PlatformTransactionManager platformTransactionManager = applicationContext.getBean(PlatformTransactionManager.class);
Assert.assertSame(transactionManager, platformTransactionManager);
// In this case, the supplied transaction manager won't be used by batch and a ResourcelessTransactionManager will be used instead.
// The user has to provide a custom BatchConfigurer.
Assert.assertTrue(getTransactionManagerSetOnJobRepository(applicationContext.getBean(JobRepository.class)) instanceof ResourcelessTransactionManager);
@Test(expected = UnsatisfiedDependencyException.class)
public void testConfigurationWithNoDataSourceAndTransactionManager() {
new AnnotationConfigApplicationContext(BatchConfigurationWithNoDataSourceAndTransactionManager.class);
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2007 the original author or authors.
* Copyright 2006-2021 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.
@@ -27,13 +27,13 @@ import org.springframework.batch.core.repository.JobExecutionAlreadyRunningExcep
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import static org.junit.Assert.fail;
/**
* @author Dan Garrette
* @author Mahmoud Ben Hassine
* @since 2.0
*/
public abstract class AbstractJobParserTests {
@@ -44,15 +44,11 @@ public abstract class AbstractJobParserTests {
@Autowired
private JobRepository jobRepository;
@Autowired
private MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean;
@Autowired
protected ArrayList<String> stepNamesList = new ArrayList<>();
@Before
public void setUp() {
mapJobRepositoryFactoryBean.clear();
stepNamesList.clear();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2007 the original author or authors.
* Copyright 2006-2021 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.
@@ -21,7 +21,6 @@ import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
@@ -30,7 +29,6 @@ import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
@@ -39,6 +37,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
@ContextConfiguration
@@ -64,14 +63,6 @@ public class FlowJobParserTests {
@Autowired
private JobRepository jobRepository;
@Autowired
private MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean;
@Before
public void setUp() {
mapJobRepositoryFactoryBean.clear();
}
@Test
public void testFlowJob() throws Exception {
assertNotNull(job1);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2019 the original author or authors.
* Copyright 2006-2021 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.
@@ -21,7 +21,6 @@ import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
@@ -32,7 +31,6 @@ import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
import org.springframework.batch.core.job.flow.JobExecutionDecider;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.lang.Nullable;
@@ -41,6 +39,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
@ContextConfiguration
@@ -66,14 +65,6 @@ public class FlowStepParserTests {
@Autowired
private JobRepository jobRepository;
@Autowired
private MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean;
@Before
public void setUp() {
mapJobRepositoryFactoryBean.clear();
}
@Test
public void testFlowStep() throws Exception {
assertNotNull(job1);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2007 the original author or authors.
* Copyright 2006-2021 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.
@@ -21,7 +21,6 @@ import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
@@ -30,7 +29,6 @@ import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
@@ -39,6 +37,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
@ContextConfiguration
@@ -56,14 +55,6 @@ public class JobStepParserTests {
@Autowired
private JobRepository jobRepository;
@Autowired
private MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean;
@Before
public void setUp() {
mapJobRepositoryFactoryBean.clear();
}
@Test
public void testFlowStep() throws Exception {
assertNotNull(job1);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2007 the original author or authors.
* Copyright 2006-2021 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.
@@ -18,7 +18,6 @@ package org.springframework.batch.core.configuration.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
@@ -26,7 +25,6 @@ import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
@@ -35,6 +33,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
@ContextConfiguration
@@ -48,14 +47,6 @@ public class NamespacePrefixedJobParserTests {
@Autowired
private JobRepository jobRepository;
@Autowired
private MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean;
@Before
public void setUp() {
mapJobRepositoryFactoryBean.clear();
}
@Test
public void testNoopJob() throws Exception {
assertNotNull(job1);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2018 the original author or authors.
* Copyright 2006-2021 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.
@@ -39,7 +39,6 @@ import org.springframework.batch.core.partition.support.PartitionStep;
import org.springframework.batch.core.partition.support.StepExecutionAggregator;
import org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.step.tasklet.TaskletStep;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
@@ -86,9 +85,6 @@ public class PartitionStepParserTests implements ApplicationContextAware {
@Autowired
private JobRepository jobRepository;
@Autowired
private MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean;
private ApplicationContext applicationContext;
private List<String> savedStepNames = new ArrayList<>();
@@ -101,7 +97,6 @@ public class PartitionStepParserTests implements ApplicationContextAware {
@Before
public void setUp() {
nameStoringTasklet.setStepNamesList(savedStepNames);
mapJobRepositoryFactoryBean.clear();
}
@SuppressWarnings("unchecked")

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2019 the original author or authors.
* Copyright 2006-2021 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.
@@ -33,7 +33,6 @@ import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
import org.springframework.batch.core.job.flow.JobExecutionDecider;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.lang.Nullable;
@@ -43,6 +42,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Dave Syer
* @author Josh Long
* @author Mahmoud Ben Hassine
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@@ -59,15 +59,11 @@ public class PartitionStepWithFlowParserTests {
@Autowired
private JobRepository jobRepository;
@Autowired
private MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean;
private List<String> savedStepNames = new ArrayList<>();
@Before
public void setUp() {
nameStoringTasklet.setStepNamesList(savedStepNames);
mapJobRepositoryFactoryBean.clear();
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2007 the original author or authors.
* Copyright 2006-2021 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.
@@ -31,7 +31,6 @@ import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
@@ -40,6 +39,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Dave Syer
* @author Josh Long
* @author Mahmoud Ben Hassine
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@@ -56,15 +56,11 @@ public class PartitionStepWithLateBindingParserTests {
@Autowired
private JobRepository jobRepository;
@Autowired
private MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean;
private List<String> savedStepNames = new ArrayList<>();
@Before
public void setUp() {
nameStoringTasklet.setStepNamesList(savedStepNames);
mapJobRepositoryFactoryBean.clear();
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2007 the original author or authors.
* Copyright 2006-2021 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.
@@ -18,7 +18,6 @@ package org.springframework.batch.core.configuration.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
@@ -26,7 +25,6 @@ import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -34,6 +32,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
@ContextConfiguration
@@ -46,14 +45,6 @@ public class PartitionStepWithNonDefaultTransactionManagerParserTests {
@Autowired
private JobRepository jobRepository;
@Autowired
private MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean;
@Before
public void setUp() {
mapJobRepositoryFactoryBean.clear();
}
@Test
public void testDefaultHandlerStep() throws Exception {
assertNotNull(job);

View File

@@ -55,6 +55,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.DeadlockLoserDataAccessException;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.retry.RetryListener;
import org.springframework.retry.listener.RetryListenerSupport;
import org.springframework.test.util.ReflectionTestUtils;
@@ -65,6 +66,7 @@ import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
/**
* @author Thomas Risberg
* @author Dan Garrette
* @author Mahmoud Ben Hassine
*/
public class StepParserTests {
@@ -297,7 +299,7 @@ public class StepParserTests {
public void testTransactionManagerDefaults() throws Exception {
ApplicationContext ctx = stepParserParentAttributeTestsCtx;
assertTrue(getTransactionManager("defaultTxMgrStep", ctx) instanceof ResourcelessTransactionManager);
assertTrue(getTransactionManager("defaultTxMgrStep", ctx) instanceof DataSourceTransactionManager);
assertDummyTransactionManager("specifiedTxMgrStep", "dummyTxMgr", ctx);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2007 the original author or authors.
* Copyright 2006-2021 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.
@@ -26,7 +26,6 @@ import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
@@ -35,6 +34,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
@ContextConfiguration
@@ -52,14 +52,6 @@ public class TaskletParserAdapterTests {
@Autowired
private JobRepository jobRepository;
@Autowired
private MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean;
@Before
public void setUp() {
mapJobRepositoryFactoryBean.clear();
}
@Test
public void testTaskletRef() throws Exception {
assertNotNull(job1);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2007 the original author or authors.
* Copyright 2006-2021 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.
@@ -17,7 +17,6 @@ package org.springframework.batch.core.configuration.xml;
import java.lang.reflect.Field;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
@@ -27,7 +26,6 @@ import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.job.flow.FlowJob;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.step.tasklet.TaskletStep;
import org.springframework.batch.core.test.namespace.config.DummyNamespaceHandler;
import org.springframework.beans.factory.annotation.Autowired;
@@ -42,6 +40,7 @@ import static org.junit.Assert.*;
/**
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
@ContextConfiguration
@@ -72,14 +71,6 @@ public class TaskletParserBeanPropertiesTests {
@Autowired
private JobRepository jobRepository;
@Autowired
private MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean;
@Before
public void setUp() {
mapJobRepositoryFactoryBean.clear();
}
@Test
public void testTaskletRef() throws Exception {
assertNotNull(job1);

View File

@@ -1,58 +0,0 @@
/*
* Copyright 2010-2018 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
*
* https://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.core.explore.support;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import java.util.Date;
/**
* Tests for {@link MapJobExplorerFactoryBean}.
*/
public class MapJobExplorerFactoryBeanTests {
/**
* Use the factory to create repository and check the explorer remembers
* created executions.
*/
@Test
public void testCreateExplorer() throws Exception {
MapJobRepositoryFactoryBean repositoryFactory = new MapJobRepositoryFactoryBean();
JobRepository jobRepository = repositoryFactory.getObject();
JobExecution jobExecution = jobRepository.createJobExecution("foo", new JobParameters());
//simulating a running job execution
jobExecution.setStartTime(new Date());
jobRepository.update(jobExecution);
MapJobExplorerFactoryBean tested = new MapJobExplorerFactoryBean(repositoryFactory);
tested.afterPropertiesSet();
JobExplorer explorer = tested.getObject();
assertEquals(1, explorer.findRunningJobExecutions("foo").size());
}
}

View File

@@ -1,87 +0,0 @@
/*
* Copyright 2006-2019 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
*
* https://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.core.explore.support;
import org.junit.Test;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.job.SimpleJob;
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.core.step.tasklet.TaskletStep;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.lang.Nullable;
import java.util.Set;
import static org.junit.Assert.assertEquals;
/**
* @author Dave Syer
*
*/
public class MapJobExplorerIntegrationTests {
private boolean block = true;
@Test
public void testRunningJobExecution() throws Exception {
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
MapJobRepositoryFactoryBean repositoryFactory = new MapJobRepositoryFactoryBean();
repositoryFactory.afterPropertiesSet();
JobRepository jobRepository = repositoryFactory.getObject();
jobLauncher.setJobRepository(jobRepository);
jobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());
jobLauncher.afterPropertiesSet();
SimpleJob job = new SimpleJob("job");
TaskletStep step = new TaskletStep("step");
step.setTasklet(new Tasklet() {
@Nullable
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
while (block) {
Thread.sleep(100L);
}
return RepeatStatus.FINISHED;
}
});
step.setTransactionManager(repositoryFactory.getTransactionManager());
step.setJobRepository(jobRepository);
step.afterPropertiesSet();
job.addStep(step);
job.setJobRepository(jobRepository);
job.afterPropertiesSet();
jobLauncher.run(job, new JobParametersBuilder().addString("test", getClass().getName()).toJobParameters());
Thread.sleep(500L);
JobExplorer explorer = new MapJobExplorerFactoryBean(repositoryFactory).getObject();
Set<JobExecution> executions = explorer.findRunningJobExecutions("job");
assertEquals(1, executions.size());
assertEquals(1, executions.iterator().next().getStepExecutions().size());
block = false;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2019 the original author or authors.
* Copyright 2006-2021 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.
@@ -26,8 +26,11 @@ import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.step.StepSupport;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.lang.Nullable;
import java.util.Collection;
@@ -52,7 +55,14 @@ public class ExtendedAbstractJobTests {
@Before
public void setUp() throws Exception {
MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(embeddedDatabase);
factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase));
factory.afterPropertiesSet();
jobRepository = factory.getObject();
job = new StubJob("job", jobRepository);
}
@@ -166,13 +176,10 @@ public class ExtendedAbstractJobTests {
}
}
MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
factory.afterPropertiesSet();
JobRepository repository = factory.getObject();
job.setJobRepository(repository);
job.setJobRepository(this.jobRepository);
job.setRestartable(true);
JobExecution execution = repository.createJobExecution("testHandleStepJob", new JobParameters());
JobExecution execution = this.jobRepository.createJobExecution("testHandleStepJob", new JobParameters());
job.handleStep(new StubStep(), execution);
assertEquals(StubStep.value, execution.getExecutionContext().get(StubStep.key));
@@ -180,9 +187,9 @@ public class ExtendedAbstractJobTests {
// simulate restart and check the job execution context's content survives
execution.setEndTime(new Date());
execution.setStatus(BatchStatus.FAILED);
repository.update(execution);
this.jobRepository.update(execution);
JobExecution restarted = repository.createJobExecution("testHandleStepJob", new JobParameters());
JobExecution restarted = this.jobRepository.createJobExecution("testHandleStepJob", new JobParameters());
assertEquals(StubStep.value, restarted.getExecutionContext().get(StubStep.key));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2008-2014 the original author or authors.
* Copyright 2008-2021 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.
@@ -29,14 +29,18 @@ import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.UnexpectedJobExecutionException;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.step.StepSupport;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
/**
* Test suite for various failure scenarios during job processing.
*
* @author Lucas Ward
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
public class SimpleJobFailureTests {
@@ -47,7 +51,15 @@ public class SimpleJobFailureTests {
@Before
public void init() throws Exception {
JobRepository jobRepository = new MapJobRepositoryFactoryBean().getObject();
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(embeddedDatabase);
factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase));
factory.afterPropertiesSet();
JobRepository jobRepository = factory.getObject();
job.setJobRepository(jobRepository);
execution = jobRepository.createJobExecution("job", new JobParameters());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2019 the original author or authors.
* Copyright 2006-2021 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.
@@ -45,23 +45,32 @@ import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.UnexpectedJobExecutionException;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.explore.support.JobExplorerFactoryBean;
import org.springframework.batch.core.listener.JobExecutionListenerSupport;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.dao.ExecutionContextDao;
import org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer;
import org.springframework.batch.core.repository.dao.JdbcExecutionContextDao;
import org.springframework.batch.core.repository.dao.JdbcJobExecutionDao;
import org.springframework.batch.core.repository.dao.JdbcJobInstanceDao;
import org.springframework.batch.core.repository.dao.JdbcStepExecutionDao;
import org.springframework.batch.core.repository.dao.JobExecutionDao;
import org.springframework.batch.core.repository.dao.JobInstanceDao;
import org.springframework.batch.core.repository.dao.MapExecutionContextDao;
import org.springframework.batch.core.repository.dao.MapJobExecutionDao;
import org.springframework.batch.core.repository.dao.MapJobInstanceDao;
import org.springframework.batch.core.repository.dao.MapStepExecutionDao;
import org.springframework.batch.core.repository.dao.StepExecutionDao;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.SimpleJobRepository;
import org.springframework.batch.core.step.StepSupport;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer;
import org.springframework.jdbc.support.incrementer.HsqlSequenceMaxValueIncrementer;
/**
* Tests for DefaultJobLifecycle. MapJobDao and MapStepExecutionDao are used
* instead of a mock repository to test that status is being stored correctly.
* Tests for DefaultJobLifecycle.
*
* @author Lucas Ward
* @author Will Schipp
@@ -71,13 +80,7 @@ public class SimpleJobTests {
private JobRepository jobRepository;
private JobInstanceDao jobInstanceDao;
private JobExecutionDao jobExecutionDao;
private StepExecutionDao stepExecutionDao;
private ExecutionContextDao ecDao;
private JobExplorer jobExplorer;
private List<Serializable> list = new ArrayList<>();
@@ -100,11 +103,21 @@ public class SimpleJobTests {
@Before
public void setUp() throws Exception {
jobInstanceDao = new MapJobInstanceDao();
jobExecutionDao = new MapJobExecutionDao();
stepExecutionDao = new MapStepExecutionDao();
ecDao = new MapExecutionContextDao();
jobRepository = new SimpleJobRepository(jobInstanceDao, jobExecutionDao, stepExecutionDao, ecDao);
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.generateUniqueName(true)
.build();
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(embeddedDatabase);
JobRepositoryFactoryBean repositoryFactoryBean = new JobRepositoryFactoryBean();
repositoryFactoryBean.setDataSource(embeddedDatabase);
repositoryFactoryBean.setTransactionManager(transactionManager);
repositoryFactoryBean.afterPropertiesSet();
this.jobRepository = repositoryFactoryBean.getObject();
JobExplorerFactoryBean explorerFactoryBean = new JobExplorerFactoryBean();
explorerFactoryBean.setDataSource(embeddedDatabase);
explorerFactoryBean.afterPropertiesSet();
this.jobExplorer = explorerFactoryBean.getObject();
job = new SimpleJob();
job.setJobRepository(jobRepository);
@@ -528,9 +541,8 @@ public class SimpleJobTests {
* Check JobRepository to ensure status is being saved.
*/
private void checkRepository(BatchStatus status, ExitStatus exitStatus) {
assertEquals(jobInstance, jobInstanceDao.getJobInstance(job.getName(), jobParameters));
// because map DAO stores in memory, it can be checked directly
JobExecution jobExecution = jobExecutionDao.findJobExecutions(jobInstance).get(0);
assertEquals(jobInstance, this.jobRepository.getLastJobExecution(job.getName(), jobParameters).getJobInstance());
JobExecution jobExecution = this.jobExplorer.getJobExecutions(jobInstance).get(0);
assertEquals(jobInstance.getId(), jobExecution.getJobId());
assertEquals(status, jobExecution.getStatus());
if (exitStatus != null) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2013 the original author or authors.
* Copyright 2006-2021 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.
@@ -27,11 +27,15 @@ import org.springframework.batch.core.JobInterruptedException;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.step.StepSupport;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
/**
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
public class SimpleStepHandlerTests {
@@ -44,8 +48,15 @@ public class SimpleStepHandlerTests {
@Before
public void setUp() throws Exception {
MapJobRepositoryFactoryBean jobRepositoryFactoryBean = new MapJobRepositoryFactoryBean();
jobRepository = jobRepositoryFactoryBean.getObject();
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(embeddedDatabase);
factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase));
factory.afterPropertiesSet();
jobRepository = factory.getObject();
jobExecution = jobRepository.createJobExecution("job", new JobParameters());
stepHandler = new SimpleStepHandler(jobRepository);
stepHandler.afterPropertiesSet();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 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.
@@ -30,7 +30,7 @@ import org.springframework.batch.core.job.flow.Flow;
import org.springframework.batch.core.job.flow.FlowExecution;
import org.springframework.batch.core.job.flow.JobFlowExecutor;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.step.JobRepositorySupport;
import org.springframework.batch.core.step.StepSupport;
import static org.junit.Assert.assertEquals;
@@ -38,6 +38,7 @@ import static org.junit.Assert.assertEquals;
/**
* @author Dave Syer
* @author Michael Minella
* @author Mahmoud Ben Hassine
*
*/
public class FlowBuilderTests {
@@ -45,7 +46,7 @@ public class FlowBuilderTests {
@Test
public void test() throws Exception {
FlowBuilder<Flow> builder = new FlowBuilder<>("flow");
JobRepository jobRepository = new MapJobRepositoryFactoryBean().getObject();
JobRepository jobRepository = new JobRepositorySupport();
JobExecution execution = jobRepository.createJobExecution("foo", new JobParameters());
builder.start(new StepSupport("step") {
@Override
@@ -58,7 +59,7 @@ public class FlowBuilderTests {
@Test
public void testTransitionOrdering() throws Exception {
FlowBuilder<Flow> builder = new FlowBuilder<>("transitionsFlow");
JobRepository jobRepository = new MapJobRepositoryFactoryBean().getObject();
JobRepository jobRepository = new JobRepositorySupport();
JobExecution execution = jobRepository.createJobExecution("foo", new JobParameters());
StepSupport stepA = new StepSupport("stepA") {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 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.
@@ -17,6 +17,8 @@ package org.springframework.batch.core.job.builder;
import java.util.Arrays;
import javax.sql.DataSource;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
@@ -40,7 +42,7 @@ import org.springframework.batch.core.job.flow.FlowExecutionStatus;
import org.springframework.batch.core.job.flow.JobExecutionDecider;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.step.StepSupport;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.beans.factory.annotation.Value;
@@ -49,6 +51,9 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.lang.Nullable;
/**
@@ -104,7 +109,15 @@ public class FlowJobBuilderTests {
@Before
public void init() throws Exception {
jobRepository = new MapJobRepositoryFactoryBean().getObject();
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(embeddedDatabase);
factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase));
factory.afterPropertiesSet();
jobRepository = factory.getObject();
execution = jobRepository.createJobExecution("flow", new JobParameters());
}
@@ -293,6 +306,15 @@ public class FlowJobBuilderTests {
.build()
.build();
}
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.generateUniqueName(true)
.build();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020 the original author or authors.
* Copyright 2020-2021 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.
@@ -15,6 +15,8 @@
*/
package org.springframework.batch.core.job.builder;
import javax.sql.DataSource;
import org.junit.Assert;
import org.junit.Test;
@@ -34,6 +36,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import static org.junit.Assert.assertEquals;
@@ -74,6 +77,15 @@ public class JobBuilderTests {
.build())
.build();
}
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.generateUniqueName(true)
.build();
}
}
static class InterfaceBasedJobExecutionListener implements JobExecutionListener {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2014 the original author or authors.
* Copyright 2010-2021 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.
@@ -34,14 +34,18 @@ import org.springframework.batch.core.job.flow.support.StateTransition;
import org.springframework.batch.core.job.flow.support.state.EndState;
import org.springframework.batch.core.job.flow.support.state.StepState;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.step.StepSupport;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
/**
* Test suite for various failure scenarios during job processing.
*
* @author Lucas Ward
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
public class FlowJobFailureTests {
@@ -52,7 +56,15 @@ public class FlowJobFailureTests {
@Before
public void init() throws Exception {
JobRepository jobRepository = new MapJobRepositoryFactoryBean().getObject();
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(embeddedDatabase);
factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase));
factory.afterPropertiesSet();
JobRepository jobRepository = factory.getObject();
job.setJobRepository(jobRepository);
execution = jobRepository.createJobExecution("job", new JobParameters());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2019 the original author or authors.
* Copyright 2006-2021 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.
@@ -25,6 +25,8 @@ import org.springframework.batch.core.JobInterruptedException;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.explore.support.JobExplorerFactoryBean;
import org.springframework.batch.core.job.flow.support.DefaultStateTransitionComparator;
import org.springframework.batch.core.job.flow.support.SimpleFlow;
import org.springframework.batch.core.job.flow.support.StateTransition;
@@ -38,9 +40,11 @@ import org.springframework.batch.core.jsr.partition.JsrPartitionHandler;
import org.springframework.batch.core.jsr.step.PartitionStep;
import org.springframework.batch.core.jsr.partition.JsrStepExecutionSplitter;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.dao.JobExecutionDao;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.step.StepSupport;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.lang.Nullable;
import java.util.ArrayList;
@@ -56,6 +60,7 @@ import static org.junit.Assert.fail;
/**
* @author Dave Syer
* @author Michael Minella
* @author Mahmoud Ben Hassine
*
*/
public class FlowJobTests {
@@ -66,18 +71,28 @@ public class FlowJobTests {
private JobRepository jobRepository;
private boolean fail = false;
private JobExplorer jobExplorer;
private JobExecutionDao jobExecutionDao;
private boolean fail = false;
@Before
public void setUp() throws Exception {
MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(embeddedDatabase);
factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase));
factory.afterPropertiesSet();
jobExecutionDao = factory.getJobExecutionDao();
jobRepository = factory.getObject();
job.setJobRepository(jobRepository);
jobExecution = jobRepository.createJobExecution("job", new JobParameters());
this.jobRepository = factory.getObject();
job.setJobRepository(this.jobRepository);
this.jobExecution = this.jobRepository.createJobExecution("job", new JobParameters());
JobExplorerFactoryBean explorerFactoryBean = new JobExplorerFactoryBean();
explorerFactoryBean.setDataSource(embeddedDatabase);
explorerFactoryBean.afterPropertiesSet();
this.jobExplorer = explorerFactoryBean.getObject();
}
@Test
@@ -743,9 +758,8 @@ public class FlowJobTests {
}
private void checkRepository(BatchStatus status, ExitStatus exitStatus) {
// because map dao stores in memory, it can be checked directly
JobInstance jobInstance = jobExecution.getJobInstance();
JobExecution other = jobExecutionDao.findJobExecutions(jobInstance).get(0);
JobInstance jobInstance = this.jobExecution.getJobInstance();
JobExecution other = this.jobExplorer.getJobExecutions(jobInstance).get(0);
assertEquals(jobInstance.getId(), other.getJobId());
assertEquals(status, other.getStatus());
if (exitStatus != null) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2013 the original author or authors.
* Copyright 2006-2021 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.
@@ -35,11 +35,15 @@ import org.springframework.batch.core.job.flow.support.StateTransition;
import org.springframework.batch.core.job.flow.support.state.EndState;
import org.springframework.batch.core.job.flow.support.state.StepState;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.step.StepSupport;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
/**
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
public class FlowStepTests {
@@ -49,7 +53,15 @@ public class FlowStepTests {
@Before
public void setUp() throws Exception {
jobRepository = new MapJobRepositoryFactoryBean().getObject();
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean();
jobRepositoryFactoryBean.setDataSource(embeddedDatabase);
jobRepositoryFactoryBean.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase));
jobRepositoryFactoryBean.afterPropertiesSet();
jobRepository = jobRepositoryFactoryBean.getObject();
jobExecution = jobRepository.createJobExecution("job", new JobParameters());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2019 the original author or authors.
* Copyright 2006-2021 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.
@@ -26,7 +26,7 @@ import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.explore.support.MapJobExplorerFactoryBean;
import org.springframework.batch.core.explore.support.JobExplorerFactoryBean;
import org.springframework.batch.core.job.flow.Flow;
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
import org.springframework.batch.core.job.flow.FlowExecutor;
@@ -43,9 +43,11 @@ import org.springframework.batch.core.job.flow.support.state.StepState;
import org.springframework.batch.core.jsr.JsrStepExecution;
import org.springframework.batch.core.jsr.job.flow.support.JsrFlow;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.dao.JobExecutionDao;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.step.StepSupport;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.lang.Nullable;
import javax.batch.api.Decider;
@@ -62,6 +64,7 @@ import static org.junit.Assert.fail;
/**
* @author Dave Syer
* @author Michael Minella
* @author Mahmoud Ben Hassine
*/
public class JsrFlowJobTests {
@@ -75,19 +78,23 @@ public class JsrFlowJobTests {
private boolean fail = false;
private JobExecutionDao jobExecutionDao;
@Before
public void setUp() throws Exception {
job = new JsrFlowJob();
MapJobRepositoryFactoryBean jobRepositoryFactory = new MapJobRepositoryFactoryBean();
jobRepositoryFactory.afterPropertiesSet();
jobExecutionDao = jobRepositoryFactory.getJobExecutionDao();
jobRepository = jobRepositoryFactory.getObject();
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(embeddedDatabase);
factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase));
factory.afterPropertiesSet();
jobRepository = factory.getObject();
job.setJobRepository(jobRepository);
jobExecution = jobRepository.createJobExecution("job", new JobParameters());
MapJobExplorerFactoryBean jobExplorerFactory = new MapJobExplorerFactoryBean(jobRepositoryFactory);
JobExplorerFactoryBean jobExplorerFactory = new JobExplorerFactoryBean();
jobExplorerFactory.setDataSource(embeddedDatabase);
jobExplorerFactory.afterPropertiesSet();
jobExplorer = jobExplorerFactory.getObject();
job.setJobExplorer(jobExplorer);
@@ -751,9 +758,8 @@ public class JsrFlowJobTests {
}
private void checkRepository(BatchStatus status, ExitStatus exitStatus) {
// because map DAO stores in memory, it can be checked directly
JobInstance jobInstance = jobExecution.getJobInstance();
JobExecution other = jobExecutionDao.findJobExecutions(jobInstance).get(0);
JobExecution other = jobExplorer.getJobExecutions(jobInstance).get(0);
assertEquals(jobInstance.getId(), other.getJobId());
assertEquals(status, other.getStatus());
if (exitStatus != null) {

View File

@@ -27,9 +27,12 @@ import org.springframework.batch.core.jsr.AbstractJsrTestCase;
import org.springframework.batch.core.jsr.configuration.support.BatchPropertyContext;
import org.springframework.batch.core.jsr.step.batchlet.BatchletSupport;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.step.JobRepositorySupport;
import org.springframework.batch.core.step.StepSupport;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.util.StopWatch;
import javax.batch.api.BatchProperty;
@@ -56,7 +59,7 @@ import static org.junit.Assert.fail;
public class JsrPartitionHandlerTests extends AbstractJsrTestCase {
private JsrPartitionHandler handler;
private JobRepository repository = new JobRepositorySupport();
private JobRepository repository;
private StepExecution stepExecution;
private AtomicInteger count;
private BatchPropertyContext propertyContext;
@@ -82,7 +85,15 @@ public class JsrPartitionHandlerTests extends AbstractJsrTestCase {
});
propertyContext = new BatchPropertyContext();
handler.setPropertyContext(propertyContext);
repository = new MapJobRepositoryFactoryBean().getObject();
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(embeddedDatabase);
factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase));
factory.afterPropertiesSet();
repository = factory.getObject();
handler.setJobRepository(repository);
MyPartitionReducer.reset();
CountingPartitionCollector.reset();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2019 the original author or authors.
* Copyright 2013-2021 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.
@@ -37,12 +37,15 @@ import org.springframework.batch.core.repository.JobExecutionAlreadyRunningExcep
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.lang.Nullable;
public class JsrChunkProcessorTests {
@@ -71,7 +74,15 @@ public class JsrChunkProcessorTests {
builder = new JsrSimpleStepBuilder<>(new StepBuilder("step1"));
builder.setBatchPropertyContext(new BatchPropertyContext());
repository = new MapJobRepositoryFactoryBean().getObject();
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(embeddedDatabase);
factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase));
factory.afterPropertiesSet();
repository = factory.getObject();
builder.repository(repository);
builder.transactionManager(new ResourcelessTransactionManager());
stepExecution = null;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2019 the original author or authors.
* Copyright 2013-2021 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.
@@ -39,12 +39,15 @@ import org.springframework.batch.core.repository.JobExecutionAlreadyRunningExcep
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.lang.Nullable;
public class JsrFaultTolerantChunkProcessorTests {
@@ -73,7 +76,15 @@ public class JsrFaultTolerantChunkProcessorTests {
builder = new JsrFaultTolerantStepBuilder<>(new StepBuilder("step1"));
builder.setBatchPropertyContext(new BatchPropertyContext());
repository = new MapJobRepositoryFactoryBean().getObject();
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(embeddedDatabase);
factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase));
factory.afterPropertiesSet();
repository = factory.getObject();
builder.repository(repository);
builder.transactionManager(new ResourcelessTransactionManager());
stepExecution = null;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2021 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.
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals;
import java.util.Collections;
import java.util.List;
import javax.sql.DataSource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -43,6 +45,7 @@ import org.springframework.batch.item.support.ListItemReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.lang.Nullable;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
@@ -151,6 +154,15 @@ public class ItemListenerErrorTests {
.build();
}
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.generateUniqueName(true)
.build();
}
@Bean
public FailingListener itemListener() {
return new FailingListener();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2014 the original author or authors.
* Copyright 2006-2021 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.
@@ -32,12 +32,16 @@ import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.partition.PartitionHandler;
import org.springframework.batch.core.partition.StepExecutionSplitter;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import static org.junit.Assert.assertEquals;
/**
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
public class PartitionStepTests {
@@ -48,7 +52,14 @@ public class PartitionStepTests {
@Before
public void setUp() throws Exception {
MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(embeddedDatabase);
factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase));
factory.afterPropertiesSet();
jobRepository = factory.getObject();
step.setJobRepository(jobRepository);
step.setName("partitioned");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2014 the original author or authors.
* Copyright 2011-2021 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.
@@ -21,9 +21,12 @@ import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.explore.support.MapJobExplorerFactoryBean;
import org.springframework.batch.core.explore.support.JobExplorerFactoryBean;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import java.util.Arrays;
import java.util.Collections;
@@ -45,9 +48,19 @@ public class RemoteStepExecutionAggregatorTests {
@Before
public void init() throws Exception {
MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(embeddedDatabase);
factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase));
factory.afterPropertiesSet();
JobRepository jobRepository = factory.getObject();
aggregator.setJobExplorer(new MapJobExplorerFactoryBean(factory).getObject());
JobExplorerFactoryBean explorerFactoryBean = new JobExplorerFactoryBean();
explorerFactoryBean.setDataSource(embeddedDatabase);
explorerFactoryBean.afterPropertiesSet();
aggregator.setJobExplorer(explorerFactoryBean.getObject());
jobExecution = jobRepository.createJobExecution("job", new JobParameters());
result = jobExecution.createStepExecution("aggregate");
stepExecution1 = jobExecution.createStepExecution("foo:1");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2008-2014 the original author or authors.
* Copyright 2008-2021 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.
@@ -33,9 +33,12 @@ import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.step.tasklet.TaskletStep;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -52,7 +55,14 @@ public class SimpleStepExecutionSplitterTests {
@Before
public void setUp() throws Exception {
step = new TaskletStep("step");
MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(embeddedDatabase);
factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase));
factory.afterPropertiesSet();
jobRepository = factory.getObject();
stepExecution = jobRepository.createJobExecution("job", new JobParameters()).createStepExecution("bar");
jobRepository.add(stepExecution);

View File

@@ -1,97 +0,0 @@
/*
* Copyright 2008-2012 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
*
* https://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.core.repository.dao;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runners.JUnit4;
import org.junit.runner.RunWith;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.item.ExecutionContext;
/**
* Tests for {@link MapExecutionContextDao}.
*/
@RunWith(JUnit4.class)
public class MapExecutionContextDaoTests extends AbstractExecutionContextDaoTests {
@Override
protected JobInstanceDao getJobInstanceDao() {
return new MapJobInstanceDao();
}
@Override
protected JobExecutionDao getJobExecutionDao() {
return new MapJobExecutionDao();
}
@Override
protected StepExecutionDao getStepExecutionDao() {
return new MapStepExecutionDao();
}
@Override
protected ExecutionContextDao getExecutionContextDao() {
return new MapExecutionContextDao();
}
@Test
public void testSaveBothJobAndStepContextWithSameId() throws Exception {
MapExecutionContextDao tested = new MapExecutionContextDao();
JobExecution jobExecution = new JobExecution(1L);
StepExecution stepExecution = new StepExecution("stepName", jobExecution, 1L);
assertTrue(stepExecution.getId() == jobExecution.getId());
jobExecution.getExecutionContext().put("type", "job");
stepExecution.getExecutionContext().put("type", "step");
assertTrue(!jobExecution.getExecutionContext().get("type").equals(stepExecution.getExecutionContext().get("type")));
assertEquals("job", jobExecution.getExecutionContext().get("type"));
assertEquals("step", stepExecution.getExecutionContext().get("type"));
tested.saveExecutionContext(jobExecution);
tested.saveExecutionContext(stepExecution);
ExecutionContext jobCtx = tested.getExecutionContext(jobExecution);
ExecutionContext stepCtx = tested.getExecutionContext(stepExecution);
assertEquals("job", jobCtx.get("type"));
assertEquals("step", stepCtx.get("type"));
}
@Test
public void testPersistentCopy() throws Exception {
MapExecutionContextDao tested = new MapExecutionContextDao();
JobExecution jobExecution = new JobExecution((long)1);
StepExecution stepExecution = new StepExecution("stepName", jobExecution, 123L);
assertTrue(stepExecution.getExecutionContext().isEmpty());
tested.updateExecutionContext(stepExecution);
stepExecution.getExecutionContext().put("key","value");
ExecutionContext retrieved = tested.getExecutionContext(stepExecution);
assertTrue(retrieved.isEmpty());
tested.updateExecutionContext(jobExecution);
jobExecution.getExecutionContext().put("key", "value");
retrieved = tested.getExecutionContext(jobExecution);
assertTrue(retrieved.isEmpty());
}
}

View File

@@ -1,131 +0,0 @@
/*
* Copyright 2008-2014 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
*
* https://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.core.repository.dao;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import java.util.Collections;
import java.util.Date;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobInstance;
import org.springframework.batch.core.JobParameters;
@RunWith(JUnit4.class)
public class MapJobExecutionDaoTests extends AbstractJobExecutionDaoTests {
@Override
protected JobExecutionDao getJobExecutionDao() {
return new MapJobExecutionDao();
}
@Override
protected JobInstanceDao getJobInstanceDao() {
return new MapJobInstanceDao();
}
/**
* Modifications to saved entity do not affect the persisted object.
*/
@Test
public void testPersistentCopy() {
JobExecutionDao tested = new MapJobExecutionDao();
JobExecution jobExecution = new JobExecution(new JobInstance((long) 1, "mapJob"), new JobParameters());
assertNull(jobExecution.getStartTime());
tested.saveJobExecution(jobExecution);
jobExecution.setStartTime(new Date());
JobExecution retrieved = tested.getJobExecution(jobExecution.getId());
assertNull(retrieved.getStartTime());
tested.updateJobExecution(jobExecution);
jobExecution.setEndTime(new Date());
assertNull(retrieved.getEndTime());
}
/**
* Verify that the ids are properly generated even under heavy concurrent load
*/
@Test
public void testConcurrentSaveJobExecution() throws Exception {
final int iterations = 100;
// Object under test
final JobExecutionDao tested = new MapJobExecutionDao();
// Support objects for this testing
final CountDownLatch latch = new CountDownLatch(1);
final SortedSet<Long> ids = Collections.synchronizedSortedSet(new TreeSet<>()); // TODO Change to SkipList w/JDK6
final AtomicReference<Exception> exception = new AtomicReference<>(null);
// Implementation of the high-concurrency code
final Runnable codeUnderTest = new Runnable() {
@Override
public void run() {
try {
JobExecution jobExecution = new JobExecution(new JobInstance((long) -1, "mapJob"), new JobParameters());
latch.await();
tested.saveJobExecution(jobExecution);
ids.add(jobExecution.getId());
} catch(Exception e) {
exception.set(e);
}
}
};
// Create the threads
final Thread[] threads = new Thread[iterations];
for(int i = 0; i < iterations; i++) {
Thread t = new Thread(codeUnderTest, "Map Job Thread #" + (i+1));
t.setPriority(Thread.MAX_PRIORITY);
t.setDaemon(true);
t.start();
Thread.yield();
threads[i] = t;
}
// Let the high concurrency abuse begin!
do { latch.countDown(); } while(latch.getCount() > 0);
for(Thread t : threads) { t.join(); }
// Ensure no general exceptions arose
if(exception.get() != null) {
throw new RuntimeException("Exception occurred under high concurrency usage", exception.get());
}
// Validate the ids: we'd expect one of these three things to fail
if(ids.size() < iterations) {
fail("Duplicate id generated during high concurrency usage");
}
if(ids.first() < 0) {
fail("Generated an id less than zero during high concurrency usage: " + ids.first());
}
if(ids.last() > iterations) {
fail("Generated an id larger than expected during high concurrency usage: " + ids.last());
}
}
}

View File

@@ -1,62 +0,0 @@
/*
* Copyright 2008-2014 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
*
* https://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.core.repository.dao;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.springframework.batch.core.JobInstance;
import org.springframework.batch.core.JobParameters;
import java.util.List;
import static org.junit.Assert.assertTrue;
@RunWith(JUnit4.class)
public class MapJobInstanceDaoTests extends AbstractJobInstanceDaoTests {
@Override
protected JobInstanceDao getJobInstanceDao() {
return new MapJobInstanceDao();
}
@Test
public void testWildcardPrefix() {
MapJobInstanceDao mapJobInstanceDao = new MapJobInstanceDao();
mapJobInstanceDao.createJobInstance("testJob", new JobParameters());
mapJobInstanceDao.createJobInstance("Jobtest", new JobParameters());
List<JobInstance> jobInstances = mapJobInstanceDao.findJobInstancesByName("*Job", 0, 2);
assertTrue("Invalid matching job instances found, expected 1, got: " + jobInstances.size(), jobInstances.size() == 1);
}
@Test
public void testWildcardSuffix() {
MapJobInstanceDao mapJobInstanceDao = new MapJobInstanceDao();
mapJobInstanceDao.createJobInstance("testJob", new JobParameters());
mapJobInstanceDao.createJobInstance("Jobtest", new JobParameters());
List<JobInstance> jobInstances = mapJobInstanceDao.findJobInstancesByName("Job*", 0, 2);
assertTrue("No matching job instances found, expected 1, got: " + jobInstances.size(), jobInstances.size() == 1);
}
@Test
public void testWildcardRange() {
MapJobInstanceDao mapJobInstanceDao = new MapJobInstanceDao();
mapJobInstanceDao.createJobInstance("testJob", new JobParameters());
mapJobInstanceDao.createJobInstance("Jobtest", new JobParameters());
List<JobInstance> jobInstances = mapJobInstanceDao.findJobInstancesByName("*Job*", 0, 2);
assertTrue("No matching job instances found, expected 2, got: " + jobInstances.size(), jobInstances.size() == 2);
}
}

View File

@@ -1,142 +0,0 @@
/*
* Copyright 2008-2020 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
*
* https://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.core.repository.dao;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.util.Date;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.SimpleJobRepository;
@RunWith(JUnit4.class)
public class MapStepExecutionDaoTests extends AbstractStepExecutionDaoTests {
@Override
protected StepExecutionDao getStepExecutionDao() {
return new MapStepExecutionDao();
}
@Override
protected JobRepository getJobRepository() {
return new SimpleJobRepository(new MapJobInstanceDao(), new MapJobExecutionDao(), new MapStepExecutionDao(),
new MapExecutionContextDao());
}
/**
* Modifications to saved entity do not affect the persisted object.
*/
@Test
public void testPersistentCopy() {
StepExecutionDao tested = new MapStepExecutionDao();
JobExecution jobExecution = new JobExecution(77L);
StepExecution stepExecution = new StepExecution("stepName", jobExecution);
assertNull(stepExecution.getEndTime());
tested.saveStepExecution(stepExecution);
stepExecution.setEndTime(new Date());
StepExecution retrieved = tested.getStepExecution(jobExecution, stepExecution.getId());
assertNull(retrieved.getEndTime());
stepExecution.setEndTime(null);
tested.updateStepExecution(stepExecution);
stepExecution.setEndTime(new Date());
StepExecution stored = tested.getStepExecution(jobExecution, stepExecution.getId());
assertNull(stored.getEndTime());
}
@Test
public void testAddStepExecutions() {
StepExecutionDao tested = new MapStepExecutionDao();
JobExecution jobExecution = new JobExecution(88L);
// Create step execution with status STARTED
StepExecution stepExecution = new StepExecution("Step one", jobExecution);
stepExecution.setStatus(BatchStatus.STARTED);
// Save and check id
tested.saveStepExecution(stepExecution);
assertNotNull(stepExecution.getId());
// Job execution instance doesn't contain step execution instances
assertEquals(0, jobExecution.getStepExecutions().size());
// Load all execution steps and check
tested.addStepExecutions(jobExecution);
assertEquals(1, jobExecution.getStepExecutions().size());
// Check the first (and only) step execution instance of the job instance
StepExecution jobStepExecution = jobExecution.getStepExecutions().iterator().next();
assertEquals(BatchStatus.STARTED, jobStepExecution.getStatus());
assertEquals(stepExecution.getId(), jobStepExecution.getId());
// Load the step execution instance from the repository and check is it the same
StepExecution repoStepExecution = tested.getStepExecution(jobExecution, stepExecution.getId());
assertEquals(stepExecution.getId(), repoStepExecution.getId());
assertEquals(BatchStatus.STARTED, repoStepExecution.getStatus());
// Update the step execution instance
repoStepExecution.setStatus(BatchStatus.COMPLETED);
// Update the step execution in the repository and check
tested.updateStepExecution(repoStepExecution);
StepExecution updatedStepExecution = tested.getStepExecution(jobExecution, stepExecution.getId());
assertEquals(stepExecution.getId(), updatedStepExecution.getId());
assertEquals(BatchStatus.COMPLETED, updatedStepExecution.getStatus());
// Now, add step executions from the repository and check
tested.addStepExecutions(jobExecution);
jobStepExecution = jobExecution.getStepExecutions().iterator().next();
assertEquals(1, jobExecution.getStepExecutions().size());
assertEquals(stepExecution.getId(), jobStepExecution.getId());
assertEquals(BatchStatus.COMPLETED, jobStepExecution.getStatus());
}
@Test
public void testCountStepExecutions() {
// Given
StepExecutionDao tested = new MapStepExecutionDao();
JobExecution jobExecution = new JobExecution(jobInstance, 88L, null, null);
StepExecution firstStepExecution = new StepExecution("Step one", jobExecution);
firstStepExecution.setStatus(BatchStatus.STARTED);
tested.saveStepExecution(firstStepExecution);
StepExecution secondStepExecution = new StepExecution("Step two", jobExecution);
secondStepExecution.setStatus(BatchStatus.STARTED);
tested.saveStepExecution(secondStepExecution);
// When
int result = tested.countStepExecutions(jobInstance, firstStepExecution.getStepName());
// Then
assertEquals(1, result);
}
}

View File

@@ -1,62 +0,0 @@
/*
* Copyright 2008-2018 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
*
* https://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.core.repository.support;
import org.junit.Test;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.job.JobSupport;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobRepository;
import java.util.Date;
import static org.junit.Assert.fail;
/**
* Tests for {@link MapJobRepositoryFactoryBean}.
*/
public class MapJobRepositoryFactoryBeanTests {
private MapJobRepositoryFactoryBean tested = new MapJobRepositoryFactoryBean();
/**
* Use the factory to create repository and check the repository remembers
* created executions.
*/
@Test
public void testCreateRepository() throws Exception {
tested.afterPropertiesSet();
JobRepository repository = tested.getObject();
Job job = new JobSupport("jobName");
JobParameters jobParameters = new JobParameters();
JobExecution jobExecution = repository.createJobExecution(job.getName(), jobParameters);
// simulate a running execution
jobExecution.setStartTime(new Date());
repository.update(jobExecution);
try {
repository.createJobExecution(job.getName(), jobParameters);
fail("Expected JobExecutionAlreadyRunningException");
}
catch (JobExecutionAlreadyRunningException e) {
// expected
}
}
}

View File

@@ -19,6 +19,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.core.BatchStatus;
@@ -41,12 +42,15 @@ import org.springframework.batch.core.configuration.xml.DummyItemReader;
import org.springframework.batch.core.configuration.xml.DummyItemWriter;
import org.springframework.batch.core.job.SimpleJob;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.batch.item.support.ListItemWriter;
import org.springframework.batch.item.support.PassThroughItemProcessor;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.lang.Nullable;
import org.springframework.transaction.PlatformTransactionManager;
@@ -61,9 +65,24 @@ import static org.junit.Assert.assertEquals;
*/
public class StepBuilderTests {
private JobRepository jobRepository;
@Before
public void setUp() throws Exception {
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(embeddedDatabase);
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(embeddedDatabase);
factory.setTransactionManager(transactionManager);
factory.afterPropertiesSet();
this.jobRepository = factory.getObject();
}
@Test
public void test() throws Exception {
JobRepository jobRepository = new MapJobRepositoryFactoryBean().getObject();
StepExecution execution = jobRepository.createJobExecution("foo", new JobParameters()).createStepExecution(
"step");
jobRepository.add(execution);
@@ -76,7 +95,6 @@ public class StepBuilderTests {
@Test
public void testListeners() throws Exception {
JobRepository jobRepository = new MapJobRepositoryFactoryBean().getObject();
StepExecution execution = jobRepository.createJobExecution("foo", new JobParameters()).createStepExecution("step");
jobRepository.add(execution);
PlatformTransactionManager transactionManager = new ResourcelessTransactionManager();
@@ -98,7 +116,6 @@ public class StepBuilderTests {
@Test
public void testAnnotationBasedChunkListenerForTaskletStep() throws Exception {
JobRepository jobRepository = new MapJobRepositoryFactoryBean().getObject();
StepExecution execution = jobRepository.createJobExecution("foo", new JobParameters()).createStepExecution("step");
jobRepository.add(execution);
PlatformTransactionManager transactionManager = new ResourcelessTransactionManager();
@@ -115,7 +132,6 @@ public class StepBuilderTests {
@Test
public void testAnnotationBasedChunkListenerForSimpleTaskletStep() throws Exception {
JobRepository jobRepository = new MapJobRepositoryFactoryBean().getObject();
StepExecution execution = jobRepository.createJobExecution("foo", new JobParameters()).createStepExecution("step");
jobRepository.add(execution);
PlatformTransactionManager transactionManager = new ResourcelessTransactionManager();
@@ -134,7 +150,6 @@ public class StepBuilderTests {
@Test
public void testAnnotationBasedChunkListenerForFaultTolerantTaskletStep() throws Exception {
JobRepository jobRepository = new MapJobRepositoryFactoryBean().getObject();
StepExecution execution = jobRepository.createJobExecution("foo", new JobParameters()).createStepExecution("step");
jobRepository.add(execution);
PlatformTransactionManager transactionManager = new ResourcelessTransactionManager();
@@ -154,7 +169,6 @@ public class StepBuilderTests {
@Test
public void testAnnotationBasedChunkListenerForJobStepBuilder() throws Exception {
JobRepository jobRepository = new MapJobRepositoryFactoryBean().getObject();
StepExecution execution = jobRepository.createJobExecution("foo", new JobParameters()).createStepExecution("step");
jobRepository.add(execution);
PlatformTransactionManager transactionManager = new ResourcelessTransactionManager();
@@ -175,7 +189,6 @@ public class StepBuilderTests {
@Test
public void testItemListeners() throws Exception {
JobRepository jobRepository = new MapJobRepositoryFactoryBean().getObject();
StepExecution execution = jobRepository.createJobExecution("foo", new JobParameters()).createStepExecution("step");
jobRepository.add(execution);
PlatformTransactionManager transactionManager = new ResourcelessTransactionManager();
@@ -218,7 +231,6 @@ public class StepBuilderTests {
}
private void assertStepFunctions(boolean faultTolerantStep) throws Exception {
JobRepository jobRepository = new MapJobRepositoryFactoryBean().getObject();
StepExecution execution = jobRepository.createJobExecution("foo", new JobParameters()).createStepExecution("step");
jobRepository.add(execution);
PlatformTransactionManager transactionManager = new ResourcelessTransactionManager();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2019 the original author or authors.
* Copyright 2006-2021 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.
@@ -37,10 +37,13 @@ import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepListener;
import org.springframework.batch.core.listener.SkipListenerSupport;
import org.springframework.batch.core.repository.dao.MapExecutionContextDao;
import org.springframework.batch.core.repository.dao.MapJobExecutionDao;
import org.springframework.batch.core.repository.dao.MapJobInstanceDao;
import org.springframework.batch.core.repository.dao.MapStepExecutionDao;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer;
import org.springframework.batch.core.repository.dao.JdbcExecutionContextDao;
import org.springframework.batch.core.repository.dao.JdbcJobExecutionDao;
import org.springframework.batch.core.repository.dao.JdbcJobInstanceDao;
import org.springframework.batch.core.repository.dao.JdbcStepExecutionDao;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.SimpleJobRepository;
import org.springframework.batch.core.step.AbstractStep;
import org.springframework.batch.core.step.factory.FaultTolerantStepFactoryBean;
@@ -53,9 +56,16 @@ import org.springframework.batch.item.support.AbstractItemCountingItemStreamItem
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.batch.support.transaction.TransactionAwareProxyFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer;
import org.springframework.jdbc.support.incrementer.HsqlSequenceMaxValueIncrementer;
import org.springframework.lang.Nullable;
import org.springframework.retry.policy.MapRetryContextCache;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.StringUtils;
@@ -64,6 +74,7 @@ import static org.junit.Assert.assertTrue;
/**
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
public class FaultTolerantStepFactoryBeanRetryTests {
@@ -85,9 +96,7 @@ public class FaultTolerantStepFactoryBeanRetryTests {
boolean fail = false;
private SimpleJobRepository repository = new SimpleJobRepository(
new MapJobInstanceDao(), new MapJobExecutionDao(),
new MapStepExecutionDao(), new MapExecutionContextDao());
private JobRepository repository;
JobExecution jobExecution;
@@ -102,6 +111,18 @@ public class FaultTolerantStepFactoryBeanRetryTests {
@Before
public void setUp() throws Exception {
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.generateUniqueName(true)
.build();
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(embeddedDatabase);
JobRepositoryFactoryBean repositoryFactoryBean = new JobRepositoryFactoryBean();
repositoryFactoryBean.setDataSource(embeddedDatabase);
repositoryFactoryBean.setTransactionManager(transactionManager);
repositoryFactoryBean.afterPropertiesSet();
repository = repositoryFactoryBean.getObject();
factory = new FaultTolerantStepFactoryBean<>();
factory.setBeanName("step");
@@ -109,7 +130,7 @@ public class FaultTolerantStepFactoryBeanRetryTests {
new ArrayList<>()));
factory.setItemWriter(writer);
factory.setJobRepository(repository);
factory.setTransactionManager(new ResourcelessTransactionManager());
factory.setTransactionManager(transactionManager);
factory.setRetryableExceptionClasses(getExceptionMap(Exception.class));
factory.setCommitInterval(1); // trivial by default

View File

@@ -37,7 +37,7 @@ import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepListener;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.FatalStepExecutionException;
import org.springframework.batch.core.step.factory.FaultTolerantStepFactoryBean;
@@ -46,6 +46,9 @@ import org.springframework.batch.item.support.ListItemReader;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.batch.support.transaction.TransactionAwareProxyFactory;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionAttribute;
@@ -106,8 +109,13 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
factory.setSkippableExceptionClasses(getExceptionMap(Exception.class));
MapJobRepositoryFactoryBean repositoryFactory = new MapJobRepositoryFactoryBean();
repositoryFactory.setTransactionManager(transactionManager);
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JobRepositoryFactoryBean repositoryFactory = new JobRepositoryFactoryBean();
repositoryFactory.setDataSource(embeddedDatabase);
repositoryFactory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase));
repositoryFactory.afterPropertiesSet();
repository = repositoryFactory.getObject();
factory.setJobRepository(repository);

View File

@@ -45,7 +45,7 @@ import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepListener;
import org.springframework.batch.core.listener.SkipListenerSupport;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.factory.FaultTolerantStepFactoryBean;
import org.springframework.batch.core.step.skip.LimitCheckingItemSkipPolicy;
@@ -63,8 +63,10 @@ import org.springframework.batch.item.UnexpectedInputException;
import org.springframework.batch.item.WriteFailedException;
import org.springframework.batch.item.WriterNotOpenException;
import org.springframework.batch.item.support.AbstractItemStreamItemReader;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.lang.Nullable;
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
import org.springframework.test.util.ReflectionTestUtils;
@@ -108,10 +110,17 @@ public class FaultTolerantStepFactoryBeanTests {
@SuppressWarnings("unchecked")
@Before
public void setUp() throws Exception {
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb-extended.sql")
.generateUniqueName(true)
.build();
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(embeddedDatabase);
factory = new FaultTolerantStepFactoryBean<>();
factory.setBeanName("stepName");
factory.setTransactionManager(new ResourcelessTransactionManager());
factory.setTransactionManager(transactionManager);
factory.setCommitInterval(2);
reader.clear();
@@ -127,9 +136,12 @@ public class FaultTolerantStepFactoryBeanTests {
factory
.setSkippableExceptionClasses(getExceptionMap(SkippableException.class, SkippableRuntimeException.class));
MapJobRepositoryFactoryBean repositoryFactory = new MapJobRepositoryFactoryBean();
repositoryFactory.afterPropertiesSet();
repository = repositoryFactory.getObject();
JobRepositoryFactoryBean repositoryFactoryBean = new JobRepositoryFactoryBean();
repositoryFactoryBean.setDataSource(embeddedDatabase);
repositoryFactoryBean.setTransactionManager(transactionManager);
repositoryFactoryBean.setMaxVarCharLength(10000);
repositoryFactoryBean.afterPropertiesSet();
repository = repositoryFactoryBean.getObject();
factory.setJobRepository(repository);
jobExecution = repository.createJobExecution("skipJob", new JobParameters());

View File

@@ -42,10 +42,13 @@ import org.springframework.batch.core.StepListener;
import org.springframework.batch.core.job.SimpleJob;
import org.springframework.batch.core.listener.ItemListenerSupport;
import org.springframework.batch.core.listener.StepListenerSupport;
import org.springframework.batch.core.repository.dao.MapExecutionContextDao;
import org.springframework.batch.core.repository.dao.MapJobExecutionDao;
import org.springframework.batch.core.repository.dao.MapJobInstanceDao;
import org.springframework.batch.core.repository.dao.MapStepExecutionDao;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer;
import org.springframework.batch.core.repository.dao.JdbcExecutionContextDao;
import org.springframework.batch.core.repository.dao.JdbcJobExecutionDao;
import org.springframework.batch.core.repository.dao.JdbcJobInstanceDao;
import org.springframework.batch.core.repository.dao.JdbcStepExecutionDao;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.SimpleJobRepository;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.AbstractStep;
@@ -58,6 +61,12 @@ import org.springframework.batch.repeat.exception.SimpleLimitExceptionHandler;
import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer;
import org.springframework.jdbc.support.incrementer.HsqlSequenceMaxValueIncrementer;
import org.springframework.lang.Nullable;
/**
@@ -67,8 +76,7 @@ public class SimpleStepFactoryBeanTests {
private List<Exception> listened = new ArrayList<>();
private SimpleJobRepository repository = new SimpleJobRepository(new MapJobInstanceDao(), new MapJobExecutionDao(),
new MapStepExecutionDao(), new MapExecutionContextDao());
private JobRepository repository;
private List<String> written = new ArrayList<>();
@@ -85,6 +93,18 @@ public class SimpleStepFactoryBeanTests {
@Before
public void setUp() throws Exception {
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.generateUniqueName(true)
.build();
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(embeddedDatabase);
JobRepositoryFactoryBean repositoryFactoryBean = new JobRepositoryFactoryBean();
repositoryFactoryBean.setDataSource(embeddedDatabase);
repositoryFactoryBean.setTransactionManager(transactionManager);
repositoryFactoryBean.afterPropertiesSet();
repository = repositoryFactoryBean.getObject();
job.setJobRepository(repository);
job.setBeanName("simpleJob");
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2014 the original author or authors.
* Copyright 2006-2021 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.
@@ -29,14 +29,18 @@ import org.springframework.batch.core.UnexpectedJobExecutionException;
import org.springframework.batch.core.job.JobSupport;
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* @author Dave Syer
* @author Mahmoud Ben Hassine
*
*/
public class JobStepTests {
@@ -50,7 +54,14 @@ public class JobStepTests {
@Before
public void setUp() throws Exception {
step.setName("step");
MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(embeddedDatabase);
factory.setTransactionManager(new DataSourceTransactionManager(embeddedDatabase));
factory.afterPropertiesSet();
jobRepository = factory.getObject();
step.setJobRepository(jobRepository);
JobExecution jobExecution = jobRepository.createJobExecution("job", new JobParameters());

View File

@@ -23,7 +23,10 @@ import static org.junit.Assert.assertTrue;
import java.util.List;
import java.util.concurrent.Semaphore;
import javax.sql.DataSource;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
@@ -35,18 +38,19 @@ import org.springframework.batch.core.repository.JobExecutionAlreadyRunningExcep
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.batch.core.repository.dao.MapExecutionContextDao;
import org.springframework.batch.core.repository.dao.MapJobExecutionDao;
import org.springframework.batch.core.repository.dao.MapJobInstanceDao;
import org.springframework.batch.core.repository.dao.MapStepExecutionDao;
import org.springframework.batch.core.repository.support.SimpleJobRepository;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
import org.springframework.batch.repeat.support.RepeatTemplate;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.lang.Nullable;
import org.springframework.transaction.PlatformTransactionManager;
// FIXME This test fails with an embedded database. Need to check if the datasource should be configured with mvcc enabled
@Ignore
public class StepExecutorInterruptionTests {
private TaskletStep step;
@@ -59,10 +63,21 @@ public class StepExecutorInterruptionTests {
private JobRepository jobRepository;
private PlatformTransactionManager transactionManager;
@Before
public void setUp() throws Exception {
jobRepository = new SimpleJobRepository(new MapJobInstanceDao(), new MapJobExecutionDao(),
new MapStepExecutionDao(), new MapExecutionContextDao());
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.generateUniqueName(true)
.build();
this.transactionManager = new DataSourceTransactionManager(embeddedDatabase);
JobRepositoryFactoryBean repositoryFactoryBean = new JobRepositoryFactoryBean();
repositoryFactoryBean.setDataSource(embeddedDatabase);
repositoryFactoryBean.setTransactionManager(this.transactionManager);
repositoryFactoryBean.afterPropertiesSet();
jobRepository = repositoryFactoryBean.getObject();
}
private void configureStep(TaskletStep step) throws JobExecutionAlreadyRunningException, JobRestartException,
@@ -74,7 +89,7 @@ public class StepExecutorInterruptionTests {
job.setBeanName("testJob");
jobExecution = jobRepository.createJobExecution(job.getName(), new JobParameters());
step.setJobRepository(jobRepository);
step.setTransactionManager(new ResourcelessTransactionManager());
step.setTransactionManager(this.transactionManager);
itemWriter = new ItemWriter<Object>() {
@Override
public void write(List<? extends Object> item) throws Exception {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2019 the original author or authors.
* Copyright 2006-2021 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.
@@ -41,10 +41,12 @@ import org.springframework.batch.core.StepExecutionListener;
import org.springframework.batch.core.job.JobSupport;
import org.springframework.batch.core.listener.StepExecutionListenerSupport;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.dao.MapExecutionContextDao;
import org.springframework.batch.core.repository.dao.MapJobExecutionDao;
import org.springframework.batch.core.repository.dao.MapJobInstanceDao;
import org.springframework.batch.core.repository.dao.MapStepExecutionDao;
import org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer;
import org.springframework.batch.core.repository.dao.JdbcExecutionContextDao;
import org.springframework.batch.core.repository.dao.JdbcJobExecutionDao;
import org.springframework.batch.core.repository.dao.JdbcJobInstanceDao;
import org.springframework.batch.core.repository.dao.JdbcStepExecutionDao;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.core.repository.support.SimpleJobRepository;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.JobRepositorySupport;
@@ -63,6 +65,12 @@ import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
import org.springframework.batch.repeat.support.RepeatTemplate;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer;
import org.springframework.jdbc.support.incrementer.HsqlSequenceMaxValueIncrementer;
import org.springframework.lang.Nullable;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
@@ -230,10 +238,18 @@ public class TaskletStepTests {
@Test
public void testRepository() throws Exception {
SimpleJobRepository repository = new SimpleJobRepository(new MapJobInstanceDao(), new MapJobExecutionDao(),
new MapStepExecutionDao(), new MapExecutionContextDao());
EmbeddedDatabase embeddedDatabase = new EmbeddedDatabaseBuilder()
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(embeddedDatabase);
JobRepositoryFactoryBean repositoryFactoryBean = new JobRepositoryFactoryBean();
repositoryFactoryBean.setDataSource(embeddedDatabase);
repositoryFactoryBean.setTransactionManager(transactionManager);
repositoryFactoryBean.afterPropertiesSet();
JobRepository repository = repositoryFactoryBean.getObject();
step.setJobRepository(repository);
step.setTransactionManager(transactionManager);
JobExecution jobExecution = repository.createJobExecution(job.getName(), jobParameters);
StepExecution stepExecution = new StepExecution(step.getName(), jobExecution);

View File

@@ -45,11 +45,13 @@ import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;
import org.springframework.jdbc.datasource.embedded.ConnectionProperties;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseConfigurer;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
@@ -86,6 +88,7 @@ public class ConcurrentTransactionTests {
@Configuration
@EnableBatchProcessing
@Import(DataSourceConfiguration.class)
public static class ConcurrentJobConfiguration extends DefaultBatchConfigurer {
@Autowired
@@ -94,64 +97,15 @@ public class ConcurrentTransactionTests {
@Autowired
private StepBuilderFactory stepBuilderFactory;
public ConcurrentJobConfiguration(DataSource dataSource) {
super(dataSource);
}
@Bean
public TaskExecutor taskExecutor() {
return new SimpleAsyncTaskExecutor();
}
/**
* This datasource configuration configures the HSQLDB instance using MVCC. When
* configured using the default behavior, transaction serialization errors are
* thrown (default configuration example below).
*
* return new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder().
* addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql").
* addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql").
* build());
* @return
*/
@Bean
DataSource dataSource() {
ResourceLoader defaultResourceLoader = new DefaultResourceLoader();
EmbeddedDatabaseFactory embeddedDatabaseFactory = new EmbeddedDatabaseFactory();
embeddedDatabaseFactory.setDatabaseConfigurer(new EmbeddedDatabaseConfigurer() {
@Override
@SuppressWarnings("unchecked")
public void configureConnectionProperties(ConnectionProperties properties, String databaseName) {
try {
properties.setDriverClass((Class<? extends Driver>) ClassUtils.forName("org.hsqldb.jdbcDriver", this.getClass().getClassLoader()));
}
catch (Exception e) {
e.printStackTrace();
}
properties.setUrl("jdbc:hsqldb:mem:" + databaseName + ";hsqldb.tx=mvcc");
properties.setUsername("sa");
properties.setPassword("");
}
@Override
public void shutdown(DataSource dataSource, String databaseName) {
try {
Connection connection = dataSource.getConnection();
Statement stmt = connection.createStatement();
stmt.execute("SHUTDOWN");
}
catch (SQLException ex) {
}
}
});
ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
databasePopulator.addScript(defaultResourceLoader.getResource("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql"));
databasePopulator.addScript(defaultResourceLoader.getResource("classpath:org/springframework/batch/core/schema-hsqldb.sql"));
embeddedDatabaseFactory.setDatabasePopulator(databasePopulator);
embeddedDatabaseFactory.setGenerateUniqueDatabaseName(true);
return embeddedDatabaseFactory.getDatabase();
}
@Bean
public Flow flow() {
return new FlowBuilder<Flow>("flow")
@@ -216,11 +170,67 @@ public class ConcurrentTransactionTests {
@Override
protected JobRepository createJobRepository() throws Exception {
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(dataSource());
factory.setDataSource(getDataSource());
factory.setIsolationLevelForCreate("ISOLATION_READ_COMMITTED");
factory.setTransactionManager(getTransactionManager());
factory.afterPropertiesSet();
return factory.getObject();
}
}
@Configuration
static class DataSourceConfiguration {
/**
* This datasource configuration configures the HSQLDB instance using MVCC. When
* configured using the default behavior, transaction serialization errors are
* thrown (default configuration example below).
*
* return new PooledEmbeddedDataSource(new EmbeddedDatabaseBuilder().
* addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql").
* addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql").
* build());
* @return
*/
@Bean
DataSource dataSource() {
ResourceLoader defaultResourceLoader = new DefaultResourceLoader();
EmbeddedDatabaseFactory embeddedDatabaseFactory = new EmbeddedDatabaseFactory();
embeddedDatabaseFactory.setDatabaseConfigurer(new EmbeddedDatabaseConfigurer() {
@Override
@SuppressWarnings("unchecked")
public void configureConnectionProperties(ConnectionProperties properties, String databaseName) {
try {
properties.setDriverClass((Class<? extends Driver>) ClassUtils.forName("org.hsqldb.jdbcDriver", this.getClass().getClassLoader()));
}
catch (Exception e) {
e.printStackTrace();
}
properties.setUrl("jdbc:hsqldb:mem:" + databaseName + ";hsqldb.tx=mvcc");
properties.setUsername("sa");
properties.setPassword("");
}
@Override
public void shutdown(DataSource dataSource, String databaseName) {
try {
Connection connection = dataSource.getConnection();
Statement stmt = connection.createStatement();
stmt.execute("SHUTDOWN");
}
catch (SQLException ex) {
}
}
});
ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
databasePopulator.addScript(defaultResourceLoader.getResource("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql"));
databasePopulator.addScript(defaultResourceLoader.getResource("classpath:org/springframework/batch/core/schema-hsqldb.sql"));
embeddedDatabaseFactory.setDatabasePopulator(databasePopulator);
embeddedDatabaseFactory.setGenerateUniqueDatabaseName(true);
return embeddedDatabaseFactory.getDatabase();
}
}
}

View File

@@ -1,142 +0,0 @@
/*
* Copyright 2006-2009 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
*
* https://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.core.test.repository;
import static org.junit.Assert.assertEquals;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.Test;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.repository.dao.MapExecutionContextDao;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.Assert;
/**
* @author Dave Syer
*
*/
public class ConcurrentMapExecutionContextDaoTests {
private MapExecutionContextDao dao = new MapExecutionContextDao();
private PlatformTransactionManager transactionManager = new ResourcelessTransactionManager();
@Test
public void testSaveUpdate() throws Exception {
StepExecution stepExecution = new StepExecution("step", new JobExecution(11L));
stepExecution.setId(123L);
stepExecution.getExecutionContext().put("foo", "bar");
dao.saveExecutionContext(stepExecution);
ExecutionContext executionContext = dao.getExecutionContext(stepExecution);
assertEquals("bar", executionContext.get("foo"));
}
@Test
public void testTransactionalSaveUpdate() throws Exception {
final StepExecution stepExecution = new StepExecution("step", new JobExecution(11L));
stepExecution.setId(123L);
new TransactionTemplate(transactionManager).execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus status) {
stepExecution.getExecutionContext().put("foo", "bar");
dao.saveExecutionContext(stepExecution);
return null;
}
});
ExecutionContext executionContext = dao.getExecutionContext(stepExecution);
assertEquals("bar", executionContext.get("foo"));
}
@Test
public void testConcurrentTransactionalSaveUpdate() throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(3);
CompletionService<StepExecution> completionService = new ExecutorCompletionService<>(executor);
final int outerMax = 10;
final int innerMax = 100;
for (int i = 0; i < outerMax; i++) {
final StepExecution stepExecution1 = new StepExecution("step", new JobExecution(11L));
stepExecution1.setId(123L + i);
final StepExecution stepExecution2 = new StepExecution("step", new JobExecution(11L));
stepExecution2.setId(1234L + i);
completionService.submit(new Callable<StepExecution>() {
@Override
public StepExecution call() throws Exception {
for (int i = 0; i < innerMax; i++) {
String value = "bar" + i;
saveAndAssert(stepExecution1, value);
}
return stepExecution1;
}
});
completionService.submit(new Callable<StepExecution>() {
@Override
public StepExecution call() throws Exception {
for (int i = 0; i < innerMax; i++) {
String value = "spam" + i;
saveAndAssert(stepExecution2, value);
}
return stepExecution2;
}
});
completionService.take().get();
completionService.take().get();
}
executor.shutdown();
}
private void saveAndAssert(final StepExecution stepExecution, final String value) {
new TransactionTemplate(transactionManager).execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus status) {
stepExecution.getExecutionContext().put("foo", value);
dao.saveExecutionContext(stepExecution);
return null;
}
});
ExecutionContext executionContext = dao.getExecutionContext(stepExecution);
Assert.state(executionContext != null, "Lost insert: null executionContext at value=" + value);
String foo = executionContext.getString("foo");
Assert.state(value.equals(foo), "Lost update: wrong value=" + value + " (found " + foo + ") for id="
+ stepExecution.getId());
}
}

View File

@@ -1,259 +0,0 @@
/*
* Copyright 2010-2019 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
*
* https://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.core.test.step;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.step.factory.FaultTolerantStepFactoryBean;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.lang.Nullable;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.util.Assert;
import static org.junit.Assert.assertEquals;
/**
* Tests for {@link FaultTolerantStepFactoryBean}.
*/
public class MapRepositoryFaultTolerantStepFactoryBeanRollbackTests {
private static final int MAX_COUNT = 1000;
private final Log logger = LogFactory.getLog(getClass());
private FaultTolerantStepFactoryBean<String, String> factory;
private SkipReaderStub reader;
private SkipProcessorStub processor;
private SkipWriterStub writer;
private JobExecution jobExecution;
private StepExecution stepExecution;
private JobRepository repository;
private PlatformTransactionManager transactionManager = new ResourcelessTransactionManager();
@SuppressWarnings("unchecked")
@Before
public void setUp() throws Exception {
reader = new SkipReaderStub();
writer = new SkipWriterStub();
processor = new SkipProcessorStub();
factory = new FaultTolerantStepFactoryBean<>();
factory.setTransactionManager(transactionManager);
factory.setBeanName("stepName");
factory.setCommitInterval(3);
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(3);
taskExecutor.setMaxPoolSize(6);
taskExecutor.setQueueCapacity(0);
taskExecutor.afterPropertiesSet();
factory.setTaskExecutor(taskExecutor);
factory.setSkipLimit(10);
factory.setSkippableExceptionClasses(getExceptionMap(Exception.class));
}
@Test
public void testUpdatesNoRollback() throws Exception {
writer.write(Arrays.asList("foo", "bar"));
processor.process("spam");
assertEquals(2, writer.getWritten().size());
assertEquals(1, processor.getProcessed().size());
writer.clear();
processor.clear();
assertEquals(0, processor.getProcessed().size());
}
@Test
public void testMultithreadedSkipInWrite() throws Throwable {
for (int i = 0; i < MAX_COUNT; i++) {
if (i%100==0) {
logger.info("Starting step: "+i);
repository = new MapJobRepositoryFactoryBean(transactionManager).getObject();
factory.setJobRepository(repository);
jobExecution = repository.createJobExecution("vanillaJob", new JobParameters());
}
reader.clear();
reader.setItems("1", "2", "3", "4", "5");
factory.setItemReader(reader);
writer.clear();
factory.setItemWriter(writer);
processor.clear();
factory.setItemProcessor(processor);
writer.setFailures("1", "2", "3", "4", "5");
try {
Step step = factory.getObject();
stepExecution = jobExecution.createStepExecution(factory.getName());
repository.add(stepExecution);
step.execute(stepExecution);
assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
assertEquals(5, stepExecution.getSkipCount());
List<String> processed = new ArrayList<>(processor.getProcessed());
Collections.sort(processed);
assertEquals("[1, 1, 2, 2, 3, 3, 4, 4, 5, 5]", processed.toString());
}
catch (Throwable e) {
logger.info("Failed on iteration " + i + " of " + MAX_COUNT);
throw e;
}
}
}
private static class SkipReaderStub implements ItemReader<String> {
private String[] items;
private int counter = -1;
public SkipReaderStub() throws Exception {
super();
}
public void setItems(String... items) {
Assert.isTrue(counter < 0, "Items cannot be set once reading has started");
this.items = items;
}
public void clear() {
counter = -1;
}
@Nullable
@Override
public synchronized String read() throws Exception {
counter++;
if (counter >= items.length) {
return null;
}
return items[counter];
}
}
private static class SkipWriterStub implements ItemWriter<String> {
private final Log logger = LogFactory.getLog(getClass());
private List<String> written = new CopyOnWriteArrayList<>();
private Collection<String> failures = Collections.emptySet();
public void setFailures(String... failures) {
this.failures = Arrays.asList(failures);
}
public List<String> getWritten() {
return written;
}
public void clear() {
written.clear();
}
@Override
public void write(List<? extends String> items) throws Exception {
for (String item : items) {
logger.trace("Writing: "+item);
written.add(item);
checkFailure(item);
}
}
private void checkFailure(String item) {
if (failures.contains(item)) {
throw new RuntimeException("Planned failure");
}
}
}
private static class SkipProcessorStub implements ItemProcessor<String, String> {
private final Log logger = LogFactory.getLog(getClass());
private List<String> processed = new CopyOnWriteArrayList<>();
public List<String> getProcessed() {
return processed;
}
public void clear() {
processed.clear();
}
@Nullable
@Override
public String process(String item) throws Exception {
processed.add(item);
logger.debug("Processed item: "+item);
return item;
}
}
@SuppressWarnings("unchecked")
private Map<Class<? extends Throwable>, Boolean> getExceptionMap(Class<? extends Throwable>... args) {
Map<Class<? extends Throwable>, Boolean> map = new HashMap<>();
for (Class<? extends Throwable> arg : args) {
map.put(arg, true);
}
return map;
}
}

View File

@@ -1,240 +0,0 @@
/*
* Copyright 2010-2019 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
*
* https://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.core.test.step;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.step.factory.FaultTolerantStepFactoryBean;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.lang.Nullable;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.util.Assert;
/**
* Tests for {@link FaultTolerantStepFactoryBean}.
*/
public class MapRepositoryFaultTolerantStepFactoryBeanTests {
private static final int MAX_COUNT = 1000;
private final Log logger = LogFactory.getLog(getClass());
private FaultTolerantStepFactoryBean<String, String> factory;
private SkipReaderStub reader;
private SkipProcessorStub processor;
private SkipWriterStub writer;
private JobExecution jobExecution;
private StepExecution stepExecution;
private JobRepository repository;
private PlatformTransactionManager transactionManager = new ResourcelessTransactionManager();
@Before
public void setUp() throws Exception {
reader = new SkipReaderStub();
writer = new SkipWriterStub();
processor = new SkipProcessorStub();
factory = new FaultTolerantStepFactoryBean<>();
factory.setBeanName("stepName");
factory.setTransactionManager(transactionManager);
factory.setCommitInterval(3);
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(3);
taskExecutor.setMaxPoolSize(6);
taskExecutor.setQueueCapacity(0);
taskExecutor.afterPropertiesSet();
factory.setTaskExecutor(taskExecutor);
}
@Test
public void testUpdatesNoRollback() throws Exception {
writer.write(Arrays.asList("foo", "bar"));
processor.process("spam");
assertEquals(2, writer.getWritten().size());
assertEquals(1, processor.getProcessed().size());
writer.clear();
processor.clear();
assertEquals(0, processor.getProcessed().size());
}
@Test
public void testMultithreadedSunnyDay() throws Throwable {
for (int i = 0; i < MAX_COUNT; i++) {
if (i%100==0) {
logger.info("Starting step: "+i);
repository = new MapJobRepositoryFactoryBean(transactionManager).getObject();
factory.setJobRepository(repository);
jobExecution = repository.createJobExecution("vanillaJob", new JobParameters());
}
reader.clear();
reader.setItems("1", "2", "3", "4", "5");
factory.setItemReader(reader);
writer.clear();
factory.setItemWriter(writer);
processor.clear();
factory.setItemProcessor(processor);
try {
Step step = factory.getObject();
stepExecution = jobExecution.createStepExecution(factory.getName());
repository.add(stepExecution);
step.execute(stepExecution);
assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
List<String> committed = new ArrayList<>(writer.getWritten());
Collections.sort(committed);
assertEquals("[1, 2, 3, 4, 5]", committed.toString());
List<String> processed = new ArrayList<>(processor.getProcessed());
Collections.sort(processed);
assertEquals("[1, 2, 3, 4, 5]", processed.toString());
assertEquals(0, stepExecution.getSkipCount());
}
catch (Throwable e) {
logger.info("Failed on iteration " + i + " of " + MAX_COUNT);
throw e;
}
}
}
private static class SkipReaderStub implements ItemReader<String> {
private String[] items;
private int counter = -1;
public SkipReaderStub() throws Exception {
super();
}
public void setItems(String... items) {
Assert.isTrue(counter < 0, "Items cannot be set once reading has started");
this.items = items;
}
public void clear() {
counter = -1;
}
@Nullable
@Override
public synchronized String read() throws Exception, UnexpectedInputException, ParseException {
counter++;
if (counter >= items.length) {
return null;
}
String item = items[counter];
return item;
}
}
private static class SkipWriterStub implements ItemWriter<String> {
private List<String> written = new CopyOnWriteArrayList<>();
private Collection<String> failures = Collections.emptySet();
public List<String> getWritten() {
return written;
}
public void clear() {
written.clear();
}
@Override
public void write(List<? extends String> items) throws Exception {
for (String item : items) {
written.add(item);
checkFailure(item);
}
}
private void checkFailure(String item) {
if (failures.contains(item)) {
throw new RuntimeException("Planned failure");
}
}
}
private static class SkipProcessorStub implements ItemProcessor<String, String> {
private final Log logger = LogFactory.getLog(getClass());
private List<String> processed = new CopyOnWriteArrayList<>();
public List<String> getProcessed() {
return processed;
}
public void clear() {
processed.clear();
}
@Nullable
@Override
public String process(String item) throws Exception {
processed.add(item);
logger.debug("Processed item: "+item);
return item;
}
}
}

View File

@@ -1,101 +0,0 @@
/*
* Copyright 2006-2021 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
*
* https://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.core.test.step;
import static org.junit.Assert.assertEquals;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.lang.Nullable;
/**
* @author Dave Syer
*
*/
public class SplitJobMapRepositoryIntegrationTests {
private static final int MAX_COUNT = 1000;
/** Logger */
private final Log logger = LogFactory.getLog(getClass());
@SuppressWarnings("resource")
@Test
public void testMultithreadedSplit() throws Throwable {
JobLauncher jobLauncher = null;
Job job = null;
ClassPathXmlApplicationContext context = null;
for (int i = 0; i < MAX_COUNT; i++) {
if (i % 100 == 0) {
if (context!=null) {
context.close();
}
logger.info("Starting job: " + i);
context = new ClassPathXmlApplicationContext(getClass().getSimpleName()
+ "-context.xml", getClass());
jobLauncher = context.getBean("jobLauncher", JobLauncher.class);
job = context.getBean("job", Job.class);
}
try {
JobExecution execution = jobLauncher.run(job, new JobParametersBuilder().addLong("count", (long) i)
.toJobParameters());
assertEquals(BatchStatus.COMPLETED, execution.getStatus());
}
catch (Throwable e) {
logger.info("Failed on iteration " + i + " of " + MAX_COUNT);
throw e;
}
}
}
public static class CountingTasklet implements Tasklet {
private int maxCount = 10;
private AtomicInteger count = new AtomicInteger(0);
@Nullable
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
contribution.incrementReadCount();
contribution.incrementWriteCount(1);
return RepeatStatus.continueIf(count.incrementAndGet() < maxCount);
}
}
}