Commit 52bb45fe authored by Ravinder Pannala's avatar Ravinder Pannala

Initial commit

parent 6a8edb69
# Spring-boot-batch
# spring-batch-example
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.javatechie</groupId>
<artifactId>batch-processing-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>batch-processing-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
package com.javatechie.spring.batch;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
public class BatchProcessingDemoApplication {
public static void main(String[] args) {
SpringApplication.run(BatchProcessingDemoApplication.class, args);
}
}
package com.javatechie.spring.batch.config;
import com.javatechie.spring.batch.entity.Customer;
import org.springframework.batch.item.ItemProcessor;
public class CustomerProcessor implements ItemProcessor<Customer,Customer> {
@Override
public Customer process(Customer customer) throws Exception {
return customer;
}
}
package com.javatechie.spring.batch.config;
import com.javatechie.spring.batch.entity.Customer;
import com.javatechie.spring.batch.repository.CustomerRepository;
import lombok.AllArgsConstructor;
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.item.data.RepositoryItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.LineMapper;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;
@Configuration
@EnableBatchProcessing
@AllArgsConstructor
public class SpringBatchConfig {
private JobBuilderFactory jobBuilderFactory;
private StepBuilderFactory stepBuilderFactory;
private CustomerRepository customerRepository;
@Bean
public FlatFileItemReader<Customer> reader() {
FlatFileItemReader<Customer> itemReader = new FlatFileItemReader<>();
itemReader.setResource(new FileSystemResource("src/main/resources/customers.csv"));
itemReader.setName("csvReader");
itemReader.setLinesToSkip(1);
itemReader.setLineMapper(lineMapper());
return itemReader;
}
private LineMapper<Customer> lineMapper() {
DefaultLineMapper<Customer> lineMapper = new DefaultLineMapper<>();
DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();
lineTokenizer.setDelimiter(",");
lineTokenizer.setStrict(false);
lineTokenizer.setNames("id", "firstName", "lastName", "email", "gender", "contactNo", "country", "dob");
BeanWrapperFieldSetMapper<Customer> fieldSetMapper = new BeanWrapperFieldSetMapper<>();
fieldSetMapper.setTargetType(Customer.class);
lineMapper.setLineTokenizer(lineTokenizer);
lineMapper.setFieldSetMapper(fieldSetMapper);
return lineMapper;
}
@Bean
public CustomerProcessor processor() {
return new CustomerProcessor();
}
@Bean
public RepositoryItemWriter<Customer> writer() {
RepositoryItemWriter<Customer> writer = new RepositoryItemWriter<>();
writer.setRepository(customerRepository);
writer.setMethodName("save");
return writer;
}
@Bean
public Step step1() {
return stepBuilderFactory.get("csv-step").<Customer, Customer>chunk(10)
.reader(reader())
.processor(processor())
.writer(writer())
.taskExecutor(taskExecutor())
.build();
}
@Bean(name = "runJob")
public Job runJob() {
return jobBuilderFactory.get("importCustomers")
.flow(step1())
.end().build();
}
@Bean
public TaskExecutor taskExecutor() {
SimpleAsyncTaskExecutor asyncTaskExecutor = new SimpleAsyncTaskExecutor();
asyncTaskExecutor.setConcurrencyLimit(10);
return asyncTaskExecutor;
}
}
package com.javatechie.spring.batch.config;
import com.javatechie.spring.batch.entity.Customer;
import com.javatechie.spring.batch.repository.CustomerRepository;
import lombok.AllArgsConstructor;
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.launch.support.RunIdIncrementer;
import org.springframework.batch.item.data.RepositoryItemReader;
import org.springframework.batch.item.data.RepositoryItemWriter;
import org.springframework.batch.item.database.JdbcCursorItemReader;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor;
import org.springframework.batch.item.file.transform.DelimitedLineAggregator;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;
import org.springframework.data.domain.Sort;
import javax.sql.DataSource;
import java.util.HashMap;
@Configuration
@EnableBatchProcessing
@AllArgsConstructor
public class SpringBatchReadConfig {
private JobBuilderFactory jobBuilderFactory;
private StepBuilderFactory stepBuilderFactory;
private CustomerRepository customerRepository;
@Bean
public RepositoryItemReader<Customer> repositoryReader() {
RepositoryItemReader<Customer> itemReader = new RepositoryItemReader();
itemReader.setRepository(customerRepository);
itemReader.setMethodName("findAll");
HashMap<String, Sort.Direction> sorts = new HashMap<>();
sorts.put("id", Sort.Direction.DESC);
itemReader.setSort(sorts);
return itemReader;
}
@Bean
public CustomerProcessor customerProcessor() {
return new CustomerProcessor();
}
@Bean
public FlatFileItemWriter<Customer> csvWriter() {
FlatFileItemWriter<Customer> flatFileItemWriter = new FlatFileItemWriter<>();
flatFileItemWriter.setResource(new FileSystemResource("src/main/resources/customersResult.csv"));
DelimitedLineAggregator<Customer> lineAggregator = new DelimitedLineAggregator();
lineAggregator.setDelimiter(",");
BeanWrapperFieldExtractor<Customer> fieldSetMapper = new BeanWrapperFieldExtractor<>();
fieldSetMapper.setNames(new String[]{"id", "firstName", "lastName", "email", "gender", "contactNo", "country", "dob"});
lineAggregator.setFieldExtractor(fieldSetMapper);
flatFileItemWriter.setLineAggregator(lineAggregator);
return flatFileItemWriter;
}
//@Bean
public Step exportStep1() {
return stepBuilderFactory.get("db-step").<Customer, Customer>chunk(10)
.reader(repositoryReader())
.processor(customerProcessor())
.writer(csvWriter())
.taskExecutor(readTaskExecutor())
.build();
}
@Bean(name = "exportCustomerJob")
public Job exportCustomerJob() {
return jobBuilderFactory.get("getCustomers")
.incrementer(new RunIdIncrementer())
.flow(exportStep1())
.end()
.build();
}
@Bean
public TaskExecutor readTaskExecutor() {
SimpleAsyncTaskExecutor asyncTaskExecutor = new SimpleAsyncTaskExecutor();
asyncTaskExecutor.setConcurrencyLimit(10);
return asyncTaskExecutor;
}
}
package com.javatechie.spring.batch.controller;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/jobs")
public class JobController {
@Autowired
private JobLauncher jobLauncher;
@Autowired
@Qualifier("runJob")
private Job runJob;
@Autowired
@Qualifier("exportCustomerJob")
private Job exportCustomerJob;
@PostMapping("/importCustomers")
public void importCsvToDBJob() {
JobParameters jobParameters = new JobParametersBuilder()
.addLong("startAt", System.currentTimeMillis()).toJobParameters();
try {
jobLauncher.run(runJob, jobParameters);
} catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException |
JobParametersInvalidException e) {
e.printStackTrace();
}
}
@GetMapping("/getCustomers")
public void importDBToCsvJob() {
JobParameters jobParameters = new JobParametersBuilder().addLong("startAt", System.currentTimeMillis()).toJobParameters();
try {
jobLauncher.run(exportCustomerJob, jobParameters);
} catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException |
JobParametersInvalidException e) {
e.printStackTrace();
}
}
}
package com.javatechie.spring.batch.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "CUSTOMERS_INFO")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Customer {
@Id
@Column(name = "CUSTOMER_ID")
private int id;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "LAST_NAME")
private String lastName;
@Column(name = "EMAIL")
private String email;
@Column(name = "GENDER")
private String gender;
@Column(name = "CONTACT")
private String contactNo;
@Column(name = "COUNTRY")
private String country;
@Column(name = "DOB")
private String dob;
}
package com.javatechie.spring.batch.repository;
import com.javatechie.spring.batch.entity.Customer;
import org.springframework.data.jpa.repository.JpaRepository;
public interface CustomerRepository extends JpaRepository<Customer,Integer> {
}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/customer
spring.datasource.username = root
spring.datasource.password = Welcome@2023
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
server.port=9191
spring.batch.initialize-schema=ALWAYS
#disabled job run at startup
spring.batch.job.enabled=false
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
package com.javatechie.spring.batch;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class BatchProcessingDemoApplicationTests {
@Test
void contextLoads() {
}
}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/customer
spring.datasource.username = root
spring.datasource.password = Welcome@2023
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
server.port=9191
spring.batch.initialize-schema=ALWAYS
#disabled job run at startup
spring.batch.job.enabled=false
\ No newline at end of file
This diff is collapsed.
884,Olivie,Corris,ocorrisoj@bizjournals.com,Agender,772-941-0693,United States,20-10-1998
779,Francklyn,Huttley,fhuttleylm@artisteer.com,Male,570-232-1012,United States,25-06-2004
778,Joby,Bagniuk,jbagniukll@unc.edu,Female,831-593-4853,United States,14-07-2002
719,Shaylah,Trammel,strammeljy@chron.com,Female,502-383-3657,United States,11-07-1992
549,Maurie,Ciccetti,mciccettif8@washington.edu,Male,901-826-5444,United States,13-10-2004
508,Lisle,Olliar,lolliare3@disqus.com,Male,573-613-4047,United States,22-12-2013
452,Florinda,Denacamp,fdenacampcj@hibu.com,Female,913-664-5808,United States,20-01-2010
415,Thaxter,Sisnett,tsisnettbi@hp.com,Male,775-840-7859,United States,01-12-2016
389,Linc,Godridge,lgodridgeas@hc360.com,Male,406-962-4087,United States,18-10-2009
352,Rafaello,Rouchy,rrouchy9r@hhs.gov,Bigender,325-868-4484,United States,27-02-1995
859,Lianne,Scampion,lscampionnu@oaic.gov.au,Female,757-620-9267,United States,02-12-2001
283,Torrence,Guillard,tguillard7u@acquirethisname.com,Male,865-411-1598,United States,31-10-2009
252,Bertram,Albrooke,balbrooke6z@printfriendly.com,Male,240-660-9166,United States,08-02-2004
251,Cly,Durnan,cdurnan6y@imgur.com,Male,214-743-7019,United States,29-06-1999
188,Enriqueta,Costi,ecosti57@timesonline.co.uk,Female,616-217-3402,United States,10-04-1996
153,Zita,Duiguid,zduiguid48@yahoo.co.jp,Female,408-208-1473,United States,16-10-2003
82,Ewan,Crosland,ecrosland29@cloudflare.com,Male,562-453-2275,United States,19-09-2021
2,Jolyn,Bragg,jbragg1@go.com,Genderqueer,614-319-7266,United States,18-09-2003
307,Otes,Hammonds,ohammonds8i@networkadvertising.org,Male,318-309-4799,United States,21-03-2011
799,Celia,Matchett,cmatchettm6@usda.gov,Female,402-498-3239,United States,20-06-1999
723,Adore,Spratt,asprattk2@time.com,Female,915-400-2965,United States,07-10-1991
661,Rochelle,Creeboe,rcreeboeic@paypal.com,Genderfluid,432-697-6300,United States,10-06-1992
533,Mohandas,Collis,mcollises@pbs.org,Male,513-929-5651,United States,05-12-2007
98,Durand,Perell,dperell2p@unc.edu,Male,970-528-2511,United States,14-11-1997
38,Demetris,Golby,dgolby11@privacy.gov.au,Female,323-136-0870,United States,13-12-1991
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment