package com.interplug.qcast.batch.system; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.function.Consumer; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobExecutionListener; import org.springframework.batch.core.Step; import org.springframework.batch.core.configuration.annotation.StepScope; import org.springframework.batch.core.job.builder.JobBuilder; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.item.support.ListItemReader; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.transaction.PlatformTransactionManager; import com.interplug.qcast.biz.commCode.CommCodeService; import com.interplug.qcast.biz.commCode.dto.CommonCodeSyncResponse; import com.interplug.qcast.biz.commCode.dto.DetailCodeRequest; import com.interplug.qcast.biz.commCode.dto.HeadCodeRequest; import com.interplug.qcast.util.InterfaceQsp; import lombok.extern.slf4j.Slf4j; /** 공통코드 동기화 배치 */ @Configuration @Slf4j public class CommonCodeConfiguration implements JobExecutionListener { private final InterfaceQsp interfaceQsp; private final CommCodeService commCodeService; @Value("${qsp.system-commonCode-batch-url}") private String qspInterfaceUrl; private CommonCodeSyncResponse commonCodeSyncResponse; public CommonCodeConfiguration(InterfaceQsp interfaceQsp, CommCodeService commCodeService) { this.interfaceQsp = interfaceQsp; this.commCodeService = commCodeService; } @Override public void beforeJob(JobExecution jobExecution) { log.info("Job 시작: 초기화 메서드 호출 중..."); try { this.commonCodeSyncResponse = interfaceQsp.callApiData(HttpMethod.GET, qspInterfaceUrl, null, CommonCodeSyncResponse.class); log.info("API 호출 완료, 항목 수: {}", this.commonCodeSyncResponse.getApiHeadCdList().size()); log.info("API 호출 완료, 항목 수: {}", this.commonCodeSyncResponse.getApiCommCdList().size()); } catch (Exception e) { log.error("commonCodeSyncResponse 갱신 중 오류: {}", e.getMessage()); } } @Bean public Job commonCodeJob(JobRepository jobRepository, Step headCodeStep, Step commonCodeStep) { return new JobBuilder("commonCodeJob", jobRepository).start(headCodeStep).next(commonCodeStep) .listener(this).build(); } private Step buildStep(String stepName, JobRepository jobRepository, PlatformTransactionManager transactionManager, ItemReader reader, ItemWriter writer) { return new StepBuilder(stepName, jobRepository).chunk(10, transactionManager) .reader(reader).writer(writer).build(); } @Bean public Step headCodeStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) { return buildStep("headCodeStep", jobRepository, transactionManager, headCodeListReader(), createWriter((items) -> { try { log.debug("HeadCode batch processing {} items", items.size()); commCodeService.setHeaderCodeSyncSave(items); log.debug("Successfully processed headCommonCode batch"); } catch (Exception e) { log.error("Error processing headCommonCode batch: {}", e.getMessage(), e); throw new RuntimeException("Failed to process headCommonCode batch", e); } }, "headCode")); } @Bean public Step commonCodeStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) { return buildStep("commonCodeStep", jobRepository, transactionManager, commonCodeListReader(), createWriter((items) -> { try { log.debug("commonCodeStep batch processing {} items", items.size()); commCodeService.setCommonCodeSyncSave(items); log.debug("Successfully processed commonCode batch"); } catch (Exception e) { log.error("Error processing commonCode batch: {}", e.getMessage(), e); throw new RuntimeException("Failed to process commonCode batch", e); } }, "commonCode")); } private ListItemReader createReader(List items, String readerName) { log.info("{}Reader 호출됨...", readerName); return new ListItemReader<>(items != null ? items : Collections.emptyList()); } @Bean @StepScope public ListItemReader headCodeListReader() { return createReader( commonCodeSyncResponse != null ? commonCodeSyncResponse.getApiHeadCdList() : null, "headCode"); } @Bean @StepScope public ListItemReader commonCodeListReader() { return createReader( commonCodeSyncResponse != null ? commonCodeSyncResponse.getApiCommCdList() : null, "commonCode"); } private ItemWriter createWriter(Consumer> processor, String writerName) { return items -> { try { List itemList = new ArrayList<>(items.getItems()); processor.accept(itemList); log.info("{}Writer: {} items 처리 완료", writerName, items.size()); } catch (Exception e) { log.error("{}Writer 오류: {}", writerName, e.getMessage()); throw e; } }; } }