feat: 시설 오라클 DB Merge 배치 추가(30분 마다)
parent
6f8e3a7aec
commit
664e7f64c3
@ -0,0 +1,113 @@
|
||||
package kr.xit.batch.ens.job;
|
||||
|
||||
import kr.xit.batch.ens.task.OtherMergeTasklet;
|
||||
import kr.xit.biz.ens.service.IEnsOtherMergeService;
|
||||
import kr.xit.core.biz.batch.CustomRunIdIncrementer;
|
||||
import kr.xit.core.biz.batch.listener.CustomJobListener;
|
||||
import kr.xit.core.biz.batch.listener.CustomStepListener;
|
||||
import kr.xit.core.biz.batch.listener.NoWorkFoundStepListener;
|
||||
import kr.xit.core.biz.batch.service.IBatchCmmService;
|
||||
import kr.xit.core.biz.batch.task.BatchEndTasklet;
|
||||
import kr.xit.core.biz.batch.task.BatchFailEndTasklet;
|
||||
import kr.xit.core.biz.batch.task.BatchStartTasklet;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
|
||||
import org.springframework.batch.core.configuration.annotation.JobScope;
|
||||
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description :
|
||||
*
|
||||
* packageName : kr.xit.batch.ens.job
|
||||
* fileName : OtherMergeJobConfig
|
||||
* author : jhseo
|
||||
* date : 2024-01-10
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2024-01-10 jhseo 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Configuration
|
||||
public class OtherMergeJobConfig {
|
||||
private static final String JOB_NAME = "OtherMergeJob";
|
||||
|
||||
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
|
||||
private final JobBuilderFactory jobBuilderFactory;
|
||||
private final StepBuilderFactory stepBuilderFactory;
|
||||
|
||||
private final IBatchCmmService lockService;
|
||||
private final IEnsOtherMergeService otherService;
|
||||
|
||||
@Bean(name = JOB_NAME)
|
||||
public Job otherMergeJob() {
|
||||
return jobBuilderFactory.get(JOB_NAME)
|
||||
.incrementer(new CustomRunIdIncrementer())
|
||||
.listener(new CustomJobListener())
|
||||
.listener(new CustomStepListener())
|
||||
.listener(new NoWorkFoundStepListener())
|
||||
|
||||
// JOB 시작
|
||||
// start() 결과가 FAILED 인경우 종료
|
||||
.start(start())
|
||||
.on("FAILED")
|
||||
.end()
|
||||
|
||||
// start()의 결과로 부터 FAILED를 제외한 모든 경우 to() 실행
|
||||
//.from(start())
|
||||
.on("*")
|
||||
.to(execution())
|
||||
.on("FAILED")
|
||||
.to(fail())
|
||||
|
||||
.from(execution())
|
||||
// to() 실행 결과와 상관 없이 end() 실행
|
||||
.on("*")
|
||||
.to(end())
|
||||
|
||||
// JOB 종료
|
||||
.end()
|
||||
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean(name = JOB_NAME + "_step")
|
||||
public Step execution() {
|
||||
return stepBuilderFactory.get(JOB_NAME + "_step")
|
||||
.tasklet(new OtherMergeTasklet(otherService))
|
||||
.build();
|
||||
}
|
||||
|
||||
@JobScope
|
||||
@Bean(name = JOB_NAME + "_start_step")
|
||||
protected Step start() {
|
||||
return stepBuilderFactory.get("Job_Locking")
|
||||
.tasklet(new BatchStartTasklet(lockService))
|
||||
.build();
|
||||
}
|
||||
|
||||
@JobScope
|
||||
@Bean(name = JOB_NAME + "_end_step")
|
||||
protected Step end() {
|
||||
return stepBuilderFactory.get("Lock_Release")
|
||||
.tasklet(new BatchEndTasklet(lockService))
|
||||
.build();
|
||||
}
|
||||
|
||||
@JobScope
|
||||
@Bean(name = JOB_NAME + "_fail_step")
|
||||
protected Step fail() {
|
||||
return stepBuilderFactory.get("Lock_Release")
|
||||
.tasklet(new BatchFailEndTasklet(lockService))
|
||||
.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package kr.xit.batch.ens.scheduler;
|
||||
|
||||
import kr.xit.batch.ens.job.OtherMergeJobConfig;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.batch.core.JobParameter;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.JobParametersInvalidException;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
||||
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description : Oracle Merge
|
||||
* 대상 : Maria DB (tb_cntc_sndng_mastr, tb_cntc_sndng_detail, tb_cntc_sndng_result)
|
||||
* -> 시설 결과 마스터(elecnoticemst)
|
||||
* 시설 결과 상세(elecnoticedtl)
|
||||
* packageName : kr.xit.batch.ens.scheduler
|
||||
* fileName : OtherMergeJobScheduler
|
||||
* author : jhseo
|
||||
* date : 2024-01-10
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2024-01-10 jhseo 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Component
|
||||
public class OtherMergeJobScheduler {
|
||||
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
|
||||
private final JobLauncher jobLauncher;
|
||||
private final OtherMergeJobConfig jobConfiguration;
|
||||
@Value("${app.slack-webhook.enabled:false}")
|
||||
private String isSlackEnabled;
|
||||
|
||||
@Scheduled(cron = "${app.batch.cron.other.merge}")
|
||||
public void runJob() {
|
||||
|
||||
Map<String, JobParameter> confMap = new HashMap<>();
|
||||
confMap.put("startDate", new JobParameter(new Date()));
|
||||
confMap.put("isSlackEnabled", new JobParameter(isSlackEnabled));
|
||||
|
||||
try {
|
||||
JobParameters jobParameters = new JobParameters(confMap);
|
||||
jobLauncher.run(jobConfiguration.otherMergeJob(), jobParameters);
|
||||
|
||||
} catch (JobExecutionAlreadyRunningException | JobInstanceAlreadyCompleteException
|
||||
| JobParametersInvalidException | org.springframework.batch.core.repository.JobRestartException e) {
|
||||
|
||||
log.error(e.getMessage());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package kr.xit.batch.ens.task;
|
||||
|
||||
import kr.xit.batch.ens.task.cmm.TaskCmmUtils;
|
||||
import kr.xit.biz.ens.service.IEnsOtherMergeService;
|
||||
import kr.xit.core.exception.ErrorParse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.StepContribution;
|
||||
import org.springframework.batch.core.configuration.annotation.JobScope;
|
||||
import org.springframework.batch.core.scope.context.ChunkContext;
|
||||
import org.springframework.batch.core.step.tasklet.Tasklet;
|
||||
import org.springframework.batch.repeat.RepeatStatus;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description :
|
||||
*
|
||||
* packageName : kr.xit.batch.ens.task
|
||||
* fileName : OtherMergeTasklet
|
||||
* author : jhseo
|
||||
* date : 2024-01-10
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2024-01-10 jhseo 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class OtherMergeTasklet implements Tasklet {
|
||||
private final IEnsOtherMergeService service;
|
||||
|
||||
@Override
|
||||
@JobScope
|
||||
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) {
|
||||
final String isSlackEnabled = contribution.getStepExecution().getJobParameters().getString("isSlackEnabled");
|
||||
|
||||
try {
|
||||
MDC.put("service_error_msg", "");
|
||||
|
||||
service.mergeData();
|
||||
}catch(Exception e){
|
||||
String errMsg = ErrorParse.extractError(e).getMessage();
|
||||
log.error("OtherMergeTasklet error :: {}", e.getMessage());
|
||||
MDC.put("service_error_msg", errMsg);
|
||||
TaskCmmUtils.taskBatchErrorLog(
|
||||
contribution.getStepExecution().getJobExecution().getJobInstance().getJobName(),
|
||||
errMsg,
|
||||
isSlackEnabled
|
||||
);
|
||||
contribution.setExitStatus(ExitStatus.FAILED);
|
||||
return RepeatStatus.FINISHED;
|
||||
}
|
||||
contribution.setExitStatus(ExitStatus.COMPLETED);
|
||||
return RepeatStatus.FINISHED;
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package kr.xit.biz.ens.service;
|
||||
|
||||
import kr.xit.biz.ens.cmm.CmmEnsBizUtils;
|
||||
import kr.xit.core.exception.BizRuntimeException;
|
||||
import kr.xit.core.model.ApiResponseDTO;
|
||||
import kr.xit.core.service.AbstractService;
|
||||
import kr.xit.core.spring.util.ApiWebClientUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description : Oracle DB Merge 처리
|
||||
* - 배치에서 호출되는 클래스로 배치 로그등 Transaction 분리 필요
|
||||
* - 메소드 트랜잭션 Transactional(propagation = Propagation.REQUIRES_NEW)로 선언
|
||||
* packageName : kr.xit.biz.ens.service
|
||||
* fileName : EnsOtherMergeService
|
||||
* author : jhseo
|
||||
* date : 2023-08-31
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2023-08-31 jhseo 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class EnsOtherMergeService extends AbstractService implements IEnsOtherMergeService {
|
||||
@Value("${app.contract.host}")
|
||||
private String apiHost;
|
||||
@Value("${app.contract.other.api.merge}")
|
||||
private String apiOtherMerge;
|
||||
|
||||
private final ApiWebClientUtil apiWebClient;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 전자고지(문서) send bulks - 문서 중개자별 send
|
||||
* </pre>
|
||||
*/
|
||||
@Override
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void mergeData() {
|
||||
final String url = apiHost + apiOtherMerge;
|
||||
|
||||
final ApiResponseDTO apiResult = apiWebClient.exchange(
|
||||
url,
|
||||
HttpMethod.POST,
|
||||
"",
|
||||
ApiResponseDTO.class,
|
||||
CmmEnsBizUtils.getHeadeMap());
|
||||
|
||||
String errMsg = "";
|
||||
if(apiResult.getData() != null) {
|
||||
if(!"success".equals(apiResult.getData())){
|
||||
errMsg = apiResult.getMessage();
|
||||
throw BizRuntimeException.create(errMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package kr.xit.biz.ens.service;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description : Oracle DB Merge 처리
|
||||
*
|
||||
* packageName : kr.xit.biz.ens.service
|
||||
* fileName : IEnsOtherMergeService
|
||||
* author : jhseo
|
||||
* date : 2024-01-10
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2024-01-10 jhseo 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public interface IEnsOtherMergeService {
|
||||
void mergeData();
|
||||
}
|
Loading…
Reference in New Issue