From 664e7f64c3f753fded138831469e55b318a1d4aa Mon Sep 17 00:00:00 2001 From: jhseo Date: Wed, 10 Jan 2024 17:07:36 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=8B=9C=EC=84=A4=20=EC=98=A4=EB=9D=BC?= =?UTF-8?q?=ED=81=B4=20DB=20Merge=20=EB=B0=B0=EC=B9=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80(30=EB=B6=84=20=EB=A7=88=EB=8B=A4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kr/xit/other/service/OtherService.java | 2 +- .../kr/xit/other/web/OtherController.java | 4 +- .../resources/config/application-prod.yml | 8 +- .../batch/ens/job/OtherMergeJobConfig.java | 113 ++++++++++++++++++ .../ens/scheduler/OtherMergeJobScheduler.java | 66 ++++++++++ .../xit/batch/ens/task/OtherMergeTasklet.java | 60 ++++++++++ .../biz/ens/service/EnsOtherMergeService.java | 68 +++++++++++ .../ens/service/IEnsOtherMergeService.java | 20 ++++ .../main/resources/config/application-app.yml | 2 + .../main/resources/config/application-ens.yml | 3 + 10 files changed, 343 insertions(+), 3 deletions(-) create mode 100644 mens-batch/src/main/java/kr/xit/batch/ens/job/OtherMergeJobConfig.java create mode 100644 mens-batch/src/main/java/kr/xit/batch/ens/scheduler/OtherMergeJobScheduler.java create mode 100644 mens-batch/src/main/java/kr/xit/batch/ens/task/OtherMergeTasklet.java create mode 100644 mens-batch/src/main/java/kr/xit/biz/ens/service/EnsOtherMergeService.java create mode 100644 mens-batch/src/main/java/kr/xit/biz/ens/service/IEnsOtherMergeService.java diff --git a/mens-api/src/main/java/kr/xit/other/service/OtherService.java b/mens-api/src/main/java/kr/xit/other/service/OtherService.java index 0154c3c..0f3c811 100644 --- a/mens-api/src/main/java/kr/xit/other/service/OtherService.java +++ b/mens-api/src/main/java/kr/xit/other/service/OtherService.java @@ -56,6 +56,6 @@ public class OtherService extends AbstractService implements IOtherService { } } - return "test"; + return "success"; } } diff --git a/mens-api/src/main/java/kr/xit/other/web/OtherController.java b/mens-api/src/main/java/kr/xit/other/web/OtherController.java index 5d9e281..9836a18 100644 --- a/mens-api/src/main/java/kr/xit/other/web/OtherController.java +++ b/mens-api/src/main/java/kr/xit/other/web/OtherController.java @@ -35,6 +35,8 @@ public class OtherController { @PostMapping(value = "/merge", produces = MediaType.APPLICATION_JSON_VALUE) public IApiResponse merge() { String msg = service.mergeData(); - return ApiResponseDTO.success(msg); + String errMsg = ""; + if("success".equals(msg)) errMsg = service.mergeData(); + return ApiResponseDTO.success(msg, errMsg); } } diff --git a/mens-api/src/main/resources/config/application-prod.yml b/mens-api/src/main/resources/config/application-prod.yml index dc147d6..6522d2e 100644 --- a/mens-api/src/main/resources/config/application-prod.yml +++ b/mens-api/src/main/resources/config/application-prod.yml @@ -14,7 +14,13 @@ spring: password: ENC(+sXCmhmSV3Q/3KgOnmpnTQ==) read-only: false # multi-database - #secondary: + secondary: + database: oracle + driver-class-name: oracle.jdbc.OracleDriver + jdbc-url: jdbc:oracle:thin:@150.50.48.31:1521:ETISDDB + username: MOBELNOTI + password: wjswkrhwl12!@ + read-only: false devtools: livereload: diff --git a/mens-batch/src/main/java/kr/xit/batch/ens/job/OtherMergeJobConfig.java b/mens-batch/src/main/java/kr/xit/batch/ens/job/OtherMergeJobConfig.java new file mode 100644 index 0000000..25ae26b --- /dev/null +++ b/mens-batch/src/main/java/kr/xit/batch/ens/job/OtherMergeJobConfig.java @@ -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; + +/** + *
+ * description :
+ *
+ * packageName : kr.xit.batch.ens.job
+ * fileName    : OtherMergeJobConfig
+ * author      : jhseo
+ * date        : 2024-01-10
+ * ======================================================================
+ * 변경일         변경자        변경 내용
+ * ----------------------------------------------------------------------
+ * 2024-01-10    jhseo       최초 생성
+ *
+ * 
+ */ +@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(); + } +} diff --git a/mens-batch/src/main/java/kr/xit/batch/ens/scheduler/OtherMergeJobScheduler.java b/mens-batch/src/main/java/kr/xit/batch/ens/scheduler/OtherMergeJobScheduler.java new file mode 100644 index 0000000..e49cf30 --- /dev/null +++ b/mens-batch/src/main/java/kr/xit/batch/ens/scheduler/OtherMergeJobScheduler.java @@ -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; + +/** + *
+ * 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       최초 생성
+ *
+ * 
+ */ +@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 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); + } + } +} diff --git a/mens-batch/src/main/java/kr/xit/batch/ens/task/OtherMergeTasklet.java b/mens-batch/src/main/java/kr/xit/batch/ens/task/OtherMergeTasklet.java new file mode 100644 index 0000000..6990dea --- /dev/null +++ b/mens-batch/src/main/java/kr/xit/batch/ens/task/OtherMergeTasklet.java @@ -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; + +/** + *
+ * description :
+ *
+ * packageName : kr.xit.batch.ens.task
+ * fileName    : OtherMergeTasklet
+ * author      : jhseo
+ * date        : 2024-01-10
+ * ======================================================================
+ * 변경일         변경자        변경 내용
+ * ----------------------------------------------------------------------
+ * 2024-01-10    jhseo       최초 생성
+ *
+ * 
+ */ +@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; + } +} diff --git a/mens-batch/src/main/java/kr/xit/biz/ens/service/EnsOtherMergeService.java b/mens-batch/src/main/java/kr/xit/biz/ens/service/EnsOtherMergeService.java new file mode 100644 index 0000000..2128f66 --- /dev/null +++ b/mens-batch/src/main/java/kr/xit/biz/ens/service/EnsOtherMergeService.java @@ -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; + +/** + *
+ * 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       최초 생성
+ *
+ * 
+ */ +@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; + + /** + *
+     * 전자고지(문서) send bulks - 문서 중개자별 send
+     * 
+ */ + @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); + } + } + } +} diff --git a/mens-batch/src/main/java/kr/xit/biz/ens/service/IEnsOtherMergeService.java b/mens-batch/src/main/java/kr/xit/biz/ens/service/IEnsOtherMergeService.java new file mode 100644 index 0000000..a7f0570 --- /dev/null +++ b/mens-batch/src/main/java/kr/xit/biz/ens/service/IEnsOtherMergeService.java @@ -0,0 +1,20 @@ +package kr.xit.biz.ens.service; + +/** + *
+ * description : Oracle DB Merge 처리
+ *
+ * packageName : kr.xit.biz.ens.service
+ * fileName    : IEnsOtherMergeService
+ * author      : jhseo
+ * date        : 2024-01-10
+ * ======================================================================
+ * 변경일         변경자        변경 내용
+ * ----------------------------------------------------------------------
+ * 2024-01-10    jhseo       최초 생성
+ *
+ * 
+ */ +public interface IEnsOtherMergeService { + void mergeData(); +} diff --git a/mens-batch/src/main/resources/config/application-app.yml b/mens-batch/src/main/resources/config/application-app.yml index 79a4148..afcd5b7 100644 --- a/mens-batch/src/main/resources/config/application-app.yml +++ b/mens-batch/src/main/resources/config/application-app.yml @@ -57,3 +57,5 @@ app: close: '0 59 21 * * *' pni: accept: '0 0/1 23 * * *' + other: + merge: '0 30 8-21 * * *' diff --git a/mens-batch/src/main/resources/config/application-ens.yml b/mens-batch/src/main/resources/config/application-ens.yml index b1de5e4..ef6e1ec 100644 --- a/mens-batch/src/main/resources/config/application-ens.yml +++ b/mens-batch/src/main/resources/config/application-ens.yml @@ -30,6 +30,9 @@ app: epost: api: trace: /api/ens/epost/v1/trace + other: + api: + merge: /api/other/v1/merge # 배치 설정 batch: