স্প্রিং ব্যাচ (Spring Batch) এবং REST API ইন্টিগ্রেশন একটি শক্তিশালী কৌশল যা ব্যাচ প্রসেসিংয়ের কাজ এবং ওয়েব সার্ভিসের মধ্যে সেতুবন্ধন তৈরি করে। আপনি যখন স্প্রিং ব্যাচের মাধ্যমে ব্যাচ জব বা ব্যাচ প্রসেসিং কাজ চালান, তখন এর আউটপুট বা প্রক্রিয়াকৃত ডেটাকে REST API এর মাধ্যমে ক্লায়েন্টদের কাছে সরবরাহ করতে পারেন।
এই টিউটোরিয়ালে, আমরা একটি Spring Boot অ্যাপ্লিকেশন তৈরি করব, যেখানে Spring Batch এবং REST API একসাথে কাজ করবে। উদাহরণস্বরূপ, আমরা একটি ব্যাচ কাজ তৈরি করব যা ডেটাবেস থেকে ডেটা নিয়ে REST API এর মাধ্যমে ফ্রন্টএন্ড বা ক্লায়েন্টকে প্রক্রিয়াকৃত ডেটা সরবরাহ করবে।
এখানে, আমরা একটি User ব্যাচ জব তৈরি করব যা ডেটাবেস থেকে ইউজারদের ডেটা পড়বে, প্রক্রিয়া করবে এবং REST API এর মাধ্যমে ক্লায়েন্টকে ফেরত দেবে।
প্রথমে pom.xml
ফাইলে প্রয়োজনীয় ডিপেনডেন্সি যোগ করুন:
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Starter Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Spring Batch Core -->
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
</dependency>
<!-- MySQL JDBC Driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Spring Boot Starter Batch -->
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-starter</artifactId>
</dependency>
</dependencies>
এখানে, spring-batch-core
স্প্রিং ব্যাচের মূল লাইব্রেরি এবং spring-boot-starter-web
ওয়েব সেবা পরিচালনার জন্য ব্যবহৃত হচ্ছে।
স্প্রিং ব্যাচ কনফিগার করতে ItemReader
, ItemProcessor
, এবং ItemWriter
তৈরি করা হয়। এখানে আমরা FlatFileItemReader
ব্যবহার করব যা ডেটাবেস থেকে ডেটা পড়বে এবং প্রক্রিয়া করবে।
প্রথমে, User
ডেটা মডেল তৈরি করা হবে যা ডেটাবেসে সেভ হবে।
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class User {
@Id
private Long id;
private String name;
private String email;
// Getters and Setters
}
ItemReader ব্যবহার করে আমরা ডেটাবেস থেকে ডেটা পড়ব। ItemProcessor ব্যবহার করে ডেটা প্রক্রিয়া করা হবে এবং ItemWriter ব্যবহার করে ডেটা REST API এর মাধ্যমে ক্লায়েন্টে পাঠানো হবে।
import org.springframework.batch.item.ItemReader;
import org.springframework.beans.factory.annotation.Autowired;
public class UserItemReader implements ItemReader<User> {
@Autowired
private UserRepository userRepository;
@Override
public User read() throws Exception {
return userRepository.findFirstByOrderByIdAsc(); // Example: fetch first user from database
}
}
import org.springframework.batch.item.ItemProcessor;
public class UserItemProcessor implements ItemProcessor<User, User> {
@Override
public User process(User user) throws Exception {
user.setName(user.getName().toUpperCase()); // Example: Capitalize the name
return user;
}
}
import org.springframework.batch.item.ItemWriter;
import java.util.List;
import org.springframework.web.client.RestTemplate;
public class UserItemWriter implements ItemWriter<User> {
private RestTemplate restTemplate = new RestTemplate();
@Override
public void write(List<? extends User> items) throws Exception {
for (User user : items) {
// Sending processed data via REST API
restTemplate.postForObject("http://localhost:8080/api/users", user, User.class);
}
}
}
এখানে, ItemWriter
ফাইল থেকে প্রক্রিয়া করা ডেটা REST API এর মাধ্যমে পাঠাবে।
স্প্রিং ব্যাচের Step
কনফিগারেশন, যা ItemReader
, ItemProcessor
, এবং ItemWriter
এর মাধ্যমে একটি ব্যাচ প্রসেসিং কাজ সম্পাদন করে।
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.Job;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BatchConfig {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
@Autowired
public BatchConfig(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory) {
this.jobBuilderFactory = jobBuilderFactory;
this.stepBuilderFactory = stepBuilderFactory;
}
@Bean
public Step step1() {
return stepBuilderFactory.get("step1")
.<User, User>chunk(10)
.reader(new UserItemReader()) // ItemReader
.processor(new UserItemProcessor()) // ItemProcessor
.writer(new UserItemWriter()) // ItemWriter
.build();
}
@Bean
public Job job() {
return jobBuilderFactory.get("job")
.start(step1())
.build();
}
}
এখানে:
chunk(10)
নির্দেশ করে প্রতি ১০টি রেকর্ডের একটি ব্যাচ প্রক্রিয়া করা হবে।স্প্রিং বুট অ্যাপ্লিকেশনে একটি REST API কন্ট্রোলার তৈরি করে, যেখানে স্প্রিং ব্যাচের প্রক্রিয়া করা ডেটা সঞ্চিত করা হবে।
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
public class UserController {
@PostMapping
public User createUser(@RequestBody User user) {
// Save the user to the database (or other operations)
System.out.println("Received user: " + user.getName());
return user;
}
@GetMapping
public List<User> getAllUsers() {
// Return a list of users
return userRepository.findAll();
}
}
এখানে, @PostMapping
ব্যবহার করে স্প্রিং ব্যাচের মাধ্যমে প্রক্রিয়া করা ডেটা API এর মাধ্যমে পোস্ট করা হবে।
স্প্রিং বুট অ্যাপ্লিকেশন চালানোর জন্য মূল ক্লাস তৈরি করা:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.batch.core.launch.JobParameters;
import org.springframework.batch.core.Job;
@SpringBootApplication
public class BatchApplication {
@Autowired
private JobLauncher jobLauncher;
@Autowired
private Job job;
public static void main(String[] args) {
SpringApplication.run(BatchApplication.class, args);
}
@PostConstruct
public void runBatchJob() throws Exception {
jobLauncher.run(job, new JobParameters());
}
}
এখানে, jobLauncher.run(job, new JobParameters())
দিয়ে স্প্রিং ব্যাচ কাজটি চালানো হয়।
স্প্রিং ব্যাচ এবং REST API ইন্টিগ্রেশন একটি শক্তিশালী উপায় যা স্প্রিং ব্যাচের মাধ্যমে ডেটা প্রক্রিয়া করে এবং REST API এর মাধ্যমে ক্লায়েন্টে তা সরবরাহ করতে সাহায্য করে। আমরা এখানে একটি User ব্যাচ কাজ তৈরি করেছি, যা ডেটাবেস থেকে ডেটা পড়ে, প্রক্রিয়া করে এবং REST API ব্যবহার করে ক্লায়েন্টে প্রেরণ করে। স্প্রিং বুট এবং স্প্রিং ব্যাচ একসাথে ব্যবহৃত হলে এটি ব্যাচ প্রসেসিং এবং ওয়েব সার্ভিসের মধ্যে সেতুবন্ধন তৈরি করে।
Spring Batch একটি শক্তিশালী ব্যাচ প্রসেসিং ফ্রেমওয়ার্ক যা ব্যাচ প্রসেসিংয়ের জন্য খুবই উপকারী, বিশেষ করে বড় ডেটাসেট ম্যানেজ এবং প্রসেসিং করতে। কখনো কখনো আপনাকে REST API থেকে ডেটা পড়তে হতে পারে এবং তারপর সেই ডেটাকে Spring Batch ব্যবহার করে প্রক্রিয়া (process) করতে হতে পারে। এই ধরনের ব্যবহারিক কেসে, ItemReader কে কাস্টমাইজ করে REST API থেকে ডেটা ফেচ করা যেতে পারে এবং সেই ডেটাকে ItemProcessor এবং ItemWriter এর মাধ্যমে প্রক্রিয়া এবং লেখার কাজ করা যেতে পারে।
এখানে আমরা দেখব কিভাবে REST API থেকে ডেটা রিড করে এবং Spring Batch এর মাধ্যমে সেই ডেটা প্রক্রিয়া করা যায়।
Spring Batch এ REST API থেকে ডেটা পড়ার জন্য আপনি ItemReader কাস্টমাইজ করতে পারেন। RestTemplate
অথবা WebClient
ব্যবহার করে REST API থেকে ডেটা ফেচ করা যেতে পারে। নিচে RestTemplate ব্যবহার করে API থেকে ডেটা রিড করার একটি উদাহরণ দেখানো হলো।
Spring Batch এবং REST API থেকে ডেটা পড়ার জন্য spring-boot-starter-web
এবং spring-boot-starter-batch
ডিপেনডেন্সি প্রয়োজন।
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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>
এখানে ItemReader কাস্টমাইজ করা হয়েছে RestTemplate
ব্যবহার করে REST API থেকে ডেটা পড়ার জন্য। আমরা একটি সাধারণ API থেকে ডেটা ফেচ করবো যেখানে কিছু Employee তথ্য রিটার্ন হয়।
package com.example.demo;
import org.springframework.batch.item.ItemReader;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
import java.util.List;
@Component
public class EmployeeItemReader implements ItemReader<Employee> {
private final String apiUrl = "https://api.example.com/employees";
private int currentIndex = 0;
private List<Employee> employees;
private final RestTemplate restTemplate = new RestTemplate();
@Override
public Employee read() throws Exception {
if (employees == null || currentIndex >= employees.size()) {
// Fetch new data from REST API
employees = Arrays.asList(restTemplate.getForObject(apiUrl, Employee[].class));
currentIndex = 0; // Reset index
}
if (currentIndex < employees.size()) {
return employees.get(currentIndex++);
} else {
return null; // End of data
}
}
}
এখানে, EmployeeItemReader একটি REST API থেকে Employee তথ্য পড়ছে। RestTemplate
ব্যবহার করে API থেকে ডেটা ফেচ করা হয়েছে এবং সেগুলো একটি List হিসেবে সংরক্ষিত করা হচ্ছে। প্রতিবার read() মেথড কল হওয়ার পর, এটি পরবর্তী Employee অবজেক্ট রিটার্ন করে। যখন ডেটা শেষ হয়ে যায়, তখন null
রিটার্ন করা হয়।
এখন, একটি ItemProcessor তৈরি করা হবে যা API থেকে পাওয়া ডেটাকে প্রসেস করবে। উদাহরণস্বরূপ, আমরা Employee এর নাম পরিবর্তন করতে পারি।
package com.example.demo;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.stereotype.Component;
@Component
public class EmployeeItemProcessor implements ItemProcessor<Employee, Employee> {
@Override
public Employee process(Employee employee) throws Exception {
// প্রসেসিং (যেমন নাম পরিবর্তন)
String updatedName = employee.getFirstName() + " " + employee.getLastName();
employee.setFullName(updatedName); // নতুন নাম সেট করা
return employee;
}
}
এখানে, EmployeeItemProcessor ক্লাসে, process()
মেথডে Employee
অবজেক্টের প্রথম নাম এবং শেষ নাম মিলিয়ে নতুন একটি fullName তৈরি করা হচ্ছে।
অবশেষে, ItemWriter তৈরি করা হবে যা প্রসেস করা ডেটাকে আউটপুটে (যেমন ডাটাবেসে বা ফাইলে) লিখবে।
package com.example.demo;
import org.springframework.batch.item.ItemWriter;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class EmployeeItemWriter implements ItemWriter<Employee> {
@Override
public void write(List<? extends Employee> items) throws Exception {
// এখানে, উদাহরণস্বরূপ কনসোলে আউটপুট করা হচ্ছে
items.forEach(item -> System.out.println(item.getFullName()));
}
}
এখানে, EmployeeItemWriter কনসোলে প্রতিটি Employee
এর পূর্ণ নাম লিখছে। বাস্তবে, আপনি এই ডাটা একটি ডাটাবেস বা ফাইলে লিখতে পারেন।
এখন, Step কনফিগারেশন করা হবে যেখানে ItemReader, ItemProcessor, এবং ItemWriter ব্যবহার করা হবে।
package com.example.demo;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableBatchProcessing
public class BatchConfig {
@Bean
public Job job(JobBuilderFactory jobBuilderFactory, Step step1) {
return jobBuilderFactory.get("job")
.incrementer(new RunIdIncrementer())
.flow(step1) // Define step1
.end()
.build();
}
@Bean
public Step step1(StepBuilderFactory stepBuilderFactory,
EmployeeItemReader reader,
EmployeeItemProcessor processor,
EmployeeItemWriter writer) {
return stepBuilderFactory.get("step1")
.<Employee, Employee>chunk(10) // Define chunk size
.reader(reader)
.processor(processor)
.writer(writer)
.build();
}
}
এখানে, Step কনফিগারেশন এ ItemReader, ItemProcessor, এবং ItemWriter ইনজেক্ট করা হয়েছে, এবং chunk(10) দ্বারা প্রতিটি চাঙ্কে ১০টি আইটেম প্রক্রিয়া করা হবে।
ব্যাচ জব চালানোর জন্য JobLauncher ব্যবহার করা হয়। এটি CommandLineRunner মাধ্যমে অ্যাপ্লিকেশন চালানোর সময় কার্যকর করা যেতে পারে।
package com.example.demo;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class JobRunner implements CommandLineRunner {
@Autowired
private JobLauncher jobLauncher;
@Autowired
private Job job;
@Override
public void run(String... args) throws Exception {
jobLauncher.run(job, new JobParameters());
}
}
এখানে, JobLauncher দিয়ে job চালানো হচ্ছে এবং run() মেথড দিয়ে ব্যাচ জব কার্যকর করা হচ্ছে।
Spring Batch এর মাধ্যমে REST API থেকে ডেটা পড়া এবং প্রক্রিয়া করা খুবই কার্যকরী। ItemReader কাস্টমাইজ করে REST API থেকে ডেটা ফেচ করা যায়, তারপর ItemProcessor এর মাধ্যমে সেই ডেটা প্রক্রিয়া করা হয় এবং ItemWriter এর মাধ্যমে আউটপুট দেওয়া হয়। Spring Batch এর এই ফিচার ব্যবহার করে আপনি বড় ডেটাসেট বা অনেকগুলো আইটেমকে কার্যকরভাবে প্রক্রিয়া এবং পরিচালনা করতে পারেন।
Spring Batch ব্যাচ প্রক্রিয়াকরণ এবং ডেটা ম্যানিপুলেশন জন্য ব্যবহৃত হয়, কিন্তু কখনো কখনো আপনাকে বাহ্যিক সিস্টেম বা API এর সাথে যোগাযোগ করতে হতে পারে, যেমন REST API-এর মাধ্যমে ডেটা রিড বা রাইট করা। RestTemplate এবং WebClient হল Spring Framework-এর দুটি গুরুত্বপূর্ণ ক্লাস যা API-এর সাথে যোগাযোগের জন্য ব্যবহৃত হয়। এই দুটি টুল ব্যবহার করে আপনি Spring Batch এর মধ্যে বাহ্যিক API এর সাথে ইন্টিগ্রেশন করতে পারেন।
এখানে RestTemplate এবং WebClient ব্যবহার করে API ইন্টিগ্রেশন করার জন্য উদাহরণ দেওয়া হয়েছে।
RestTemplate একটি সিনক্রোনাস HTTP ক্লায়েন্ট যা HTTP রিকোয়েস্ট পাঠানোর জন্য ব্যবহৃত হয়। যদিও এটি এখন WebClient এর মাধ্যমে প্রতিস্থাপিত হচ্ছে, তবুও এটি অনেক অ্যাপ্লিকেশনেই ব্যবহৃত হচ্ছে এবং Spring Batch এর মধ্যে API ইন্টিগ্রেশনের জন্য ব্যবহার করা যেতে পারে।
প্রথমে Spring Batch প্রজেক্টে RestTemplate Bean কনফিগার করতে হবে। Spring Boot এর কনফিগারেশন ক্লাসে নিচের মতো Bean কনফিগার করতে হবে:
@Configuration
public class BatchConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
এখন, ItemReader
ব্যবহার করে API থেকে ডেটা রিড করার জন্য RestTemplate ব্যবহার করা যেতে পারে। নিচে একটি উদাহরণ দেখানো হলো যেখানে একটি API থেকে JSON ডেটা রিড করা হচ্ছে:
@Component
public class ApiItemReader implements ItemReader<MyItem> {
private final RestTemplate restTemplate;
private String apiUrl = "https://api.example.com/items"; // API URL
@Autowired
public ApiItemReader(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Override
public MyItem read() throws Exception {
ResponseEntity<MyItem> response = restTemplate.exchange(
apiUrl,
HttpMethod.GET,
null,
MyItem.class
);
return response.getBody(); // API থেকে প্রাপ্ত ডেটা
}
}
এখানে, RestTemplate
ব্যবহার করে একটি HTTP GET রিকোয়েস্ট পাঠানো হচ্ছে এবং API থেকে প্রাপ্ত ডেটা MyItem
ক্লাসে ম্যাপ করা হচ্ছে।
এখন এই ItemReader
-কে Spring Batch-এ একটি Step এর মধ্যে ব্যবহার করতে হবে:
@Bean
public Step step1(ApiItemReader reader, ItemProcessor<MyItem, MyProcessedItem> processor, ItemWriter<MyProcessedItem> writer) {
return stepBuilderFactory.get("step1")
.<MyItem, MyProcessedItem>chunk(10)
.reader(reader)
.processor(processor)
.writer(writer)
.build();
}
এখানে ApiItemReader
কে reader
হিসাবে ব্যবহার করা হয়েছে, যেটি API থেকে ডেটা রিড করবে এবং পরবর্তী প্রসেসিংয়ের জন্য তা পাঠাবে।
WebClient হল Spring 5 এর একটি নতুন ও আধুনিক HTTP ক্লায়েন্ট যা asynchronous এবং reactive প্রোগ্রামিং সাপোর্ট করে। এটি RestTemplate
থেকে উন্নত এবং ফিচার সমৃদ্ধ। WebClient ব্যবহার করে API ইন্টিগ্রেশন আরও কার্যকরী হতে পারে, বিশেষত যখন আপনি asynchronous বা non-blocking রিকোয়েস্ট চান।
Spring Boot-এ WebClient
Bean কনফিগার করতে নিচের কনফিগারেশন ব্যবহার করা যেতে পারে:
@Configuration
public class WebClientConfig {
@Bean
public WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
}
WebClient ব্যবহার করে API থেকে ডেটা রিড করতে একটি ItemReader
তৈরি করা হবে। এখানে, asynchronous API কল ব্যবহার করা হচ্ছে:
@Component
public class ApiItemReader implements ItemReader<MyItem> {
private final WebClient.Builder webClientBuilder;
private String apiUrl = "https://api.example.com/items"; // API URL
@Autowired
public ApiItemReader(WebClient.Builder webClientBuilder) {
this.webClientBuilder = webClientBuilder;
}
@Override
public MyItem read() throws Exception {
WebClient webClient = webClientBuilder.baseUrl(apiUrl).build();
// WebClient ব্যবহার করে API কল
MyItem item = webClient.get()
.retrieve()
.bodyToMono(MyItem.class) // API থেকে ডেটা JSON হিসেবে রিড
.block(); // synchronous হিসেবে ব্লক করতে
return item;
}
}
এখানে, WebClient
ব্যবহার করে API কল করা হচ্ছে এবং প্রাপ্ত ডেটা MyItem
ক্লাসে ম্যাপ করা হচ্ছে। bodyToMono()
একটি reactive ফাংশন যা asynchronous ডেটা রিটার্ন করে, কিন্তু .block()
ব্যবহার করে সিঙ্ক্রোনাস আউটপুট পাওয়া যাচ্ছে।
এখন WebClient
এর মাধ্যমে রিড করা ডেটা Spring Batch Step এর মধ্যে ব্যবহার করা হবে:
@Bean
public Step step1(ApiItemReader reader, ItemProcessor<MyItem, MyProcessedItem> processor, ItemWriter<MyProcessedItem> writer) {
return stepBuilderFactory.get("step1")
.<MyItem, MyProcessedItem>chunk(10)
.reader(reader)
.processor(processor)
.writer(writer)
.build();
}
এখানে ApiItemReader
কে reader
হিসাবে ব্যবহার করা হচ্ছে, যেটি API থেকে ডেটা রিড করবে এবং পরবর্তী প্রসেসিংয়ের জন্য তা পাঠাবে।
Spring Batch ব্যবহার করে RestTemplate এবং WebClient এর মাধ্যমে API ইন্টিগ্রেশন করা সম্ভব এবং এটি ব্যাচ প্রসেসিংয়ের মধ্যে বাহ্যিক সিস্টেমের সাথে ডেটা আদান-প্রদান করতে ব্যবহৃত হতে পারে। RestTemplate
একটি সিঙ্ক্রোনাস HTTP ক্লায়েন্ট, যা সহজ API ইন্টিগ্রেশন করতে সাহায্য করে, এবং WebClient
হল একটি আধুনিক এবং রিএ্যাকটিভ HTTP ক্লায়েন্ট যা asynchronous এবং non-blocking রিকোয়েস্ট সাপোর্ট করে। Spring Batch এবং Spring WebClient বা RestTemplate এর মাধ্যমে আপনি আরও স্কেলেবল, পারফরম্যান্ট, এবং কার্যকরী API ইন্টিগ্রেশন করতে সক্ষম হবেন।
Spring Batch এবং REST API এর মধ্যে ইন্টিগ্রেশন একটি শক্তিশালী কৌশল, যা ডেটা প্রক্রিয়াকরণ এবং রিপোর্টিংয়ের জন্য ব্যবহৃত হয়। Spring Batch ব্যাচ প্রসেসিংয়ের জন্য ব্যবহৃত হলেও, REST API এর মাধ্যমে আপনি এই ব্যাচ জব গুলি ট্রিগার করতে, তাদের স্ট্যাটাস মনিটর করতে এবং ফলাফল রিটার্ন করতে পারেন।
এই উদাহরণে, আমরা দেখবো কিভাবে Spring Batch জব এবং স্টেপগুলোকে REST API এর মাধ্যমে এক্সিকিউট করতে হয় এবং তাদের স্ট্যাটাস ফেচ করা যায়।
প্রথমে, Spring Boot অ্যাপ্লিকেশন তৈরি করতে হবে এবং প্রয়োজনীয় ডিপেনডেন্সি যোগ করতে হবে।
pom.xml এ Spring Boot Starter এবং Spring Batch ডিপেনডেন্সি যোগ করুন:
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Starter Batch -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<!-- Spring Boot Starter Data JPA for Database Connectivity -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- H2 Database (or any other DB you choose) -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Spring Boot Starter Actuator for Monitoring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Spring Boot Starter for RESTful services -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
</dependencies>
Spring Batch এর জন্য একটি সিম্পল ItemProcessor, ItemReader, এবং ItemWriter কনফিগার করা হবে। এছাড়া, একটি Step
এবং Job
তৈরি করা হবে।
@Configuration
@EnableBatchProcessing
public class BatchConfig {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public Step step1() {
return stepBuilderFactory.get("step1")
.<String, String>chunk(10)
.reader(itemReader())
.processor(itemProcessor())
.writer(itemWriter())
.build();
}
@Bean
public Job job() {
return jobBuilderFactory.get("batchJob")
.start(step1())
.build();
}
@Bean
public ItemReader<String> itemReader() {
return new ItemReader<String>() {
private List<String> data = Arrays.asList("Item1", "Item2", "Item3", "Item4", "Item5");
private int index = 0;
@Override
public String read() throws Exception {
if (index < data.size()) {
return data.get(index++);
} else {
return null;
}
}
};
}
@Bean
public ItemProcessor<String, String> itemProcessor() {
return new ItemProcessor<String, String>() {
@Override
public String process(String item) throws Exception {
return "Processed: " + item;
}
};
}
@Bean
public ItemWriter<String> itemWriter() {
return new ItemWriter<String>() {
@Override
public void write(List<? extends String> items) throws Exception {
for (String item : items) {
System.out.println(item);
}
}
};
}
}
এখন, আমরা একটি REST API Controller তৈরি করবো যা Spring Batch Job টিকে ট্রিগার করবে এবং তার স্ট্যাটাস পাবে। Spring Batch Job গুলো REST API এর মাধ্যমে run করা হবে।
@RestController
@RequestMapping("/batch")
public class BatchController {
@Autowired
private JobLauncher jobLauncher;
@Autowired
private Job job;
@PostMapping("/start")
public ResponseEntity<String> startBatchJob() {
try {
JobExecution jobExecution = jobLauncher.run(job, new JobParameters());
return new ResponseEntity<>("Batch Job started with JobExecution ID: " + jobExecution.getId(), HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>("Error starting batch job: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/status/{jobExecutionId}")
public ResponseEntity<String> getJobExecutionStatus(@PathVariable Long jobExecutionId) {
JobExecution jobExecution = jobRepository.getJobExecution(jobExecutionId);
if (jobExecution == null) {
return new ResponseEntity<>("Job execution not found.", HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>("Job Execution Status: " + jobExecution.getStatus(), HttpStatus.OK);
}
}
jobLauncher.run(job, new JobParameters())
দিয়ে Job রান করা হয় এবং JobExecution ID রিটার্ন করা হয়।COMPLETED
, FAILED
বা STARTED
হতে পারে।Spring Batch Job Execution History এবং Status ট্র্যাক করার জন্য, Spring Batch ডিফল্টভাবে JobRepository ব্যবহার করে, যা JobExecution এবং StepExecution মেটাডেটা সংরক্ষণ করে। এই মেটাডেটা ব্যবহার করে আপনি ব্যাচ জবের ইতিহাস এবং স্ট্যাটাস মনিটর করতে পারবেন।
@Autowired
private JobRepository jobRepository;
public void logJobExecutionDetails(Long jobExecutionId) {
JobExecution jobExecution = jobRepository.getJobExecution(jobExecutionId);
System.out.println("Job name: " + jobExecution.getJobInstance().getJobName());
System.out.println("Job status: " + jobExecution.getStatus());
System.out.println("Job start time: " + jobExecution.getStartTime());
System.out.println("Job end time: " + jobExecution.getEndTime());
System.out.println("Job failure exceptions: " + jobExecution.getAllFailureExceptions());
}
Spring Batch ব্যবহার করার মাধ্যমে ব্যাচ জবের execution history সরাসরি JobRepository তে সংরক্ষিত থাকে। এটি ডাটাবেসের টেবিলগুলিতে স্টোর করা হয় এবং এখান থেকে আপনি Job এর execution history, status, failure details ইত্যাদি পর্যালোচনা করতে পারেন।
Spring Batch Actuator ব্যবহার করে আপনি আরও উন্নত মনিটরিং করতে পারেন, যা বিভিন্ন Batch Job এবং Step এর স্ট্যাটাস, স্লিপ টাইম, এবং রান টাইম সংক্রান্ত ডেটা প্রদান করে।
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
এটি Spring Boot Actuator এর মত কাজ করবে এবং আপনাকে ব্যাচ জবের জন্য metrics, health checks, এবং job details প্রদান করবে।
Spring Batch এবং REST API এর মধ্যে ইন্টিগ্রেশন সহজভাবে ব্যাচ প্রক্রিয়াগুলিকে ওয়েব অ্যাপ্লিকেশন বা অন্য ক্লায়েন্ট অ্যাপ্লিকেশনের মাধ্যমে পরিচালনা করতে সহায়তা করে। REST API ব্যবহার করে Spring Batch Job শুরু করা এবং তার স্ট্যাটাস মনিটর করা যেতে পারে। JobLauncher
, JobRepository
, এবং JobExecution
এর মাধ্যমে আমরা ব্যাচ জব এবং স্টেপের কার্যক্রম ট্র্যাক করতে পারি। এছাড়া, Spring Batch Actuator এবং JobExecutionListener এর মাধ্যমে আমরা ব্যাচ জবের কার্যকলাপ মনিটর করতে পারি।
Read more
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ducimus nihil, quo, quis minus aspernatur expedita, incidunt facilis aliquid inventore voluptate dolores accusantium laborum labore a dolorum dolore omnis qui? Consequuntur sed facilis repellendus corrupti amet in quibusdam ducimus illo autem, a praesentium.
1 hour ago
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ducimus nihil, quo, quis minus aspernatur expedita, incidunt facilis aliquid inventore voluptate dolores accusantium laborum labore a dolorum dolore omnis qui? Consequuntur sed facilis repellendus corrupti amet in quibusdam ducimus illo autem, a praesentium.
1 hour ago
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ducimus nihil, quo, quis minus aspernatur expedita, incidunt facilis aliquid inventore voluptate dolores accusantium laborum labore a dolorum dolore omnis qui? Consequuntur sed facilis repellendus corrupti amet in quibusdam ducimus illo autem, a praesentium.
1 hour ago
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ducimus nihil, quo, quis minus aspernatur expedita, incidunt facilis aliquid inventore voluptate dolores accusantium laborum labore a dolorum dolore omnis qui? Consequuntur sed facilis repellendus corrupti amet in quibusdam ducimus illo autem, a praesentium.
1 hour ago
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ducimus nihil, quo, quis minus aspernatur expedita, incidunt facilis aliquid inventore voluptate dolores accusantium laborum labore a dolorum dolore omnis qui? Consequuntur sed facilis repellendus corrupti amet in quibusdam ducimus illo autem, a praesentium.
1 hour ago
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ducimus nihil, quo, quis minus aspernatur expedita, incidunt facilis aliquid inventore voluptate dolores accusantium laborum labore a dolorum dolore omnis qui? Consequuntur sed facilis repellendus corrupti amet in quibusdam ducimus illo autem, a praesentium.
1 hour ago
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ducimus nihil, quo, quis minus aspernatur expedita, incidunt facilis aliquid inventore voluptate dolores accusantium laborum labore a dolorum dolore omnis qui? Consequuntur sed facilis repellendus corrupti amet in quibusdam ducimus illo autem, a praesentium.
1 hour ago
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ducimus nihil, quo, quis minus aspernatur expedita, incidunt facilis aliquid inventore voluptate dolores accusantium laborum labore a dolorum dolore omnis qui? Consequuntur sed facilis repellendus corrupti amet in quibusdam ducimus illo autem, a praesentium.
1 hour ago
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ducimus nihil, quo, quis minus aspernatur expedita, incidunt facilis aliquid inventore voluptate dolores accusantium laborum labore a dolorum dolore omnis qui? Consequuntur sed facilis repellendus corrupti amet in quibusdam ducimus illo autem, a praesentium.
1 hour ago
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ducimus nihil, quo, quis minus aspernatur expedita, incidunt facilis aliquid inventore voluptate dolores accusantium laborum labore a dolorum dolore omnis qui? Consequuntur sed facilis repellendus corrupti amet in quibusdam ducimus illo autem, a praesentium.
1 hour ago