store 배치 수정

This commit is contained in:
DESKTOP-6ARNG1Q\dlsgk 2024-11-08 14:45:29 +09:00
parent e3b78204c2
commit d3bd562d80
4 changed files with 125 additions and 115 deletions

View File

@ -98,8 +98,8 @@ public class JobLauncherController {
* @throws JobParametersInvalidException
* @throws JobRestartException
*/
// @Scheduled(cron = "*/30 * * * * *")
@Scheduled(cron = "0 0 0 * * *")
// @Scheduled(cron = "*/5 * * * * *")
@Scheduled(cron = "0 55 23 * * *")
public String storeAdditionalInfoJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
@ -111,7 +111,6 @@ public class JobLauncherController {
if (job == null) {
return "Job " + jobName + " not found";
}
JobParameters jobParameters =
new JobParametersBuilder().addDate("time", new Date()).toJobParameters();

View File

@ -1,24 +1,19 @@
package com.interplug.qcast.batch.master;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.interplug.qcast.biz.displayItem.DisplayItemMapper;
import com.interplug.qcast.biz.storeFavorite.StoreFavoriteMapper;
import com.interplug.qcast.biz.storeFavorite.StoreFavoriteService;
import com.interplug.qcast.biz.storeFavorite.dto.StoreFavoriteRequest;
import com.interplug.qcast.biz.user.UserMapper;
import com.interplug.qcast.biz.user.UserService;
import com.interplug.qcast.biz.user.dto.StoreRequest;
import com.interplug.qcast.biz.user.dto.StoreSyncResponse;
import com.interplug.qcast.biz.user.dto.SyncResponse;
import com.interplug.qcast.biz.user.dto.UserRequest;
import com.interplug.qcast.util.InterfaceQsp;
import jakarta.annotation.PostConstruct;
import java.util.Collections;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import java.util.List;
import org.springframework.batch.core.*;
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.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
@ -28,38 +23,38 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.transaction.PlatformTransactionManager;
/** chunk 방식의 Job을 생성하는 Configuration */
@Configuration
public class StoreJobConfiguration {
public class StoreJobConfiguration implements JobExecutionListener {
private final InterfaceQsp interfaceQsp;
private final UserMapper userMapper;
private final StoreFavoriteMapper storeFavoriteMapper;
private final DisplayItemMapper displayItemMapper;
@Value("${qsp.url}")
private String qspUrl;
private final UserService userService;
private final StoreFavoriteService storeFavService;
@Value("${qsp.master-store-batch-url}")
private String qspMasterStoreBatchUrl;
private StoreSyncResponse storeSyncResponse;
public StoreJobConfiguration(
InterfaceQsp interfaceQsp,
UserMapper userMapper,
StoreFavoriteMapper storeFavoriteMapper,
DisplayItemMapper displayItemMapper) {
InterfaceQsp interfaceQsp, UserService userService, StoreFavoriteService storeFavService) {
this.interfaceQsp = interfaceQsp;
this.userMapper = userMapper;
this.storeFavoriteMapper = storeFavoriteMapper;
this.displayItemMapper = displayItemMapper;
this.userService = userService;
this.storeFavService = storeFavService;
}
private StoreSyncResponse storeSyncResponse; // 데이터를 저장할 필드
@PostConstruct
public void init() throws Exception {
// 애플리케이션 시작 fetchData를 번만 호출하여 데이터 로드
this.storeSyncResponse = fetchData();
@Override
public void beforeJob(JobExecution jobExecution) {
System.out.println("Job 시작: 초기화 메서드 호출 중...");
try {
this.storeSyncResponse =
interfaceQsp.callApiData(
HttpMethod.GET, qspMasterStoreBatchUrl, null, StoreSyncResponse.class);
System.out.println(
"API 호출을 통해 storeSyncResponse 갱신 완료, 항목 수: "
+ this.storeSyncResponse.getStoreList().size());
} catch (Exception e) {
System.err.println("storeSyncResponse를 갱신하는 중 오류 발생: " + e.getMessage());
}
}
@Bean
@ -69,132 +64,104 @@ public class StoreJobConfiguration {
.start(storeStep)
.next(userStep)
.next(favoriteStep)
.listener(this)
.build();
}
@Bean
public Step storeStep(JobRepository jobRepository, PlatformTransactionManager transactionManager)
throws Exception {
public Step storeStep(
JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("storeStep", jobRepository)
.<StoreRequest, StoreRequest>chunk(10, transactionManager)
.reader(storeListReader())
.processor(storeProcessor())
.writer(storeWriter())
.build();
}
@Bean
public Step userStep(JobRepository jobRepository, PlatformTransactionManager transactionManager)
throws Exception {
public Step userStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("userStep", jobRepository)
.<UserRequest, UserRequest>chunk(10, transactionManager)
.reader(userListReader())
.processor(userProcessor())
.writer(userWriter())
.build();
}
@Bean
public Step favoriteStep(
JobRepository jobRepository, PlatformTransactionManager transactionManager) throws Exception {
JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("favoriteStep", jobRepository)
.<StoreFavoriteRequest, StoreFavoriteRequest>chunk(10, transactionManager)
.reader(storeFavListReader())
.processor(favoriteProcessor())
.writer(favoriteWriter())
.build();
}
private StoreSyncResponse fetchData() throws Exception {
// 데이터 읽기
SyncResponse syncResponse = new SyncResponse();
StoreSyncResponse storeSyncResponse = new StoreSyncResponse();
String strResponse =
interfaceQsp.callApi(HttpMethod.GET, qspUrl + qspMasterStoreBatchUrl, null);
if (!"".equals(strResponse)) {
ObjectMapper om =
new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
syncResponse = om.readValue(strResponse, SyncResponse.class);
// 'data' 필드를 직접 사용하여 BatchResponse로 변환
if (syncResponse.getData() != null) {
String dataJson = om.writeValueAsString(syncResponse.getData());
// data를 JSON 문자열로 변환
storeSyncResponse = om.readValue(dataJson, StoreSyncResponse.class);
}
}
return storeSyncResponse;
@Bean
@StepScope
public ItemReader<StoreRequest> storeListReader() {
System.out.println("storeListReader 호출됨...");
return (storeSyncResponse != null && storeSyncResponse.getStoreList() != null)
? new ListItemReader<>(storeSyncResponse.getStoreList())
: new ListItemReader<>(Collections.emptyList());
}
@Bean
public ItemReader<StoreRequest> storeListReader() throws Exception {
if (storeSyncResponse.getStoreList() == null) {
storeSyncResponse.setStoreList(Collections.emptyList());
}
return new ListItemReader<>(storeSyncResponse.getStoreList());
@StepScope
public ItemReader<UserRequest> userListReader() {
System.out.println("userListReader 호출됨...");
return (storeSyncResponse != null && storeSyncResponse.getUserList() != null)
? new ListItemReader<>(storeSyncResponse.getUserList())
: new ListItemReader<>(Collections.emptyList());
}
@Bean
public ItemReader<UserRequest> userListReader() throws Exception {
if (storeSyncResponse.getUserList() == null) {
storeSyncResponse.setUserList(Collections.emptyList());
}
return new ListItemReader<>(storeSyncResponse.getUserList());
}
@Bean
public ItemReader<StoreFavoriteRequest> storeFavListReader() throws Exception {
if (storeSyncResponse.getStoreFavList() == null) {
storeSyncResponse.setStoreFavList(Collections.emptyList());
}
return new ListItemReader<>(storeSyncResponse.getStoreFavList());
}
@Bean
public ItemProcessor<StoreRequest, StoreRequest> storeProcessor() {
return item -> {
userMapper.setStoreSave(item); // 판매정 정보 동기화
userMapper.setStoreSapCdSave(item); // 판매점 custCd 동기화
userMapper.setStoreNorthModuleSave(item);
System.out.println("Processing store: " + item);
return item;
};
}
@Bean
public ItemProcessor<UserRequest, UserRequest> userProcessor() {
return item -> {
userMapper.setUserSave(item);
System.out.println("Processing user: " + item);
return item;
};
}
@Bean
public ItemProcessor<StoreFavoriteRequest, StoreFavoriteRequest> favoriteProcessor() {
return item -> {
storeFavoriteMapper.setStoreFavoriteSave(item);
System.out.println("Processing favorite: " + item);
return item;
};
@StepScope
public ItemReader<StoreFavoriteRequest> storeFavListReader() {
System.out.println("storeFavListReader 호출됨...");
return (storeSyncResponse != null && storeSyncResponse.getStoreFavList() != null)
? new ListItemReader<>(storeSyncResponse.getStoreFavList())
: new ListItemReader<>(Collections.emptyList());
}
@Bean
public ItemWriter<StoreRequest> storeWriter() {
return items -> items.forEach(item -> System.out.println("Writing store: " + item));
return items -> {
try {
List<StoreRequest> storeRequestList =
(List<StoreRequest>) items.getItems(); // Chunk에서 List로 추출
userService.setStoreBatch(storeRequestList); // 서비스에 List를 번에 전달
System.out.println("storeWriter: " + items.size() + " items 처리 완료");
} catch (Exception e) {
System.err.println("storeWriter 오류: " + e.getMessage());
}
};
}
@Bean
public ItemWriter<UserRequest> userWriter() {
return items -> items.forEach(item -> System.out.println("Writing user: " + item));
return items -> {
try {
List<UserRequest> userRequestList = (List<UserRequest>) items.getItems();
userService.setUserBatch(userRequestList);
System.out.println("userWriter: " + items.size() + " items 처리 완료");
} catch (Exception e) {
System.err.println("userWriter 오류: " + e.getMessage());
}
};
}
@Bean
public ItemWriter<StoreFavoriteRequest> favoriteWriter() {
return items -> items.forEach(item -> System.out.println("Writing favorite: " + item));
return items -> {
try {
List<StoreFavoriteRequest> storeFavoriteList =
(List<StoreFavoriteRequest>) items.getItems();
storeFavService.setStoreFavoriteBatch(storeFavoriteList);
System.out.println("favoriteWriter: " + items.size() + " items 처리 완료");
} catch (Exception e) {
System.err.println("favoriteWriter 오류: " + e.getMessage());
}
};
}
}

View File

@ -8,13 +8,16 @@ import com.interplug.qcast.config.Exception.ErrorCode;
import com.interplug.qcast.config.Exception.QcastException;
import com.interplug.qcast.config.message.Messages;
import com.interplug.qcast.util.InterfaceQsp;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;
@Slf4j
@Service
@RequiredArgsConstructor
public class StoreFavoriteService {
@ -77,4 +80,15 @@ public class StoreFavoriteService {
}
return response;
}
public void setStoreFavoriteBatch(List<StoreFavoriteRequest> storeFavList) throws Exception {
// 즐겨찾기 동기화
for (StoreFavoriteRequest storeFavoriteRequest : storeFavList) {
try {
storeFavoriteMapper.setStoreFavoriteSave(storeFavoriteRequest);
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
}

View File

@ -4,8 +4,10 @@ import com.interplug.qcast.biz.user.dto.StoreRequest;
import com.interplug.qcast.biz.user.dto.UserRequest;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
@RequiredArgsConstructor
public class UserService {
@ -52,4 +54,32 @@ public class UserService {
public int setStoreSapCdSave(StoreRequest storeReq) throws Exception {
return userMapper.setStoreSapCdSave(storeReq);
}
/**
* @param storeList
* @throws Exception
*/
public void setStoreBatch(List<StoreRequest> storeList) throws Exception {
// 판매점 동기화
for (StoreRequest storeRequest : storeList) {
try {
userMapper.setStoreSave(storeRequest);
userMapper.setStoreSapCdSave(storeRequest);
userMapper.setStoreNorthModuleSave(storeRequest);
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
public void setUserBatch(List<UserRequest> userList) throws Exception {
// 사용자 동기화
for (UserRequest userRequest : userList) {
try {
userMapper.setUserSave(userRequest);
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
}