From 7716554ac71064204e30ac3c8b700e7eab31f9a2 Mon Sep 17 00:00:00 2001 From: NAVEEN <68312849+engineerscodes@users.noreply.github.com> Date: Wed, 19 Nov 2025 23:50:59 +0530 Subject: [PATCH 1/2] Delete SpringBatch directory --- SpringBatch/pom.xml | 135 ------------------ .../main/java/org/example/Application.java | 13 -- .../java/org/example/Config/BatchConfig.java | 103 ------------- .../example/component/TimeoutListener.java | 19 --- .../java/org/example/controller/Batch.java | 43 ------ .../service/ExternalReactiveService.java | 14 -- .../src/main/resources/application.properties | 16 --- 7 files changed, 343 deletions(-) delete mode 100644 SpringBatch/pom.xml delete mode 100644 SpringBatch/src/main/java/org/example/Application.java delete mode 100644 SpringBatch/src/main/java/org/example/Config/BatchConfig.java delete mode 100644 SpringBatch/src/main/java/org/example/component/TimeoutListener.java delete mode 100644 SpringBatch/src/main/java/org/example/controller/Batch.java delete mode 100644 SpringBatch/src/main/java/org/example/service/ExternalReactiveService.java delete mode 100644 SpringBatch/src/main/resources/application.properties diff --git a/SpringBatch/pom.xml b/SpringBatch/pom.xml deleted file mode 100644 index 32b83c4..0000000 --- a/SpringBatch/pom.xml +++ /dev/null @@ -1,135 +0,0 @@ - - - 4.0.0 - - org.example - SpringBatch - 1.0-SNAPSHOT - - - 21 - 21 - 1.5.5.Final - - - - org.springframework.boot - spring-boot-starter-parent - 3.5.4 - - - - - org.springframework.boot - spring-boot-starter-web - - - - org.springframework.boot - spring-boot-starter-batch - - - - org.projectlombok - lombok - provided - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - - org.mapstruct - mapstruct - ${org.mapstruct.version} - - - - org.postgresql - postgresql - runtime - - - - - org.springframework.boot - spring-boot-starter-actuator - - - - jakarta.validation - jakarta.validation-api - - - - org.springframework.boot - spring-boot-starter-validation - - - - org.springframework.cloud - spring-cloud-starter-circuitbreaker-reactor-resilience4j - 3.3.0 - - - - io.github.resilience4j - resilience4j-bulkhead - 2.2.0 - - - - org.springframework.boot - spring-boot-starter-webflux - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - org.projectlombok - lombok - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - ${java.version} - ${java.version} - ${project.build.sourceEncoding} - - - org.projectlombok - lombok - ${lombok.version} - - - org.mapstruct - mapstruct-processor - ${org.mapstruct.version} - - - - - - - - - \ No newline at end of file diff --git a/SpringBatch/src/main/java/org/example/Application.java b/SpringBatch/src/main/java/org/example/Application.java deleted file mode 100644 index c8c47d9..0000000 --- a/SpringBatch/src/main/java/org/example/Application.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.example; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - -} diff --git a/SpringBatch/src/main/java/org/example/Config/BatchConfig.java b/SpringBatch/src/main/java/org/example/Config/BatchConfig.java deleted file mode 100644 index 39a5af4..0000000 --- a/SpringBatch/src/main/java/org/example/Config/BatchConfig.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.example.Config; - -import io.github.resilience4j.bulkhead.BulkheadConfig; -import io.github.resilience4j.bulkhead.ThreadPoolBulkheadConfig; -import io.github.resilience4j.bulkhead.annotation.Bulkhead; -import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; -import io.github.resilience4j.timelimiter.TimeLimiterConfig; -import org.example.component.TimeoutListener; -import org.springframework.batch.core.*; -import org.springframework.batch.core.configuration.annotation.*; -import org.springframework.batch.core.job.builder.*; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.batch.core.launch.support.*; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; -import org.springframework.batch.core.step.builder.*; -import org.springframework.batch.repeat.RepeatStatus; -import org.springframework.cloud.circuitbreaker.resilience4j.ReactiveResilience4jBulkheadProvider; -import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JCircuitBreakerFactory; -import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JConfigBuilder; -import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4jBulkheadProvider; -import org.springframework.cloud.client.circuitbreaker.Customizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.annotation.EnableTransactionManagement; -import javax.sql.DataSource; -import java.time.Duration; - -@Configuration -@EnableBatchProcessing -@EnableTransactionManagement -public class BatchConfig { - - @Bean - public Job demoJob(JobRepository jobRepository, Step demoStep) { - return new JobBuilder("demoJob", jobRepository) - .listener(new TimeoutListener()) - .start(demoStep) - .build(); - } - - @Bean - public Step demoStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) { - return new StepBuilder("demoStep", jobRepository) - .tasklet((contribution, chunkContext) -> { - for(int i=0; i<5000; i++) { - System.out.println("Processing step " + (i + 1) + "/5"); - Thread.sleep(1000); // Simulate work - } - System.out.println(">>> Running batch job with REST trigger <<<"); - return RepeatStatus.FINISHED; - }, transactionManager).allowStartIfComplete(true) - .build(); - } - - @Bean - public JobRepository jobRepository(DataSource dataSource, PlatformTransactionManager transactionManager) throws Exception { - JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); - factory.setDataSource(dataSource); - factory.setTransactionManager(transactionManager); - factory.afterPropertiesSet(); - return factory.getObject(); - } - - @Bean - public JobLauncher jobLauncher(JobRepository jobRepository) throws Exception { - TaskExecutorJobLauncher jobLauncher = new TaskExecutorJobLauncher(); - jobLauncher.setJobRepository(jobRepository); - - ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); - executor.setCorePoolSize(2); - executor.setMaxPoolSize(2); - executor.setQueueCapacity(2); - executor.setThreadNamePrefix("batch-job-"); - executor.initialize(); - - jobLauncher.setTaskExecutor(executor); - jobLauncher.afterPropertiesSet(); - return jobLauncher; - } - - @Bean - public Customizer defaultCustomizer() { - return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id) - .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(4)).build()) - .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults()) - .build()); - } - - @Bean - public Customizer reactiveSpecificBulkheadCustomizer() { - return provider -> provider.configure(builder -> { - builder.bulkheadConfig(BulkheadConfig.custom() - .maxConcurrentCalls(2) - .build()); - }, "serviceBulkhead"); - } - - - -} diff --git a/SpringBatch/src/main/java/org/example/component/TimeoutListener.java b/SpringBatch/src/main/java/org/example/component/TimeoutListener.java deleted file mode 100644 index 60d152d..0000000 --- a/SpringBatch/src/main/java/org/example/component/TimeoutListener.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.example.component; - -import org.springframework.batch.core.JobExecution; -import org.springframework.batch.core.JobExecutionListener; -import org.springframework.stereotype.Component; - -@Component -public class TimeoutListener implements JobExecutionListener { - - @Override - public void beforeJob(JobExecution jobExecution) { - System.out.println("Job is starting..."); - } - - @Override - public void afterJob(JobExecution jobExecution) { - System.out.println("Job has ended."); - } -} \ No newline at end of file diff --git a/SpringBatch/src/main/java/org/example/controller/Batch.java b/SpringBatch/src/main/java/org/example/controller/Batch.java deleted file mode 100644 index c9f2360..0000000 --- a/SpringBatch/src/main/java/org/example/controller/Batch.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.example.controller; - - -import lombok.extern.slf4j.Slf4j; -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.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; - -@Slf4j -@Controller -public class Batch { - - - @Autowired - private JobLauncher jobLauncher; - - - @Autowired - private Job demoJob; - - - - @GetMapping("/batch") - private ResponseEntity signUp() throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException { - JobParameters params = new JobParametersBuilder() - .addLocalDateTime("date", java.time.LocalDateTime.now()) - .toJobParameters(); - jobLauncher.run(demoJob, params); - log.info("==============================="); - return ResponseEntity.ok("Hello World"); - } - - -} diff --git a/SpringBatch/src/main/java/org/example/service/ExternalReactiveService.java b/SpringBatch/src/main/java/org/example/service/ExternalReactiveService.java deleted file mode 100644 index 6d695ae..0000000 --- a/SpringBatch/src/main/java/org/example/service/ExternalReactiveService.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.example.service; - -import org.springframework.web.reactive.function.client.WebClient; -import io.github.resilience4j.bulkhead.annotation.Bulkhead; -import org.springframework.stereotype.Service; -import reactor.core.publisher.Mono; - -@Service -public class ExternalReactiveService { - @Bulkhead(name = "serviceBulkhead", type = Bulkhead.Type.THREADPOOL) - public Mono fetchData() { - return WebClient.create().get().uri("https://example.com").retrieve().bodyToMono(String.class); - } -} \ No newline at end of file diff --git a/SpringBatch/src/main/resources/application.properties b/SpringBatch/src/main/resources/application.properties deleted file mode 100644 index 1ae0bf4..0000000 --- a/SpringBatch/src/main/resources/application.properties +++ /dev/null @@ -1,16 +0,0 @@ -## Spring JPA -spring.datasource.url=jdbc:postgresql://localhost:5432/postgres -spring.datasource.username=postgres -spring.datasource.password=naveen -spring.jpa.hibernate.ddl-auto=none -spring.jpa.show-sql=true -spring.jpa.properties.hibernate.format_sql=false -hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect -spring.servlet.multipart.enabled=true -spring.servlet.multipart.max-file-size=50MB -spring.servlet.multipart.max-request-size=60MB -spring.output.ansi.enabled=ALWAYS -management.endpoint.metrics.enabled=true -management.endpoints.prometheus.enabled=true -management.endpoints.web.exposure.include=* -spring.batch.jdbc.initialize-schema=never From 803ed5567b09d323a3c0ff1ab4a701daec2c4b7f Mon Sep 17 00:00:00 2001 From: NAVEEN <68312849+engineerscodes@users.noreply.github.com> Date: Thu, 20 Nov 2025 00:09:48 +0530 Subject: [PATCH 2/2] AI Trash --- SpringBatch/pom.xml | 135 ++++++++++++ .../main/java/org/example/Application.java | 13 ++ .../java/org/example/Config/BatchConfig.java | 198 ++++++++++++++++++ .../java/org/example/Config/MyCustomData.java | 14 ++ .../example/component/TimeoutListener.java | 19 ++ .../java/org/example/controller/Batch.java | 57 +++++ .../main/java/org/example/dto/PersonDTO.java | 13 ++ .../service/ExternalReactiveService.java | 91 ++++++++ .../src/main/resources/application.properties | 16 ++ .../target/classes/application.properties | 16 ++ .../classes/org/example/Application.class | Bin 0 -> 711 bytes .../org/example/Config/BatchConfig.class | Bin 0 -> 17300 bytes .../org/example/Config/MyCustomData.class | Bin 0 -> 2319 bytes .../example/component/TimeoutListener.class | Bin 0 -> 969 bytes .../org/example/controller/Batch.class | Bin 0 -> 3495 bytes .../classes/org/example/dto/PersonDTO.class | Bin 0 -> 2536 bytes .../service/ExternalReactiveService.class | Bin 0 -> 10485 bytes 17 files changed, 572 insertions(+) create mode 100644 SpringBatch/pom.xml create mode 100644 SpringBatch/src/main/java/org/example/Application.java create mode 100644 SpringBatch/src/main/java/org/example/Config/BatchConfig.java create mode 100644 SpringBatch/src/main/java/org/example/Config/MyCustomData.java create mode 100644 SpringBatch/src/main/java/org/example/component/TimeoutListener.java create mode 100644 SpringBatch/src/main/java/org/example/controller/Batch.java create mode 100644 SpringBatch/src/main/java/org/example/dto/PersonDTO.java create mode 100644 SpringBatch/src/main/java/org/example/service/ExternalReactiveService.java create mode 100644 SpringBatch/src/main/resources/application.properties create mode 100644 SpringBatch/target/classes/application.properties create mode 100644 SpringBatch/target/classes/org/example/Application.class create mode 100644 SpringBatch/target/classes/org/example/Config/BatchConfig.class create mode 100644 SpringBatch/target/classes/org/example/Config/MyCustomData.class create mode 100644 SpringBatch/target/classes/org/example/component/TimeoutListener.class create mode 100644 SpringBatch/target/classes/org/example/controller/Batch.class create mode 100644 SpringBatch/target/classes/org/example/dto/PersonDTO.class create mode 100644 SpringBatch/target/classes/org/example/service/ExternalReactiveService.class diff --git a/SpringBatch/pom.xml b/SpringBatch/pom.xml new file mode 100644 index 0000000..32b83c4 --- /dev/null +++ b/SpringBatch/pom.xml @@ -0,0 +1,135 @@ + + + 4.0.0 + + org.example + SpringBatch + 1.0-SNAPSHOT + + + 21 + 21 + 1.5.5.Final + + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-batch + + + + org.projectlombok + lombok + provided + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.mapstruct + mapstruct + ${org.mapstruct.version} + + + + org.postgresql + postgresql + runtime + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + jakarta.validation + jakarta.validation-api + + + + org.springframework.boot + spring-boot-starter-validation + + + + org.springframework.cloud + spring-cloud-starter-circuitbreaker-reactor-resilience4j + 3.3.0 + + + + io.github.resilience4j + resilience4j-bulkhead + 2.2.0 + + + + org.springframework.boot + spring-boot-starter-webflux + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + org.projectlombok + lombok + ${lombok.version} + + + org.mapstruct + mapstruct-processor + ${org.mapstruct.version} + + + + + + + + + \ No newline at end of file diff --git a/SpringBatch/src/main/java/org/example/Application.java b/SpringBatch/src/main/java/org/example/Application.java new file mode 100644 index 0000000..c8c47d9 --- /dev/null +++ b/SpringBatch/src/main/java/org/example/Application.java @@ -0,0 +1,13 @@ +package org.example; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/SpringBatch/src/main/java/org/example/Config/BatchConfig.java b/SpringBatch/src/main/java/org/example/Config/BatchConfig.java new file mode 100644 index 0000000..14fcdb4 --- /dev/null +++ b/SpringBatch/src/main/java/org/example/Config/BatchConfig.java @@ -0,0 +1,198 @@ +package org.example.Config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.github.resilience4j.bulkhead.BulkheadConfig; +import io.github.resilience4j.bulkhead.ThreadPoolBulkheadConfig; +import io.github.resilience4j.bulkhead.annotation.Bulkhead; +import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; +import io.github.resilience4j.timelimiter.TimeLimiterConfig; +import lombok.Data; +import org.example.component.TimeoutListener; +import org.example.dto.PersonDTO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.batch.core.*; +import org.springframework.batch.core.configuration.annotation.*; +import org.springframework.batch.core.job.builder.*; +import org.springframework.batch.core.job.flow.Flow; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.core.launch.support.*; +import org.springframework.batch.core.repository.ExecutionContextSerializer; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer; +import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; +import org.springframework.batch.core.step.builder.*; +import org.springframework.batch.item.ExecutionContext; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.circuitbreaker.resilience4j.ReactiveResilience4jBulkheadProvider; +import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JCircuitBreakerFactory; +import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JConfigBuilder; +import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4jBulkheadProvider; +import org.springframework.cloud.client.circuitbreaker.Customizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.SimpleAsyncTaskExecutor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; +import javax.sql.DataSource; +import java.io.Serializable; +import java.time.Duration; +import java.util.Objects; + +@Configuration +@EnableBatchProcessing(executionContextSerializerRef = "jacksonSerializer") +@EnableTransactionManagement +public class BatchConfig { + + + private static final Logger log = LoggerFactory.getLogger(BatchConfig.class); + + @Bean + public Job demoJob(JobRepository jobRepository, Step demoStep, Step step1, Step step2, Step step3) { + // Create a flow for step1 followed by step3 + Flow flow1 = new FlowBuilder("flow1") + .start(step1) + .next(step3) + .build(); + + // Create a flow for step2 (runs in parallel with flow1) + Flow flow2 = new FlowBuilder("flow2") + .start(step2) + .build(); + + // Create a split that runs flow1 and flow2 in parallel + Flow parallelFlow = new FlowBuilder("parallelFlow") + .split(new SimpleAsyncTaskExecutor()) + .add(flow1, flow2) + .build(); + + return new JobBuilder("demoJob", jobRepository) + .listener(new TimeoutListener()) + .start(demoStep) + .on("COMPLETED").to(parallelFlow) + .end() + .build(); + } + + @Autowired + private ObjectMapper objectMapper; + + @Bean + public Step demoStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) { + return new StepBuilder("demoStep", jobRepository) + .tasklet((contribution, chunkContext) -> { + StepExecution stepExecution = chunkContext.getStepContext().getStepExecution(); + JobExecution jobExecution = stepExecution.getJobExecution(); + + // Get job parameter person as JSON string + String personJson = jobExecution.getJobParameters().getString("person"); + log.info("Person JSON: {}", personJson); + + // Deserialize JSON to PersonDTO object + PersonDTO personDTO = objectMapper.readValue(personJson, PersonDTO.class); + log.info("Person DTO - Name: {}, Age: {}", personDTO.getName(), personDTO.getAge()); + + ExecutionContext jobContext = jobExecution.getExecutionContext(); + + jobContext.putString("Data", new MyCustomData("LOLLLLL<>" + jobExecution.getId() + ".txt").toString()); + + String earlyData = jobContext.getString("Data"); + log.info("Early Data from Job Execution Context: {}", earlyData); + System.out.println(">>> Running batch job with REST trigger <<<"); + return RepeatStatus.FINISHED; + }, transactionManager).allowStartIfComplete(true) + .build(); + } + + @Bean + public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager, org.example.service.ExternalReactiveService externalReactiveService) { + return new StepBuilder("step1", jobRepository) + .tasklet((contribution, chunkContext) -> { + log.info("Step 1: Fetching data from external source..."); + String result = externalReactiveService.fetchData().block(); + log.info("Step 1 Result: {}", result); + return RepeatStatus.FINISHED; + }, transactionManager) + .build(); + } + + @Bean + public Step step2(JobRepository jobRepository, PlatformTransactionManager transactionManager, org.example.service.ExternalReactiveService externalReactiveService) { + return new StepBuilder("step2", jobRepository) + .tasklet((contribution, chunkContext) -> { + int page = 0; + int size = 100; + log.info("Step 2: Fetching data batch - Page: {}, Size: {}", page, size); + String result = Objects.requireNonNull(externalReactiveService.fetchAllDataFromPath("/api/data/v1", size).collectList().block()).toString(); + log.info("Step 2 Result: {}", result); + return RepeatStatus.FINISHED; + }, transactionManager) + .build(); + } + + @Bean + public Step step3(JobRepository jobRepository, PlatformTransactionManager transactionManager, org.example.service.ExternalReactiveService externalReactiveService) { + return new StepBuilder("step3", jobRepository) + .tasklet((contribution, chunkContext) -> { + int page = 1; + int size = 500; + log.info("Step 3: Fetching data batch - Page: {}, Size: {}", page, size); + String result = Objects.requireNonNull(externalReactiveService.fetchAllDataFromPath("/api/data/v2", size).collectList().block()).toString(); + log.info("Step 3 Result: {}", result); + return RepeatStatus.FINISHED; + }, transactionManager) + .build(); + } + + @Bean + public JobRepository jobRepository(DataSource dataSource, PlatformTransactionManager transactionManager) throws Exception { + JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); + factory.setDataSource(dataSource); + factory.setTransactionManager(transactionManager); + factory.afterPropertiesSet(); + return factory.getObject(); + } + + @Bean + public JobLauncher jobLauncher(JobRepository jobRepository) throws Exception { + TaskExecutorJobLauncher jobLauncher = new TaskExecutorJobLauncher(); + jobLauncher.setJobRepository(jobRepository); + + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(2); + executor.setMaxPoolSize(2); + executor.setQueueCapacity(2); + executor.setThreadNamePrefix("batch-job-"); + executor.initialize(); + + jobLauncher.setTaskExecutor(executor); + jobLauncher.afterPropertiesSet(); + return jobLauncher; + } + + @Bean + public Customizer defaultCustomizer() { + return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id) + .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(4)).build()) + .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults()) + .build()); + } + + @Bean + public Customizer reactiveSpecificBulkheadCustomizer() { + return provider -> provider.configure(builder -> { + builder.bulkheadConfig(BulkheadConfig.custom() + .maxConcurrentCalls(2) + .build()); + }, "serviceBulkhead"); + } + + + @Bean + public ExecutionContextSerializer jacksonSerializer() { + return new Jackson2ExecutionContextStringSerializer(); + } + +} diff --git a/SpringBatch/src/main/java/org/example/Config/MyCustomData.java b/SpringBatch/src/main/java/org/example/Config/MyCustomData.java new file mode 100644 index 0000000..e5e0a6a --- /dev/null +++ b/SpringBatch/src/main/java/org/example/Config/MyCustomData.java @@ -0,0 +1,14 @@ +package org.example.Config; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NonNull; + +import java.io.Serializable; + + +@Data +public class MyCustomData implements Serializable { + @NonNull + private String value; +} \ No newline at end of file diff --git a/SpringBatch/src/main/java/org/example/component/TimeoutListener.java b/SpringBatch/src/main/java/org/example/component/TimeoutListener.java new file mode 100644 index 0000000..60d152d --- /dev/null +++ b/SpringBatch/src/main/java/org/example/component/TimeoutListener.java @@ -0,0 +1,19 @@ +package org.example.component; + +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobExecutionListener; +import org.springframework.stereotype.Component; + +@Component +public class TimeoutListener implements JobExecutionListener { + + @Override + public void beforeJob(JobExecution jobExecution) { + System.out.println("Job is starting..."); + } + + @Override + public void afterJob(JobExecution jobExecution) { + System.out.println("Job has ended."); + } +} \ No newline at end of file diff --git a/SpringBatch/src/main/java/org/example/controller/Batch.java b/SpringBatch/src/main/java/org/example/controller/Batch.java new file mode 100644 index 0000000..a1f1ca4 --- /dev/null +++ b/SpringBatch/src/main/java/org/example/controller/Batch.java @@ -0,0 +1,57 @@ +package org.example.controller; + + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.example.dto.PersonDTO; +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.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Slf4j +@Controller +public class Batch { + + + @Autowired + private JobLauncher jobLauncher; + + + @Autowired + private Job demoJob; + + @Autowired + private ObjectMapper objectMapper; + + + + @GetMapping("/batch") + public ResponseEntity signUp() throws Exception { + // Hardcoded PersonDTO values + PersonDTO personDTO = new PersonDTO("John Doe", 30); + + // Serialize PersonDTO to JSON string + String personJson = objectMapper.writeValueAsString(personDTO); + + JobParameters params = new JobParametersBuilder() + .addLocalDateTime("date", java.time.LocalDateTime.now()) + .addString("name", personDTO.getName()) + .addString("person", personJson) + .toJobParameters(); + jobLauncher.run(demoJob, params); + log.info("==============================="); + log.info("Batch job started with name: {} and age: {}", personDTO.getName(), personDTO.getAge()); + return ResponseEntity.ok("Batch job started for " + personDTO.getName()); + } + + +} diff --git a/SpringBatch/src/main/java/org/example/dto/PersonDTO.java b/SpringBatch/src/main/java/org/example/dto/PersonDTO.java new file mode 100644 index 0000000..38eed10 --- /dev/null +++ b/SpringBatch/src/main/java/org/example/dto/PersonDTO.java @@ -0,0 +1,13 @@ +package org.example.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PersonDTO { + private String name; + private Integer age; +} diff --git a/SpringBatch/src/main/java/org/example/service/ExternalReactiveService.java b/SpringBatch/src/main/java/org/example/service/ExternalReactiveService.java new file mode 100644 index 0000000..37073a8 --- /dev/null +++ b/SpringBatch/src/main/java/org/example/service/ExternalReactiveService.java @@ -0,0 +1,91 @@ +package org.example.service; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.github.resilience4j.bulkhead.annotation.Bulkhead; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.reactive.function.client.WebClientResponseException; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.util.retry.Retry; + +import java.time.Duration; + +@Service +public class ExternalReactiveService { + + private static final Logger log = LoggerFactory.getLogger(ExternalReactiveService.class); + + @Autowired + private ObjectMapper objectMapper; + + @Bulkhead(name = "serviceBulkhead", type = Bulkhead.Type.SEMAPHORE) + public Mono fetchData() { + return WebClient.create().get().uri("https://api.github.com/zen") + .retrieve() + .bodyToMono(String.class) + .doOnError(WebClientResponseException.class, ex -> + log.error("Error fetching data from GitHub API - Status Code: {}, Message: {}", + ex.getStatusCode().value(), ex.getMessage())) + .retryWhen(Retry.fixedDelay(5, Duration.ofMinutes(5)) + .filter(throwable -> throwable instanceof WebClientResponseException && + (((WebClientResponseException) throwable).getStatusCode().value() == 504 || + ((WebClientResponseException) throwable).getStatusCode().value() == 503)) + .doBeforeRetry(retrySignal -> + log.warn("Retrying GitHub API call - Attempt: {}, Error: {}", + retrySignal.totalRetries() + 1, retrySignal.failure().getMessage()))); + } + + @Bulkhead(name = "serviceBulkhead", type = Bulkhead.Type.SEMAPHORE) + public Mono fetchDataPageFromPath(String path, int page, int size) { + return WebClient.create() + .get() + .uri(uriBuilder -> uriBuilder + .scheme("http") + .host("localhost") + .port(9000) + .path(path) + .queryParam("page", page) + .queryParam("size", size) + .build()) + .retrieve() + .bodyToMono(String.class) + .doOnError(WebClientResponseException.class, ex -> + log.error("Error fetching page {} from {} - Status Code: {}, Message: {}", + page, path, ex.getStatusCode().value(), ex.getMessage())) + .retryWhen(Retry.fixedDelay(5, Duration.ofMinutes(1)) + .filter(throwable -> throwable instanceof WebClientResponseException && + (((WebClientResponseException) throwable).getStatusCode().value() == 504 || + ((WebClientResponseException) throwable).getStatusCode().value() == 503)) + .doBeforeRetry(retrySignal -> + log.warn("Retrying API call for page {} from {} - Attempt: {}, Error: {}", + page, path, retrySignal.totalRetries() + 1, retrySignal.failure().getMessage()))); + } + + public Flux fetchAllDataFromPath(String path, int size) { + return fetchDataPageFromPath(path, 0, size).flatMapMany(firstPage -> { + try { + JsonNode root = objectMapper.readTree(firstPage); + int totalPages = root.path("totalPages").asInt(); + log.info("Fetched page 0/{} from {}, response: {}", totalPages - 1, path, firstPage); + + if (totalPages <= 1) { + return Flux.just(firstPage); + } + + return Flux.concat( + Mono.just(firstPage), + Flux.range(1, totalPages) + .concatMap(page -> fetchDataPageFromPath(path, page, size) + .doOnNext(response -> log.info("Fetched page {}/{} from {}, response: {}", page, totalPages, path, response))) + ); + } catch (Exception e) { + return Flux.error(e); + } + }); + } +} \ No newline at end of file diff --git a/SpringBatch/src/main/resources/application.properties b/SpringBatch/src/main/resources/application.properties new file mode 100644 index 0000000..1ae0bf4 --- /dev/null +++ b/SpringBatch/src/main/resources/application.properties @@ -0,0 +1,16 @@ +## Spring JPA +spring.datasource.url=jdbc:postgresql://localhost:5432/postgres +spring.datasource.username=postgres +spring.datasource.password=naveen +spring.jpa.hibernate.ddl-auto=none +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.format_sql=false +hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect +spring.servlet.multipart.enabled=true +spring.servlet.multipart.max-file-size=50MB +spring.servlet.multipart.max-request-size=60MB +spring.output.ansi.enabled=ALWAYS +management.endpoint.metrics.enabled=true +management.endpoints.prometheus.enabled=true +management.endpoints.web.exposure.include=* +spring.batch.jdbc.initialize-schema=never diff --git a/SpringBatch/target/classes/application.properties b/SpringBatch/target/classes/application.properties new file mode 100644 index 0000000..1ae0bf4 --- /dev/null +++ b/SpringBatch/target/classes/application.properties @@ -0,0 +1,16 @@ +## Spring JPA +spring.datasource.url=jdbc:postgresql://localhost:5432/postgres +spring.datasource.username=postgres +spring.datasource.password=naveen +spring.jpa.hibernate.ddl-auto=none +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.format_sql=false +hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect +spring.servlet.multipart.enabled=true +spring.servlet.multipart.max-file-size=50MB +spring.servlet.multipart.max-request-size=60MB +spring.output.ansi.enabled=ALWAYS +management.endpoint.metrics.enabled=true +management.endpoints.prometheus.enabled=true +management.endpoints.web.exposure.include=* +spring.batch.jdbc.initialize-schema=never diff --git a/SpringBatch/target/classes/org/example/Application.class b/SpringBatch/target/classes/org/example/Application.class new file mode 100644 index 0000000000000000000000000000000000000000..bf96010940afdd9093fccd74c8acda5b2580e1a5 GIT binary patch literal 711 zcmZuvxlY4C5PcgG972E)?yH~+DR4&9oyKs-8+Sj*& zVQwImILneim@Ajd&>rZJ$0Kf}v;Uk`doNRlwY+D^(he};l7?UIl+8M#I5!bNER=+a z@l#>%_3Z_B6j@;?u`$${3B`$YL$wM!>^gF2mdi|8nTU~0rCU-dZSx19+QU+Aa@Kif zHIbB)BmUmtn4Y81poeXEbP?{WfVrC>IY*XHnvt$`-@sn;aEqi1gG%N}Hh&Y)#sXPW zSi};6xZ=GW45+ug?mMQg|LfiPfzHOmbOED|Wvq~YmHrwLOR9pkT&`n-v}?Nw`~d4@ Bw2c4& literal 0 HcmV?d00001 diff --git a/SpringBatch/target/classes/org/example/Config/BatchConfig.class b/SpringBatch/target/classes/org/example/Config/BatchConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..5f81ba969850704fab7519ed6f8bd5800f74d806 GIT binary patch literal 17300 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 F@C*4y=NA9~ literal 0 HcmV?d00001 diff --git a/SpringBatch/target/classes/org/example/controller/Batch.class b/SpringBatch/target/classes/org/example/controller/Batch.class new file mode 100644 index 0000000000000000000000000000000000000000..4e82227c28fce32f601ae1966c8e362104a2b47f GIT binary patch literal 3495 zcmbVP33n4!6#iaYI&C^yh%DlQK?U0)9S~F`AeORNOaW;r0&bJ!HJx@cFV4KQ#eLuR z71!V3c3AWre}F&3AL8+QlW99`gP=KQmiOkqd%wHi{Q389e*oBvA2Mh`tA#cjE6^^m za?+i49p4Qq&avX8ENOxEJzn7H2L)PtddDnu2&`9O#gVgawdPBwtd(S3DbPN}HeX^Pr8WmmgJFDNI5X^<1&&A7$Ftu{8`Hi0ew;jBP*CiJu% zGbR{_8VU()PHWk4LOyMoL~#on1$G$CqMEV9c<5H;j0&fmqEX8!sZcscRPnfLK2Vov zf8F!TGRz={)(+e$&_X~IPIj;k^9V^R|}bBAJX2W%X~A=V9VF{Vk3BE^N_>jmRVU`>mBRB z85WtiaOEadF&Ak!)UuqL@$^K_#QpBvb1&rFpqz6n@w>@`$89`;CmC8Vnil%?f6y<=JSm6DAzC}&;OosxqpD7pF+0rHJ_105|Xa!DRG zDRLQ9Fk!*7F^MUGyPElILhG7yLPj-mmj?sw>2m@tisXCKO3YW%YvjRdRz+Yz*{Iax^Rhuo4@A!T*atc?&5*pwDI=(|xg7ilRU=UGNi)QPkzhk|J@@`}D32m+;D6Ku3j zw&1I3QB66AWgtUV;4+V_PmYW=Ik2mFG)p&#*vVp?jyo^G8K`SD;IS=dS;z$w&@9v05`<)=0<>}EtO!~Bd-#itT9%vP`;XYjmJ70 z6_Jw!O|(eHqA`P%nFi$%)=vXTbs;8GMS*EPQS<{R=jP1rvF}w3?Dm!w-$*pHG$Z>GVhl8%!T&&GKc$#-gU`we(n* zI5cIpMF&TTw+Z>#6#abaF9SK~`u+$bMGXf+ONkz(kDmSw?;^xcF`F6Q&1YaOW_h<81UQFhxe|B|&l8q8{1=~Xe1^ZnI-TuY zx#1GJE@D-o?^mqeasf9D|Bl@0i?}^|$0cmKfGt^vyW20|-s}T+^L_#Oqa@wOYjEpj z9B##_pD~<$^fE?TVBSs}a$aXI}*CC+n|;oH~v7T;t2KTg{DDF6Tf literal 0 HcmV?d00001 diff --git a/SpringBatch/target/classes/org/example/dto/PersonDTO.class b/SpringBatch/target/classes/org/example/dto/PersonDTO.class new file mode 100644 index 0000000000000000000000000000000000000000..bc0bb8b4fffb4ec859fdcfd12e8b75fca1275d45 GIT binary patch literal 2536 zcma)8U31e$6g_K8mTg30LK5Oa`6z)VPJ;UZ6l_8Zfq-coQj(!F?MoGBCl+y}RN64* zpLF^Inin40nL=lH=#&>a)8Eja(Z^DHR+1gt3DAk--MzYd_S|#tUHQ*{pZx}47ArZV zkhWmhFp&```oVfxe&=j%wPbls`Q;@UguZuU<*tC?Ih#^oXyJkL&?&bZZ@s*%0@quw zYLKjr9P$EbXPr)myPRsClIt?4=ILeIIEVp(Y{T(xe!K0o1V$#heDAJ4kPTIx{7O3) zY#hRnKxSR4YZ`TAVzSG37k3yV7DjCx(a?omdNCRSq&_Otm_-}!;HZE_%*804;U3T= zqCAH2u8re3L9R_FY|i;>B#@q%tPN4PQ#RhiX@Mh~&W4=xy@sQ{bQPVvP&u9o1ul0- zm4NQUy*r++qtDnli}y+VitD-RYIN{@W*}xUxZrwnaeH%B1}n~LE6R!Aa9a1Bz}4%- zXsD)3CPx=uo6{8UN9C1^ zOvyYl$F-S{?eXH^vT_<5b!RKl!(6&otKZ~7HPQ)WxZP5eGzKxp<2_mB$8iWubQ66; z21z}?>~9ARIq&LR40KxNoUTNwaozV-r~+pzmL(j_;8q^DQL}JI7t-efsBwx7KFsz^@sHP8G~=bjF%O~pp7sf@%3KMKX6YA*pCY$OerF=%0hBnmV+TxO znyZ=Q={b%0O^QPCE`p9rKu+nKl7Lrb}3mA(kN}3WK2oVbc_NY z(rU6zQ0U|N5kB4z-ul1rTDlH=ZVx74i?Q~rtM@r z=2_`I`rM8=bo6QBJT5SR5iH{()0o0IZr~Hz($w=RE^%hy7OUnmXC~^bj|yiQREd8Q zIV<}Q1}vmrV${MgKUwh-WAQZC5$1fKFou4^CBj_h@j7XyRz$OYT~^HwYm;0x>m;ie z`_S19I6)X)#(!}%IaUhQE5>Xj?y*9(Noli%sU27|PjT!UZ6B)``a#i1o@BM)d~|Go zA*C1tyFOEU|1Bg&Mb2*)v0uB8=$=5nvdM_cK+TW77 hx7;0R%<+^I>-i?fECre8{{j}d(oK68U$E+n{{as7&IAAe literal 0 HcmV?d00001 diff --git a/SpringBatch/target/classes/org/example/service/ExternalReactiveService.class b/SpringBatch/target/classes/org/example/service/ExternalReactiveService.class new file mode 100644 index 0000000000000000000000000000000000000000..0d6fa853cbacaa0fc61c8d188abfce7bd805ba85 GIT binary patch literal 10485 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