package javaconfigftw.batch;
import javaconfigftw.Customer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.sql.Driver;
@Configuration
@EnableBatchProcessing(modular = true)
@ComponentScan
@PropertySource("classpath:/services.properties")
public class BatchConfiguration {
private static final String readCsvFileIntoTableStep = "readCsvFileIntoTableStep";
private static final String readCsvFileIntoTableStepReader = readCsvFileIntoTableStep + "Reader";
private static final String readCsvFileIntoTableStepWriter = readCsvFileIntoTableStep + "Writer";
private static final String readCsvFileIntoTableStepProcessor = readCsvFileIntoTableStep + "Processor";
private static final String customerLoaderJob = "customerLoaderJob";
private Log log = LogFactory.getLog(getClass());
@Bean
public TaskScheduler taskScheduler() {
return new ConcurrentTaskScheduler();
}
@Bean
public PlatformTransactionManager transactionManager(DataSource ds) {
return new DataSourceTransactionManager(ds);
}
@Bean
public DataSource dataSource(Environment environment) {
String pw = environment.getProperty("dataSource.password"),
user = environment.getProperty("dataSource.user"),
url = environment.getProperty("dataSource.url");
Class<Driver> classOfDs = environment.getPropertyAsClass("dataSource.driverClass", Driver.class);
SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
dataSource.setPassword(pw);
dataSource.setUrl(url);
dataSource.setUsername(user);
dataSource.setDriverClass(classOfDs);
return dataSource;
}
/**
* maps CSV data into rows of fields, which are then
* mapped to Customer.class instances based on conventions:
* <p/>
* <CODE>col 1 => firstName => customer.setFirstName(String)</CODE>
*/
@Bean(name = readCsvFileIntoTableStepReader)
@StepScope
public FlatFileItemReader<Customer> reader(@Value("#{jobParameters['input.file']}") Resource resource) throws Exception {
log.debug(String.format("building FlatFileItemReader to read in the file %s", resource.getFile().getAbsolutePath()));
FlatFileItemReader<Customer> csvFileReader = new FlatFileItemReader<Customer>();
csvFileReader.setResource(resource);
DelimitedLineTokenizer delimitedLineTokenizer = new DelimitedLineTokenizer(DelimitedLineTokenizer.DELIMITER_COMMA);
delimitedLineTokenizer.setNames(new String[]{"lastName", "firstName"});
BeanWrapperFieldSetMapper<Customer> beanWrapperFieldSetMapper = new BeanWrapperFieldSetMapper<Customer>();
beanWrapperFieldSetMapper.setTargetType(Customer.class);
DefaultLineMapper<Customer> defaultLineMapper = new DefaultLineMapper<Customer>();
defaultLineMapper.setLineTokenizer(delimitedLineTokenizer);
defaultLineMapper.setFieldSetMapper(beanWrapperFieldSetMapper);
csvFileReader.setLineMapper(defaultLineMapper);
return csvFileReader;
}
@Bean(name = readCsvFileIntoTableStepProcessor)
public ItemProcessor<Customer, Customer> processor() {
return new ItemProcessor<Customer, Customer>() {
@Override
public Customer process(Customer item) throws Exception {
log.debug(String.format("processing the customer %s", item.toString()));
return item;
}
};
}
@Bean(name = readCsvFileIntoTableStepWriter)
public JdbcBatchItemWriter<Customer> writer(DataSource dataSource) throws Exception {
JdbcBatchItemWriter<Customer> jdbcBatchItemWriter = new JdbcBatchItemWriter<Customer>();
jdbcBatchItemWriter.setAssertUpdates(true);
jdbcBatchItemWriter.setDataSource(dataSource);
jdbcBatchItemWriter.setSql(" INSERT INTO customer( first_name, last_name) VALUES ( :firstName , :lastName ) ");
jdbcBatchItemWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<Customer>());
return jdbcBatchItemWriter;
}
@Bean
public Job customerLoaderJob(JobBuilderFactory jobs, @Qualifier(readCsvFileIntoTableStep) Step s1) {
return jobs.get(customerLoaderJob)
.flow(s1)
.end()
.build();
}
@Bean(name = readCsvFileIntoTableStep)
public Step readCsvFileIntoTableStep(
StepBuilderFactory stepBuilderFactory,
PlatformTransactionManager platformTransactionManager,
@Qualifier(readCsvFileIntoTableStepReader) ItemReader<Customer> ir,
@Qualifier(readCsvFileIntoTableStepProcessor) ItemProcessor<Customer, Customer> itemProcessor,
@Qualifier(readCsvFileIntoTableStepWriter) ItemWriter<Customer> iw) {
StepBuilder builder = stepBuilderFactory.get(readCsvFileIntoTableStep);
return builder.<Customer, Customer>chunk(3)
.reader(ir)
.processor(itemProcessor)
.writer(iw)
.transactionManager(platformTransactionManager)
.build();
}
}