공통코드 배치

This commit is contained in:
basssy 2024-11-10 18:30:52 +09:00
parent 51ab84aea3
commit e2f164d357
11 changed files with 518 additions and 66 deletions

View File

@ -2,7 +2,6 @@ package com.interplug.qcast.batch;
import java.util.Date;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
@ -15,6 +14,7 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
@ -34,22 +34,16 @@ public class JobLauncherController {
* @throws JobRestartException
*/
@GetMapping("/batch/job/{jobName}") // Path Variable로 jobName을 받음
public String launchJob(@PathVariable String jobName)
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
public String launchJob(@PathVariable String jobName) throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
Job job = jobs.get(jobName);
if (job == null) {
return "Job " + jobName + " not found";
}
JobParameters jobParameters =
new JobParametersBuilder()
.addString("jobName", jobName)
.addDate("time", new Date())
.toJobParameters();
JobParameters jobParameters = new JobParametersBuilder().addString("jobName", jobName)
.addDate("time", new Date()).toJobParameters();
jobLauncher.run(job, jobParameters);
@ -66,11 +60,8 @@ public class JobLauncherController {
* @throws JobRestartException
*/
@Scheduled(cron = "0 55 23 * * *")
public String scheduleJobLauncher()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
public String scheduleJobLauncher() throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
String jobName = "sampleOtherJob";
Job job = jobs.get(jobName);
@ -78,11 +69,8 @@ public class JobLauncherController {
return "Job " + jobName + " not found";
}
JobParameters jobParameters =
new JobParametersBuilder()
.addString("jobName", jobName)
.addDate("time", new Date())
.toJobParameters();
JobParameters jobParameters = new JobParametersBuilder().addString("jobName", jobName)
.addDate("time", new Date()).toJobParameters();
jobLauncher.run(job, jobParameters);
@ -98,13 +86,10 @@ public class JobLauncherController {
* @throws JobParametersInvalidException
* @throws JobRestartException
*/
// @Scheduled(cron = "*/5 * * * * *")
// @Scheduled(cron = "*/5 * * * * *")
@Scheduled(cron = "0 55 23 * * *")
public String storeAdditionalInfoJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
public String storeAdditionalInfoJob() throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
String jobName = "storeAdditionalJob";
Job job = jobs.get(jobName);
@ -129,11 +114,8 @@ public class JobLauncherController {
* @throws JobRestartException
*/
@Scheduled(cron = "0 0 0 * * *")
public String materialJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
public String materialJob() throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
String jobName = "materialJob";
Job job = jobs.get(jobName);
@ -159,11 +141,8 @@ public class JobLauncherController {
* @throws JobRestartException
*/
@Scheduled(cron = "0 0 0 * * *")
public String bomJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
public String bomJob() throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
String jobName = "bomJob";
Job job = jobs.get(jobName);
@ -189,11 +168,8 @@ public class JobLauncherController {
* @throws JobRestartException
*/
@Scheduled(cron = "0 0 0 * * *")
public String businessChargerJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
public String businessChargerJob() throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
String jobName = "businessChargerJob";
Job job = jobs.get(jobName);
@ -219,11 +195,8 @@ public class JobLauncherController {
* @throws JobRestartException
*/
@Scheduled(cron = "0 0 0 * * *")
public String adminUserJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
public String adminUserJob() throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
String jobName = "adminUserJob";
Job job = jobs.get(jobName);
@ -249,11 +222,8 @@ public class JobLauncherController {
* @throws JobRestartException
*/
@Scheduled(cron = "0 0 0 * * *")
public String priceJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
public String priceJob() throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
String jobName = "priceJob";
Job job = jobs.get(jobName);
@ -268,4 +238,30 @@ public class JobLauncherController {
return "OK";
}
/**
* 공통코드 M_COMM_H, M_COMM_L 동기화 배치
*
* @return
* @throws JobInstanceAlreadyCompleteException
* @throws JobExecutionAlreadyRunningException
* @throws JobParametersInvalidException
* @throws JobRestartException
*/
@Scheduled(cron = "0 0 0 * * *")
public String commonCodeJob() throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
String jobName = "commonCodeJob";
Job job = jobs.get(jobName);
if (job == null) {
return "Job " + jobName + " not found";
}
JobParameters jobParameters =
new JobParametersBuilder().addDate("time", new Date()).toJobParameters();
jobLauncher.run(job, jobParameters);
return "OK";
}
}

View File

@ -0,0 +1,138 @@
package com.interplug.qcast.batch.system;
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());
} 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 <T> Step buildStep(String stepName, JobRepository jobRepository,
PlatformTransactionManager transactionManager, ItemReader<T> reader, ItemWriter<T> writer) {
return new StepBuilder(stepName, jobRepository).<T, T>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 <T> ListItemReader<T> createReader(List<T> items, String readerName) {
log.info("{}Reader 호출됨...", readerName);
return new ListItemReader<>(items != null ? items : Collections.emptyList());
}
@Bean
@StepScope
public ListItemReader<HeadCodeRequest> headCodeListReader() {
return createReader(
commonCodeSyncResponse != null ? commonCodeSyncResponse.getApiHeadCdList() : null,
"headCode");
}
@Bean
@StepScope
public ListItemReader<DetailCodeRequest> commonCodeListReader() {
return createReader(
commonCodeSyncResponse != null ? commonCodeSyncResponse.getApiCommCdList() : null,
"commonCode");
}
private <T> ItemWriter<T> createWriter(Consumer<List<T>> processor, String writerName) {
return items -> {
try {
List<T> itemList = (List<T>) items.getItems();
processor.accept(itemList);
log.info("{}Writer: {} items 처리 완료", writerName, items.size());
} catch (Exception e) {
log.error("{}Writer 오류: {}", writerName, e.getMessage());
throw e;
}
};
}
}

View File

@ -3,14 +3,70 @@ package com.interplug.qcast.biz.commCode;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.interplug.qcast.biz.commCode.dto.CodeRes;
import com.interplug.qcast.biz.commCode.dto.DetailCodeRequest;
import com.interplug.qcast.biz.commCode.dto.HeadCodeRequest;
@Mapper
public interface CommCodeMapper {
/**
* Qcast 공통코드 저장시 실시간 동기화
*
* @param codeRes
* @return
*/
int setCommHUpdate(CodeRes codeRes);
/**
* Qcast 공통코드 저장시 실시간 동기화
*
* @param codeRes
* @return
*/
int setCommLUpdate(CodeRes codeRes);
/**
* QCast에서 사용하는 공통코드 조회
*
* @return
*/
List<CodeRes> selectQcastCommCode();
/**
* 배치 공통코드상세 테이블 사용플래그 변경
*
* @return
* @throws Exception
*/
int deleteCommonCodeSync() throws Exception;
/**
* 배치 공통코드헤더 테이블 사용플래그 변경
*
* @return
* @throws Exception
*/
int deleteHeadCodeSync() throws Exception;
/**
* 배치 공통코드 헤더 정보 동기화 저장
*
* @param headCodeReq
* @return
* @throws Exception
*/
int setHeadCodeSyncSave(HeadCodeRequest headCodeReq) throws Exception;
/**
* 배치 공통코드 상세 정보 동기화 저장
*
* @param detailCodeReq
* @return
* @throws Exception
*/
int setCommonCodeSyncSave(DetailCodeRequest detailCodeReq) throws Exception;
}

View File

@ -1,13 +1,17 @@
package com.interplug.qcast.biz.commCode;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;
import com.interplug.qcast.biz.commCode.dto.CodeReq;
import com.interplug.qcast.biz.commCode.dto.CodeRes;
import com.interplug.qcast.biz.commCode.dto.CommCodeRes;
import java.util.ArrayList;
import java.util.List;
import com.interplug.qcast.biz.commCode.dto.DetailCodeRequest;
import com.interplug.qcast.biz.commCode.dto.HeadCodeRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
@RequiredArgsConstructor
public class CommCodeService {
@ -49,17 +53,48 @@ public class CommCodeService {
public List<CommCodeRes> selectQcastCommCode() {
List<CodeRes> result = commCodeMapper.selectQcastCommCode();
List<CommCodeRes> commCodeList = new ArrayList<>();
result.forEach(
cr -> {
commCodeList.add(
CommCodeRes.builder()
.clHeadCd(cr.getClHeadCd())
.clCode(cr.getClCode())
.clCodeNm(cr.getClCodeNm())
.clCodeJp(cr.getClCodeJp())
.clPriority(cr.getClPriority())
.build());
});
result.forEach(cr -> {
commCodeList.add(CommCodeRes.builder().clHeadCd(cr.getClHeadCd()).clCode(cr.getClCode())
.clCodeNm(cr.getClCodeNm()).clCodeJp(cr.getClCodeJp()).clPriority(cr.getClPriority())
.build());
});
return commCodeList;
}
/**
* 헤더코드 동기화
*
* @param headCodeList
* @throws Exception
*/
public void setHeaderCodeSyncSave(List<HeadCodeRequest> headCodeList) throws Exception {
// 헤더코드 동기화
commCodeMapper.deleteHeadCodeSync();
for (HeadCodeRequest headCodeReq : headCodeList) {
try {
commCodeMapper.setHeadCodeSyncSave(headCodeReq);
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
/**
* 상세코드 동기화
*
* @param detailCodeList
* @throws Exception
*/
public void setCommonCodeSyncSave(List<DetailCodeRequest> detailCodeList) throws Exception {
// 상세코드 동기화
commCodeMapper.deleteCommonCodeSync();
for (DetailCodeRequest detailCodeReq : detailCodeList) {
try {
commCodeMapper.setCommonCodeSyncSave(detailCodeReq);
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
}

View File

@ -0,0 +1,17 @@
package com.interplug.qcast.biz.commCode.dto;
import java.util.List;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class CommonCodeSyncResponse {
@Schema(description = "공통코드 H 목록")
private List<HeadCodeRequest> apiHeadCdList;
@Schema(description = "공통코드 L 목록")
private List<DetailCodeRequest> apiCommCdList;
}

View File

@ -0,0 +1,27 @@
package com.interplug.qcast.biz.commCode.dto;
import lombok.Data;
@Data
public class DetailCodeRequest {
private String headCd;
private String code;
private String readCd;
private String codeNm;
private String codeJp;
private String code4Th;
private String refChr1;
private String refChr2;
private String refChr3;
private String refChr4;
private String refChr5;
private Integer refNum1;
private Integer refNum2;
private Integer refNum3;
private Integer refNum4;
private Integer refNum5;
private Integer priority;
private String refCnt;
private String statCd;
private Integer delFlg;
}

View File

@ -0,0 +1,24 @@
package com.interplug.qcast.biz.commCode.dto;
import lombok.Data;
@Data
public class HeadCodeRequest {
private String headCd;
private String headId;
private String headNm;
private String headJp;
private String head4Th;
private String refChr1;
private String refChr2;
private String refChr3;
private String refChr4;
private String refChr5;
private String refNum1;
private String refNum2;
private String refNum3;
private String refNum4;
private String refNum5;
private String remarks;
private Integer delFlg;
}

View File

@ -47,6 +47,7 @@ qsp:
simulation-guide-info-url: /api/simulation/guideInfo
aes256.key: jpqcellQ123456!!
auto.login.aes256.key: _autoL!!
system-commonCode-batch-url: /api/system/commonCodeListData
#File
file:
root.path: C:\\

View File

@ -47,6 +47,7 @@ qsp:
simulation-guide-info-url: /api/simulation/guideInfo
aes256.key: jpqcellQ123456!!
auto.login.aes256.key: _autoL!!
system-commonCode-batch-url: /api/system/commonCodeListData
#File
file:

View File

@ -47,6 +47,7 @@ qsp:
simulation-guide-info-url: /api/simulation/guideInfo
aes256.key: jpqcellQ123456!!
auto.login.aes256.key: _autoL!!
system-commonCode-batch-url: /api/system/commonCodeListData
#File
file:

View File

@ -171,4 +171,160 @@
ORDER BY A.CL_HEAD_CD, A.CL_PRIORITY
</select>
<delete id="deleteCommonCodeSync" parameterType="com.interplug.qcast.biz.commCode.dto.DetailCodeRequest">
/* sqlid : com.interplug.qcast.commCode.deleteCommonCodeSync (배치 공통코드상세 테이블 사용플래그 변경)*/
UPDATE M_COMM_L SET DEL_FLG = '1'
</delete>
<delete id="deleteHeadCodeSync" parameterType="com.interplug.qcast.biz.commCode.dto.HeadCodeRequest">
/* sqlid : com.interplug.qcast.commCode.deleteHeadCodeSync (배치 공통코드헤더 테이블 사용플래그 변경)*/
UPDATE M_COMM_H SET DEL_FLG = '1'
</delete>
<insert id="setHeadCodeSyncSave" parameterType="com.interplug.qcast.biz.commCode.dto.HeadCodeRequest">
/* sqlid : com.interplug.qcast.commCode.setHeadCodeSyncSave (배치 공통코드 헤더 정보 동기화 저장)*/
MERGE M_COMM_H AS A
USING
( SELECT #{headCd} AS HEAD_CD ) AS D
ON (A.HEAD_CD = D.HEAD_CD
)
WHEN MATCHED THEN
UPDATE SET
HEAD_ID = #{headId}
, HEAD_NM = #{headNm}
, HEAD_JP = #{headJp}
, HEAD_4TH = #{head4Th}
, REF_CHR1 = #{refChr1}
, REF_CHR2 = #{refChr2}
, REF_CHR3 = #{refChr3}
, REF_CHR4 = #{refChr4}
, REF_CHR5 = #{refChr5}
, REF_NUM1 = #{refNum1}
, REF_NUM2 = #{refNum2}
, REF_NUM3 = #{refNum3}
, REF_NUM4 = #{refNum4}
, REF_NUM5 = #{refNum5}
, REMARKS = #{remarks}
, DEL_FLG = #{delFlg}
, LAST_EDIT_DATETIME = GETDATE()
WHEN NOT MATCHED THEN
INSERT (
HEAD_CD
, HEAD_ID
, HEAD_NM
, HEAD_JP
, HEAD_4TH
, REF_CHR1
, REF_CHR2
, REF_CHR3
, REF_CHR4
, REF_CHR5
, REF_NUM1
, REF_NUM2
, REF_NUM3
, REF_NUM4
, REF_NUM5
, REMARKS
, DEL_FLG
, REGIST_DATETIME
, LAST_EDIT_DATETIME
) VALUES (
#{headCd}
, #{headId}
, #{headNm}
, #{headJp}
, #{head4Th}
, #{refChr1}
, #{refChr2}
, #{refChr3}
, #{refChr4}
, #{refChr5}
, #{refNum1}
, #{refNum2}
, #{refNum3}
, #{refNum4}
, #{refNum5}
, #{remarks}
, #{delFlg}
, GETDATE()
, GETDATE()
);
</insert>
<insert id="setCommonCodeSyncSave" parameterType="com.interplug.qcast.biz.commCode.dto.DetailCodeRequest">
/* sqlid : com.interplug.qcast.commCode.setCommonCodeSyncSave (배치 공통코드 상세 정보 동기화 저장)*/
MERGE M_COMM_L AS A
USING
( SELECT #{headCd} AS HEAD_CD, #{code} AS CODE ) AS D
ON (A.HEAD_CD = D.HEAD_CD AND A.CODE = D.CODE
)
WHEN MATCHED THEN
UPDATE SET
CODE = #{code}
, READ_CD = #{readCd}
, CODE_NM = #{codeNm}
, CODE_JP = #{codeJp}
, CODE_4TH = #{code4Th}
, REF_CHR1 = #{refChr1}
, REF_CHR2 = #{refChr2}
, REF_CHR3 = #{refChr3}
, REF_CHR4 = #{refChr4}
, REF_CHR5 = #{refChr5}
, REF_NUM1 = #{refNum1}
, REF_NUM2 = #{refNum2}
, REF_NUM3 = #{refNum3}
, REF_NUM4 = #{refNum4}
, REF_NUM5 = #{refNum5}
, PRIORITY = #{priority}
, REF_CNT = #{refCnt}
, DEL_FLG = #{delFlg}
, LAST_EDIT_DATETIME = GETDATE()
WHEN NOT MATCHED THEN
INSERT (
HEAD_CD
, CODE
, READ_CD
, CODE_NM
, CODE_JP
, CODE_4TH
, REF_CHR1
, REF_CHR2
, REF_CHR3
, REF_CHR4
, REF_CHR5
, REF_NUM1
, REF_NUM2
, REF_NUM3
, REF_NUM4
, REF_NUM5
, PRIORITY
, REF_CNT
, DEL_FLG
, REGIST_DATETIME
, LAST_EDIT_DATETIME
) VALUES (
#{headCd}
, #{code}
, #{readCd}
, #{codeNm}
, #{codeJp}
, #{code4Th}
, #{refChr1}
, #{refChr2}
, #{refChr3}
, #{refChr4}
, #{refChr5}
, #{refNum1}
, #{refNum2}
, #{refNum3}
, #{refNum4}
, #{refNum5}
, #{priority}
, #{refCnt}
, #{delFlg}
, GETDATE()
, GETDATE()
);
</insert>
</mapper>