package com.interplug.qcast.batch.master; import com.fasterxml.jackson.core.type.TypeReference; import com.interplug.qcast.biz.displayItem.DisplayItemService; import com.interplug.qcast.biz.displayItem.dto.ItemSyncResponse; import com.interplug.qcast.util.InterfaceQsp; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.batch.core.Job; 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.ItemProcessor; 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; /** Item 마스터 동기화 배치 */ @Configuration public class MaterialConfiguration implements JobExecutionListener { private final DisplayItemService displayItemService; private final InterfaceQsp interfaceQsp; List itemSyncList; @Value("${qsp.master-material-batch-url}") private String qspInterfaceUrl; @Value("${qsp.master-material-batch-page-size:1000}") private int pageSize; public MaterialConfiguration(DisplayItemService displayItemService, InterfaceQsp interfaceQsp) { this.displayItemService = displayItemService; this.interfaceQsp = interfaceQsp; } @Bean public Job materialJob(JobRepository jobRepository, Step materialStep) { return new JobBuilder("materialJob", jobRepository).start(materialStep).build(); } @Bean public Step materialStep( JobRepository jobRepository, PlatformTransactionManager transactionManager) throws Exception { return new StepBuilder("materialStep", jobRepository) .chunk(100, transactionManager) .reader(materialReader()) .processor(materialProcessor()) .writer(materialWriter()) .build(); } @Bean @StepScope public ListItemReader materialReader() throws Exception { List aggregated = new ArrayList<>(); int page = 1; while (true) { Map params = new HashMap<>(); params.put("allYn", "N"); params.put("page", page); params.put("size", pageSize); List pageItems = interfaceQsp.callApiData( HttpMethod.GET, qspInterfaceUrl, params, new TypeReference>() {}); if (pageItems == null || pageItems.isEmpty()) { break; } aggregated.addAll(pageItems); if (pageItems.size() < pageSize) { break; } page++; } this.itemSyncList = aggregated; return (itemSyncList != null) ? new ListItemReader<>(itemSyncList) : new ListItemReader<>(Collections.emptyList()); } @Bean public ItemProcessor materialProcessor() { return item -> item; } @Bean public ItemWriter materialWriter() { return items -> { displayItemService.setItemSyncSave((List) items.getItems()); }; } }