refactor: API에서 batch모듈 제거
parent
6d05fcaf45
commit
dccf7a2fb7
@ -1,38 +0,0 @@
|
|||||||
package kr.xit.core.biz.batch;
|
|
||||||
|
|
||||||
import org.springframework.batch.core.JobParameters;
|
|
||||||
import org.springframework.batch.core.JobParametersBuilder;
|
|
||||||
import org.springframework.batch.core.launch.support.RunIdIncrementer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* description : Spring Boot 2.0.x에서 발생하는 버그
|
|
||||||
* => 배치 Job이 실패할 경우 이후에 파라미터를 변경해도 계속 실패한 파라미터가 사용
|
|
||||||
* Spring Boot 2.1.0 이상부터는
|
|
||||||
* => 이전의 Job이 실행시 사용한 파라미터 중 하나가 다음 실행시 누락되면 누락된 파라미터를 재사용
|
|
||||||
* --> 넘어온 파라미터와 run.id만 사용
|
|
||||||
* .incrementer(new RunIdIncrementer()) -> .incrementer(new UniqueRunIdIncrementer())
|
|
||||||
*
|
|
||||||
* packageName : kr.xit.core.biz.batch
|
|
||||||
* fileName : CustomRunIdIncrementer
|
|
||||||
* author : limju
|
|
||||||
* date : 2023-05-16
|
|
||||||
* ======================================================================
|
|
||||||
* 변경일 변경자 변경 내용
|
|
||||||
* ----------------------------------------------------------------------
|
|
||||||
* 2023-05-16 limju 최초 생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
public class CustomRunIdIncrementer extends RunIdIncrementer {
|
|
||||||
private static final String RUN_ID = "run.id";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JobParameters getNext(JobParameters parameters) {
|
|
||||||
JobParameters params = (parameters == null) ? new JobParameters() : parameters;
|
|
||||||
return new JobParametersBuilder()
|
|
||||||
.addLong(RUN_ID, params.getLong(RUN_ID, 0L) + 1)
|
|
||||||
.toJobParameters();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
|||||||
package kr.xit.core.biz.batch;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* description : ItemReaderAdapter 를 사용한 List<T> 데이타의 read() 구현
|
|
||||||
* -> ItemReader 의 read
|
|
||||||
* ItemReaderAdapter의 targetObject 지정시 사용
|
|
||||||
* -> ItemReaderAdapter.setTargetObject(Object o)
|
|
||||||
* : new ListReader<>(대상목록-서비스 조회결과)
|
|
||||||
* : new ListReader<>(loggingService.findLogging(null))
|
|
||||||
* packageName : kr.xit.core.biz.batch
|
|
||||||
* fileName : ListReader
|
|
||||||
* author : limju
|
|
||||||
* date : 2023-05-16
|
|
||||||
* ======================================================================
|
|
||||||
* 변경일 변경자 변경 내용
|
|
||||||
* ----------------------------------------------------------------------
|
|
||||||
* 2023-05-16 limju 최초 생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
public class ListReader<T> {
|
|
||||||
private List<T> list;
|
|
||||||
|
|
||||||
public ListReader(List<T> list){
|
|
||||||
this.list = list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T read() {
|
|
||||||
if(list.isEmpty()){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return list.remove(0);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package kr.xit.core.biz.batch.listener;
|
|
||||||
|
|
||||||
import org.springframework.batch.core.ChunkListener;
|
|
||||||
import org.springframework.batch.core.scope.context.ChunkContext;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* description : Chunk 실행시 로그 출력
|
|
||||||
*
|
|
||||||
* packageName : kr.xit.core.biz.batch.listener
|
|
||||||
* fileName : CustomChunkListener
|
|
||||||
* author : limju
|
|
||||||
* date : 2023-05-16
|
|
||||||
* ======================================================================
|
|
||||||
* 변경일 변경자 변경 내용
|
|
||||||
* ----------------------------------------------------------------------
|
|
||||||
* 2023-05-16 limju 최초 생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
public class CustomChunkListener {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public ChunkListener chunkListener() {
|
|
||||||
return new ChunkListener() {
|
|
||||||
@Override
|
|
||||||
public void beforeChunk(ChunkContext context) {
|
|
||||||
log.info("↓ Chunk start");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterChunk(ChunkContext context) {
|
|
||||||
log.info("↑ Chunk end");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterChunkError(ChunkContext context) {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package kr.xit.core.biz.batch.listener;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.springframework.batch.core.listener.ItemListenerSupport;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class CustomItemListner extends ItemListenerSupport {
|
|
||||||
|
|
||||||
public void onReadError(Exception ex) {
|
|
||||||
log.error("onReadError", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onProcessError(Object item, Exception e) {
|
|
||||||
log.error("onProcessError", e);
|
|
||||||
super.onProcessError(item, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onWriteError(Exception ex, List item) {
|
|
||||||
log.error("onWriteError", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
package kr.xit.core.biz.batch.listener;
|
|
||||||
|
|
||||||
import org.springframework.batch.core.JobExecution;
|
|
||||||
import org.springframework.batch.core.listener.JobExecutionListenerSupport;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* description : Job 실행시 로그 출력
|
|
||||||
*
|
|
||||||
* packageName : kr.xit.core.biz.batch.listener
|
|
||||||
* fileName : CustomJobListener
|
|
||||||
* author : limju
|
|
||||||
* date : 2023-05-16
|
|
||||||
* ======================================================================
|
|
||||||
* 변경일 변경자 변경 내용
|
|
||||||
* ----------------------------------------------------------------------
|
|
||||||
* 2023-05-16 limju 최초 생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class CustomJobListener extends JobExecutionListenerSupport {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void beforeJob(JobExecution jobExecution) {
|
|
||||||
log.info("\n");
|
|
||||||
log.info("====================================================");
|
|
||||||
log.info("========== ↓ [{}] Job start ===========", jobExecution.getJobInstance().getJobName());
|
|
||||||
log.info("====================================================");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterJob(JobExecution jobExecution) {
|
|
||||||
log.info("===============================================================");
|
|
||||||
log.info("========== ↑ [{}] Job end :: {} ==========", jobExecution.getJobInstance().getJobName(), jobExecution.getStatus());
|
|
||||||
log.info("===============================================================");
|
|
||||||
log.info("\n");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package kr.xit.core.biz.batch.listener;
|
|
||||||
|
|
||||||
import org.springframework.batch.core.ExitStatus;
|
|
||||||
import org.springframework.batch.core.StepExecution;
|
|
||||||
import org.springframework.batch.core.StepExecutionListener;
|
|
||||||
import org.springframework.batch.core.listener.StepExecutionListenerSupport;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* description : step 실행시 로그 출력
|
|
||||||
*
|
|
||||||
* packageName : kr.xit.core.biz.batch.listener
|
|
||||||
* fileName : CustomStepListener
|
|
||||||
* author : limju
|
|
||||||
* date : 2023-05-16
|
|
||||||
* ======================================================================
|
|
||||||
* 변경일 변경자 변경 내용
|
|
||||||
* ----------------------------------------------------------------------
|
|
||||||
* 2023-05-16 limju 최초 생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class CustomStepListener extends StepExecutionListenerSupport {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void beforeStep(StepExecution stepExecution) {
|
|
||||||
log.info("##### ↓ [{}] Step start", stepExecution.getStepName());
|
|
||||||
//log.info("##### [{}-{}] Step is start", stepExecution.getJobExecution().getJobInstance().getJobName(), stepExecution.getStepName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExitStatus afterStep(StepExecution stepExecution) {
|
|
||||||
log.info("##### ↑ [{}] Step end :: {}", stepExecution.getStepName(), stepExecution.getStatus());
|
|
||||||
//log.info("##### [{}-{}] Step is completed {}", stepExecution.getJobExecution().getJobInstance().getJobName(), stepExecution.getStepName(), stepExecution.getStatus());
|
|
||||||
return stepExecution.getExitStatus();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package kr.xit.core.biz.batch.listener;
|
|
||||||
|
|
||||||
import org.springframework.batch.core.ExitStatus;
|
|
||||||
import org.springframework.batch.core.StepExecution;
|
|
||||||
import org.springframework.batch.core.listener.StepExecutionListenerSupport;
|
|
||||||
|
|
||||||
public class NoWorkFoundStepListener extends StepExecutionListenerSupport {
|
|
||||||
|
|
||||||
public ExitStatus afterStep(StepExecution stepExecution) {
|
|
||||||
if (stepExecution.getReadCount() == 0) {
|
|
||||||
return ExitStatus.FAILED;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
package kr.xit.core.biz.batch.mapper;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.egovframe.rte.psl.dataaccess.mapper.Mapper;
|
|
||||||
|
|
||||||
import kr.xit.core.biz.batch.model.BatchCmmDTO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* description :
|
|
||||||
*
|
|
||||||
* packageName : kr.xit.core.biz.batch.mapper
|
|
||||||
* fileName : IBatchCmmMapper
|
|
||||||
* author : limju
|
|
||||||
* date : 2023-05-16
|
|
||||||
* ======================================================================
|
|
||||||
* 변경일 변경자 변경 내용
|
|
||||||
* ----------------------------------------------------------------------
|
|
||||||
* 2023-05-16 limju 최초 생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface IBatchCmmMapper {
|
|
||||||
Optional<BatchCmmDTO> selectBatchLockByInstanceId(final String instanceId);
|
|
||||||
int insertBatchLock(final BatchCmmDTO dto);
|
|
||||||
int updateBatchLock(final BatchCmmDTO dto);
|
|
||||||
|
|
||||||
int insertBatchLog(final BatchCmmDTO dto);
|
|
||||||
int updateBatchLog(final BatchCmmDTO dto);
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
package kr.xit.core.biz.batch.model;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* description :
|
|
||||||
*
|
|
||||||
* packageName : kr.xit.core.biz.batch.model
|
|
||||||
* fileName : BatchCmmDTO
|
|
||||||
* author : limju
|
|
||||||
* date : 2023-05-16
|
|
||||||
* ======================================================================
|
|
||||||
* 변경일 변경자 변경 내용
|
|
||||||
* ----------------------------------------------------------------------
|
|
||||||
* 2023-05-16 limju 최초 생성
|
|
||||||
* 2023-06-15 limju 배치로그 추가
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Builder
|
|
||||||
public class BatchCmmDTO {
|
|
||||||
/**
|
|
||||||
* 배치 로그 ID
|
|
||||||
*/
|
|
||||||
private String batchLogId;
|
|
||||||
/**
|
|
||||||
* 배치 인스턴스 ID
|
|
||||||
*/
|
|
||||||
private String instanceId;
|
|
||||||
/**
|
|
||||||
* 배치 API trace ID
|
|
||||||
*/
|
|
||||||
private String traceId;
|
|
||||||
/**
|
|
||||||
* 실행 결과
|
|
||||||
*/
|
|
||||||
private String result;
|
|
||||||
/**
|
|
||||||
* 에러메세지
|
|
||||||
*/
|
|
||||||
private String message;
|
|
||||||
/**
|
|
||||||
* 배치 실행중 여부
|
|
||||||
*/
|
|
||||||
private String useYn;
|
|
||||||
|
|
||||||
//@Convert(converter = Jsr310.LocalDateTimeConverter.class)
|
|
||||||
@JsonDeserialize(using = LocalDateDeserializer.class)
|
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd kk:mm:ss.SSS")
|
|
||||||
private LocalDateTime registDt;
|
|
||||||
|
|
||||||
@JsonDeserialize(using = LocalDateDeserializer.class)
|
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd kk:mm:ss.SSS")
|
|
||||||
private LocalDateTime updateDt;
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
package kr.xit.core.biz.batch.service;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import kr.xit.core.biz.batch.mapper.IBatchCmmMapper;
|
|
||||||
import kr.xit.core.biz.batch.model.BatchCmmDTO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* description :
|
|
||||||
*
|
|
||||||
* packageName : kr.xit.core.biz.service
|
|
||||||
* fileName : BatchLockService
|
|
||||||
* author : limju
|
|
||||||
* date : 2023-05-18
|
|
||||||
* ======================================================================
|
|
||||||
* 변경일 변경자 변경 내용
|
|
||||||
* ----------------------------------------------------------------------
|
|
||||||
* 2023-05-18 limju 최초 생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class BatchCmmService extends EgovAbstractServiceImpl implements IBatchCmmService {
|
|
||||||
private final IBatchCmmMapper mapper;
|
|
||||||
|
|
||||||
public BatchCmmService(IBatchCmmMapper mapper) {
|
|
||||||
this.mapper = mapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(readOnly = true)
|
|
||||||
public Optional<BatchCmmDTO> findById(final String instanceId) {
|
|
||||||
return mapper.selectBatchLockByInstanceId(instanceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
|
||||||
public void addBatchLock(final BatchCmmDTO dto) {
|
|
||||||
mapper.insertBatchLock(dto);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
|
||||||
public void modifyBatchLock(final BatchCmmDTO dto) {
|
|
||||||
mapper.updateBatchLock(dto);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
|
||||||
public void addBatchLog(final BatchCmmDTO dto) {
|
|
||||||
mapper.insertBatchLog(dto);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
|
||||||
public void modifyBatchLog(final BatchCmmDTO dto) {
|
|
||||||
mapper.updateBatchLog(dto);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package kr.xit.core.biz.batch.service;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import kr.xit.core.biz.batch.model.BatchCmmDTO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* description :
|
|
||||||
*
|
|
||||||
* packageName : kr.xit.core.biz.service
|
|
||||||
* fileName : IBatchCmmService
|
|
||||||
* author : limju
|
|
||||||
* date : 2023-05-18
|
|
||||||
* ======================================================================
|
|
||||||
* 변경일 변경자 변경 내용
|
|
||||||
* ----------------------------------------------------------------------
|
|
||||||
* 2023-05-18 limju 최초 생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
public interface IBatchCmmService {
|
|
||||||
Optional<BatchCmmDTO> findById(final String instanceId);
|
|
||||||
void addBatchLock(final BatchCmmDTO dto);
|
|
||||||
void modifyBatchLock(final BatchCmmDTO dto);
|
|
||||||
|
|
||||||
void addBatchLog(final BatchCmmDTO dto);
|
|
||||||
void modifyBatchLog(final BatchCmmDTO dto);
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
package kr.xit.core.biz.batch.task;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.slf4j.MDC;
|
|
||||||
import org.springframework.batch.core.ExitStatus;
|
|
||||||
import org.springframework.batch.core.StepContribution;
|
|
||||||
import org.springframework.batch.core.scope.context.ChunkContext;
|
|
||||||
import org.springframework.batch.core.step.tasklet.Tasklet;
|
|
||||||
import org.springframework.batch.repeat.RepeatStatus;
|
|
||||||
|
|
||||||
import kr.xit.core.biz.batch.model.BatchCmmDTO;
|
|
||||||
import kr.xit.core.biz.batch.service.IBatchCmmService;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* description : 배치 종료시 lock table update
|
|
||||||
* 종료하는 배치 인스턴스의 사용여부(use_yn)를 미사용(N)으로 변경
|
|
||||||
*
|
|
||||||
* packageName : kr.xit.core.biz.batch.task
|
|
||||||
* fileName : BatchEndTasklet
|
|
||||||
* author : limju
|
|
||||||
* date : 2023-05-16
|
|
||||||
* ======================================================================
|
|
||||||
* 변경일 변경자 변경 내용
|
|
||||||
* ----------------------------------------------------------------------
|
|
||||||
* 2023-05-16 limju 최초 생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
* @see kr.xit.core.aop.TraceLoggerAspect
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class BatchEndTasklet implements Tasklet {
|
|
||||||
private final IBatchCmmService batchCmmService;
|
|
||||||
|
|
||||||
public BatchEndTasklet(IBatchCmmService batchCmmService) {
|
|
||||||
this.batchCmmService = batchCmmService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
|
|
||||||
String jobName = contribution.getStepExecution().getJobExecution().getJobInstance().getJobName();
|
|
||||||
contribution.setExitStatus(ExitStatus.COMPLETED);
|
|
||||||
BatchCmmDTO dto = BatchCmmDTO
|
|
||||||
.builder()
|
|
||||||
.instanceId(jobName)
|
|
||||||
.result(contribution.getExitStatus().getExitCode())
|
|
||||||
.useYn("N")
|
|
||||||
.batchLogId(MDC.get("batch_log_id"))
|
|
||||||
.traceId(StringUtils.defaultString(MDC.get("request_trace_id"), MDC.get("request_trace_batch_id")))
|
|
||||||
.build();
|
|
||||||
log.info("@@@@@@@@@@@@@{}", MDC.getCopyOfContextMap());
|
|
||||||
batchCmmService.modifyBatchLock(dto);
|
|
||||||
batchCmmService.modifyBatchLog(dto);
|
|
||||||
return RepeatStatus.FINISHED;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
package kr.xit.core.biz.batch.task;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.slf4j.MDC;
|
|
||||||
import org.springframework.batch.core.ExitStatus;
|
|
||||||
import org.springframework.batch.core.StepContribution;
|
|
||||||
import org.springframework.batch.core.scope.context.ChunkContext;
|
|
||||||
import org.springframework.batch.core.step.tasklet.Tasklet;
|
|
||||||
import org.springframework.batch.repeat.RepeatStatus;
|
|
||||||
|
|
||||||
import kr.xit.core.biz.batch.model.BatchCmmDTO;
|
|
||||||
import kr.xit.core.biz.batch.service.IBatchCmmService;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* description : 배치 종료시 lock table update
|
|
||||||
* 종료하는 배치 인스턴스의 사용여부(use_yn)를 미사용(N)으로 변경
|
|
||||||
*
|
|
||||||
* packageName : kr.xit.core.biz.batch.task
|
|
||||||
* fileName : BatchEndTasklet
|
|
||||||
* author : limju
|
|
||||||
* date : 2023-05-16
|
|
||||||
* ======================================================================
|
|
||||||
* 변경일 변경자 변경 내용
|
|
||||||
* ----------------------------------------------------------------------
|
|
||||||
* 2023-05-16 limju 최초 생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
* @see kr.xit.core.aop.TraceLoggerAspect
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class BatchFailEndTasklet implements Tasklet {
|
|
||||||
private final IBatchCmmService batchCmmService;
|
|
||||||
|
|
||||||
public BatchFailEndTasklet(IBatchCmmService batchCmmService) {
|
|
||||||
this.batchCmmService = batchCmmService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
|
|
||||||
String jobName = contribution.getStepExecution().getJobExecution().getJobInstance().getJobName();
|
|
||||||
contribution.setExitStatus(ExitStatus.FAILED);
|
|
||||||
BatchCmmDTO dto = BatchCmmDTO
|
|
||||||
.builder()
|
|
||||||
.instanceId(jobName)
|
|
||||||
.result(contribution.getExitStatus().getExitCode())
|
|
||||||
.useYn("N")
|
|
||||||
.batchLogId(MDC.get("batch_log_id"))
|
|
||||||
.traceId(StringUtils.defaultString(MDC.get("request_trace_id"), MDC.get("request_trace_batch_id")))
|
|
||||||
.build();
|
|
||||||
log.info("@@@@@@@@@@@@@{}", MDC.getCopyOfContextMap());
|
|
||||||
|
|
||||||
batchCmmService.modifyBatchLock(dto);
|
|
||||||
batchCmmService.modifyBatchLog(dto);
|
|
||||||
|
|
||||||
return RepeatStatus.FINISHED;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
package kr.xit.core.biz.batch.task;
|
|
||||||
|
|
||||||
import org.slf4j.MDC;
|
|
||||||
import org.springframework.batch.core.ExitStatus;
|
|
||||||
import org.springframework.batch.core.StepContribution;
|
|
||||||
import org.springframework.batch.core.scope.context.ChunkContext;
|
|
||||||
import org.springframework.batch.core.step.tasklet.Tasklet;
|
|
||||||
import org.springframework.batch.repeat.RepeatStatus;
|
|
||||||
|
|
||||||
import kr.xit.core.biz.batch.model.BatchCmmDTO;
|
|
||||||
import kr.xit.core.biz.batch.service.IBatchCmmService;
|
|
||||||
import kr.xit.core.support.utils.Checks;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* description : 배치 시작시 lock table insert or update
|
|
||||||
* 시작하는 배치 인스턴스의 사용여부(use_yn)를 사용(Y)으로 변경(생성)
|
|
||||||
* -> 사용여부가 사용(Y) 이면 실행중 이므로 배치 종료
|
|
||||||
*
|
|
||||||
* packageName : kr.xit.core.biz.batch.task
|
|
||||||
* fileName : BatchStartTasklet
|
|
||||||
* author : limju
|
|
||||||
* date : 2023-05-16
|
|
||||||
* ======================================================================
|
|
||||||
* 변경일 변경자 변경 내용
|
|
||||||
* ----------------------------------------------------------------------
|
|
||||||
* 2023-05-16 limju 최초 생성
|
|
||||||
* 2023-08-21 limju lock이 걸린 경우 release 하도록 변경 : 중복실행 되지 않도록 배치 시간 보장 전제
|
|
||||||
* </pre>
|
|
||||||
* @see kr.xit.core.aop.TraceLoggerAspect
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class BatchStartTasklet implements Tasklet {
|
|
||||||
private final IBatchCmmService batchCmmService;
|
|
||||||
|
|
||||||
public BatchStartTasklet(IBatchCmmService batchCmmService) {
|
|
||||||
this.batchCmmService = batchCmmService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
|
|
||||||
String jobName = contribution.getStepExecution().getJobExecution().getJobInstance().getJobName();
|
|
||||||
BatchCmmDTO dto = batchCmmService.findById(jobName)
|
|
||||||
.orElseGet(()-> BatchCmmDTO
|
|
||||||
.builder()
|
|
||||||
.build());
|
|
||||||
|
|
||||||
if(Checks.isEmpty(dto.getInstanceId())){
|
|
||||||
dto.setInstanceId(jobName);
|
|
||||||
dto.setResult(null);
|
|
||||||
dto.setUseYn("Y");
|
|
||||||
batchCmmService.addBatchLock(dto);
|
|
||||||
batchCmmService.addBatchLog(dto);
|
|
||||||
MDC.put("batch_log_id", dto.getBatchLogId());
|
|
||||||
}else{
|
|
||||||
if("Y".equals(dto.getUseYn())){
|
|
||||||
log.error("======= [{}] 배치 실행(사용) 중으로 종료 =======", jobName);
|
|
||||||
contribution.setExitStatus(ExitStatus.FAILED);
|
|
||||||
dto.setResult("배치 실행(사용) 중으로 종료");
|
|
||||||
// lock이 걸린 경우 reset : 2023-08-21
|
|
||||||
dto.setUseYn("N");
|
|
||||||
batchCmmService.modifyBatchLock(dto);
|
|
||||||
batchCmmService.addBatchLog(dto);
|
|
||||||
}else{
|
|
||||||
dto.setUseYn("Y");
|
|
||||||
dto.setResult(null);
|
|
||||||
batchCmmService.modifyBatchLock(dto);
|
|
||||||
batchCmmService.addBatchLog(dto);
|
|
||||||
MDC.put("batch_log_id", dto.getBatchLogId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return RepeatStatus.FINISHED;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,27 @@
|
|||||||
|
package kr.xit.ens.support.cmm.mapper;
|
||||||
|
|
||||||
|
import kr.xit.biz.ens.model.nice.NiceCiDTO.CrtfInfo;
|
||||||
|
import org.egovframe.rte.psl.dataaccess.mapper.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* description : 전자고지 공통 mapper
|
||||||
|
* - cache: CaffeineCache use
|
||||||
|
*
|
||||||
|
* packageName : kr.xit.ens.support.cmm.mapper
|
||||||
|
* fileName : ICmmEnsMapper
|
||||||
|
* author : limju
|
||||||
|
* date : 2023-09-12
|
||||||
|
* ======================================================================
|
||||||
|
* 변경일 변경자 변경 내용
|
||||||
|
* ----------------------------------------------------------------------
|
||||||
|
* 2023-09-12 limju 최초 생성
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface ICmmEnsMapper {
|
||||||
|
CrtfInfo selectNiceCrtfInfo(final CrtfInfo dto);
|
||||||
|
|
||||||
|
int updateNiceCrtfPublickey(final CrtfInfo dto);
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package kr.xit.ens.support.cmm.service;
|
||||||
|
|
||||||
|
import com.github.benmanes.caffeine.cache.Cache;
|
||||||
|
import com.github.benmanes.caffeine.cache.stats.CacheStats;
|
||||||
|
import kr.xit.biz.ens.model.nice.NiceCiDTO.CrtfInfo;
|
||||||
|
import kr.xit.ens.support.cmm.mapper.ICmmEnsMapper;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.cache.CacheManager;
|
||||||
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
|
import org.springframework.cache.caffeine.CaffeineCache;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Service
|
||||||
|
public class CmmEnsCacheService implements ICmmEnsCacheService {
|
||||||
|
private final ICmmEnsMapper cmmEnsMapper;
|
||||||
|
private final CacheManager cacheManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET Nice CI 인증 관련 정보
|
||||||
|
* @param signguCode
|
||||||
|
* @param ffnlgCode
|
||||||
|
* @param clientId
|
||||||
|
* @return CrtfInfo
|
||||||
|
*/
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
@Cacheable(cacheNames = "niceCrtfInfo", keyGenerator = "cacheKeyGenerator")
|
||||||
|
public CrtfInfo getNiceCrtfInfoCache(final String signguCode, final String ffnlgCode, final String clientId) {
|
||||||
|
return cmmEnsMapper.selectNiceCrtfInfo(CrtfInfo.builder()
|
||||||
|
.signguCode(signguCode)
|
||||||
|
.ffnlgCode(ffnlgCode)
|
||||||
|
.clientId(clientId)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
@CacheEvict(cacheNames = "niceCrtfInfo", keyGenerator = "cacheKeyGenerator")
|
||||||
|
public void removeNiceCrtfInfoCache(final String signguCode, final String ffnlgCode, final String clientId) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void logCache(){
|
||||||
|
if(!log.isDebugEnabled()) {
|
||||||
|
for(String cacheName : cacheManager.getCacheNames()) {
|
||||||
|
Cache cache = ((CaffeineCache) cacheManager.getCache(cacheName)).getNativeCache();
|
||||||
|
|
||||||
|
for(Object key : cache.asMap().keySet()) {
|
||||||
|
Object value = cache.getIfPresent(key);
|
||||||
|
log.info("key: {} - value: {}", key, value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
CacheStats stats = cache.stats();
|
||||||
|
log.info("cache '{}' - stats : {}", cacheName, stats.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package kr.xit.ens.support.cmm.service;
|
||||||
|
|
||||||
|
import kr.xit.biz.ens.model.nice.NiceCiDTO.CrtfInfo;
|
||||||
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* description : CaffeineCache 적용
|
||||||
|
*
|
||||||
|
* packageName : kr.xit.ens.support.cmm.service
|
||||||
|
* fileName : ICmmEnsCacheService
|
||||||
|
* author : limju
|
||||||
|
* date : 2023-09-12
|
||||||
|
* ======================================================================
|
||||||
|
* 변경일 변경자 변경 내용
|
||||||
|
* ----------------------------------------------------------------------
|
||||||
|
* 2023-09-12 limju 최초 생성
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public interface ICmmEnsCacheService {
|
||||||
|
CrtfInfo getNiceCrtfInfoCache(final String signguCode, final String ffnlgCode, final String clientId);
|
||||||
|
|
||||||
|
|
||||||
|
void removeNiceCrtfInfoCache(final String signguCode, final String ffnlgCode, final String clientId);
|
||||||
|
|
||||||
|
void logCache();
|
||||||
|
}
|
@ -1,17 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
||||||
<mapper namespace="kr.xit.biz.ens.mapper.IKkoMyDocMapper">
|
|
||||||
|
|
||||||
<select id="selectMobilePage" resultType="kr.xit.biz.ens.model.KkoMyDocDTO$MobilePageManage">
|
|
||||||
/** ens-mysql-mapper|selectMobilePage-모바일페이지콘텐트조회|julim */
|
|
||||||
SELECT tempm.sndng_detail_id
|
|
||||||
, tempm.sndng_se_code
|
|
||||||
, tempm.mobile_page_cn
|
|
||||||
FROM tb_ens_kakao_my_doc tekmd
|
|
||||||
JOIN tb_ens_mobile_page_manage tempm
|
|
||||||
ON tekmd.sndng_detail_id = tempm.sndng_detail_id
|
|
||||||
WHERE tekmd.unity_sndng_detail_id = #{external_document_uuid}
|
|
||||||
AND tekmd.document_binder_uuid = #{document_binder_uuid}
|
|
||||||
</select>
|
|
||||||
</mapper>
|
|
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="kr.xit.biz.ens.mapper.IKkoMyDocMapper">
|
||||||
|
|
||||||
|
<select id="selectMobilePage" resultType="kr.xit.biz.ens.model.KkoMyDocDTO$MobilePageManage">
|
||||||
|
/** ens-mysql-mapper|selectMobilePage-모바일페이지콘텐트조회|julim */
|
||||||
|
SELECT tempm.sndng_detail_id
|
||||||
|
, tempm.sndng_se_code
|
||||||
|
, tempm.mobile_page_cn
|
||||||
|
FROM tb_ens_kakao_my_doc tekmd
|
||||||
|
JOIN tb_ens_mobile_page_manage tempm
|
||||||
|
ON tekmd.sndng_detail_id = tempm.sndng_detail_id
|
||||||
|
WHERE tekmd.unity_sndng_detail_id = #{external_document_uuid}
|
||||||
|
AND tekmd.document_binder_uuid = #{document_binder_uuid}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
@ -1,68 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
||||||
|
|
||||||
<mapper namespace="kr.xit.core.biz.batch.mapper.IBatchCmmMapper">
|
|
||||||
<select id="selectBatchLockByInstanceId" resultType="kr.xit.core.biz.batch.model.BatchCmmDTO">
|
|
||||||
/** cmm-batch-mapper|findById-배치실행상태조회|julim */
|
|
||||||
SELECT instance_id
|
|
||||||
, use_yn
|
|
||||||
FROM tb_cmm_batch_lock
|
|
||||||
WHERE instance_id = #{instanceId}
|
|
||||||
-- FOR UPDATE
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<insert id="insertBatchLock">
|
|
||||||
/** cmm-batch-mapper|insertBatchLock-배치락 데이타 생성|julim */
|
|
||||||
INSERT INTO tb_cmm_batch_lock (
|
|
||||||
instance_id,
|
|
||||||
regist_dt,
|
|
||||||
use_yn
|
|
||||||
) VALUES (
|
|
||||||
#{instanceId},
|
|
||||||
NOW(3),
|
|
||||||
#{useYn}
|
|
||||||
)
|
|
||||||
</insert>
|
|
||||||
|
|
||||||
<insert id="updateBatchLock">
|
|
||||||
/** cmm-batch-mapper|updateBatchLock-배치 실행 상태 및 결과 반영|julim */
|
|
||||||
UPDATE tb_cmm_batch_lock
|
|
||||||
SET result = #{result}
|
|
||||||
, use_yn = #{useYn}
|
|
||||||
, updt_dt = NOW(3)
|
|
||||||
WHERE instance_id = #{instanceId}
|
|
||||||
</insert>
|
|
||||||
|
|
||||||
<insert id="insertBatchLog">
|
|
||||||
/** cmm-batch-mapper|insertBatchLog-배치 로그 데이타 생성|julim */
|
|
||||||
<selectKey keyProperty="batchLogId" resultType="string" order="BEFORE">
|
|
||||||
SELECT LPAD(NEXTVAL(tb_cmm_batch_log_seq), 20, '0')
|
|
||||||
</selectKey>
|
|
||||||
INSERT INTO tb_cmm_batch_log (
|
|
||||||
batch_log_id,
|
|
||||||
instance_id,
|
|
||||||
trace_id,
|
|
||||||
result,
|
|
||||||
message,
|
|
||||||
regist_dt
|
|
||||||
) VALUES (
|
|
||||||
#{batchLogId},
|
|
||||||
#{instanceId},
|
|
||||||
#{traceId},
|
|
||||||
#{result},
|
|
||||||
#{message},
|
|
||||||
NOW(3)
|
|
||||||
)
|
|
||||||
</insert>
|
|
||||||
|
|
||||||
<insert id="updateBatchLog">
|
|
||||||
/** cmm-batch-mapper|updateBatchLog-배치 결과 반영|julim */
|
|
||||||
UPDATE tb_cmm_batch_log
|
|
||||||
SET trace_id = IFNULL(#{traceId}, trace_id)
|
|
||||||
, result = IFNULL(#{result}, result)
|
|
||||||
, message = IFNULL(SUBSTRING(#{message}, 1, 100), message)
|
|
||||||
, updt_dt = NOW(3)
|
|
||||||
WHERE batch_log_id = #{batchLogId}
|
|
||||||
</insert>
|
|
||||||
</mapper>
|
|
@ -1,17 +1,12 @@
|
|||||||
package kr.xit.core.biz.model;
|
package kr.xit.biz.common;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.ToString;
|
|
||||||
import lombok.experimental.SuperBuilder;
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
Loading…
Reference in New Issue