262 lines
8.2 KiB
Java
262 lines
8.2 KiB
Java
package com.interplug.qcast.batch;
|
|
|
|
import java.util.*;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.batch.core.*;
|
|
import org.springframework.batch.core.explore.JobExplorer;
|
|
import org.springframework.batch.core.launch.JobLauncher;
|
|
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
|
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
|
|
import org.springframework.batch.core.repository.JobRestartException;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
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;
|
|
|
|
@RestController
|
|
@RequiredArgsConstructor
|
|
@Slf4j
|
|
public class JobLauncherController {
|
|
private final Map<String, Job> jobs; // 여러 Job을 주입받도록 변경
|
|
|
|
private final JobLauncher jobLauncher;
|
|
private final JobExplorer jobExplorer;
|
|
|
|
@Value("${qsp.master-admin-user-batch-url}")
|
|
private String qspInterfaceUrl;
|
|
|
|
@Value("${spring.profiles.scheduler}")
|
|
private String scheduler;
|
|
|
|
/**
|
|
* 특정 Job을 매핑으로 실행하는 메소드
|
|
*
|
|
* @param jobName
|
|
* @return
|
|
* @throws JobInstanceAlreadyCompleteException
|
|
* @throws JobExecutionAlreadyRunningException
|
|
* @throws JobParametersInvalidException
|
|
* @throws JobRestartException
|
|
*/
|
|
@GetMapping("/batch/job/{jobName}") // Path Variable로 jobName을 받음
|
|
public Map<String, Object> launchJob(@PathVariable String jobName)
|
|
throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException,
|
|
JobParametersInvalidException, JobRestartException {
|
|
|
|
|
|
Job job = jobs.get(jobName);
|
|
Map<String, Object> resultMap = new HashMap<String, Object>();
|
|
if (job == null) {
|
|
// return "Job " + jobName + " not found";
|
|
resultMap.put("code", "FAILED");
|
|
resultMap.put("message", "Job" + jobName + " not found");
|
|
return resultMap;
|
|
}
|
|
|
|
// 실행 중인 Job 확인 (데이터베이스 기반)
|
|
if (isJobRunning(jobName)) {
|
|
log.warn("Job {} is already running, skipping execution", jobName);
|
|
resultMap.put("code", "FAILED");
|
|
resultMap.put("message", "Job "+ jobName +" is already running, skipping execution");
|
|
return resultMap;
|
|
}
|
|
|
|
try {
|
|
log.info("Starting job: {}", jobName);
|
|
|
|
JobParameters jobParameters = new JobParametersBuilder().addString("jobName", jobName)
|
|
.addDate("time", new Date()).toJobParameters();
|
|
|
|
JobExecution jobExecution = jobLauncher.run(job, jobParameters);
|
|
|
|
BatchStatus status = jobExecution.getStatus();
|
|
ExitStatus exitStatus = jobExecution.getExitStatus();
|
|
|
|
resultMap.put("code", status.toString());
|
|
resultMap.put("message", exitStatus.getExitDescription());
|
|
|
|
// return "Job " + jobName + " started";
|
|
return resultMap;
|
|
} catch (Exception e) {
|
|
resultMap.put("code", "FAILED");
|
|
resultMap.put("message", e.getMessage());
|
|
return resultMap;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Q.CAST 판매점 / 사용자 / 즐겨찾기 / 노출 아이템 동기화 배치
|
|
*
|
|
|
|
*/
|
|
// @Scheduled(cron = "*/5 * * * * *")
|
|
@Scheduled(cron = "0 50 23 * * *")
|
|
public String storeAdditionalJob() throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
|
|
|
|
return executeScheduledJob("storeAdditionalJob");
|
|
|
|
}
|
|
|
|
/**
|
|
* 아이템 동기화 배치
|
|
*
|
|
|
|
*/
|
|
@Scheduled(cron = "0 30 02 * * *")
|
|
public String materialJob() throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
|
|
|
|
return executeScheduledJob("materialJob");
|
|
|
|
}
|
|
|
|
/**
|
|
* BOM 아이템 동기화 배치
|
|
*
|
|
|
|
*/
|
|
@Scheduled(cron = "0 40 02 * * *")
|
|
public String bomJob() throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
|
|
|
|
return executeScheduledJob("bomJob");
|
|
|
|
}
|
|
|
|
/**
|
|
* 영업사원 동기화 배치
|
|
*
|
|
|
|
*/
|
|
@Scheduled(cron = "0 40 03 * * *")
|
|
public String businessChargerJob() throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
|
|
|
|
return executeScheduledJob("businessChargerJob");
|
|
|
|
}
|
|
|
|
/**
|
|
* 관리자 유저 동기화 배치
|
|
*
|
|
|
|
*/
|
|
@Scheduled(cron = "0 30 01 * * *")
|
|
public String adminUserJob() throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
|
|
|
|
return executeScheduledJob("adminUserJob");
|
|
|
|
}
|
|
|
|
/**
|
|
* 가격 동기화 배치
|
|
*
|
|
|
|
*/
|
|
@Scheduled(cron = "0 20 00 * * *")
|
|
public String priceJob() throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
|
|
|
|
return executeScheduledJob("priceJob");
|
|
|
|
}
|
|
|
|
/**
|
|
* 공통코드 M_COMM_H, M_COMM_L 동기화 배치
|
|
*
|
|
|
|
*/
|
|
@Scheduled(cron = "0 10 03 * * *")
|
|
public String commonCodeJob() throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
|
|
|
|
return executeScheduledJob("commonCodeJob");
|
|
|
|
}
|
|
|
|
/**
|
|
* Q.CAST 견적특이사항 / 아이템 표시, 미표시 동기화 배치
|
|
*
|
|
|
|
*/
|
|
@Scheduled(cron = "0 30 23 * * *")
|
|
public String specialNoteDispItemAdditionalInfoJob() throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
|
|
return executeScheduledJob("specialNoteDispItemAdditionalJob");
|
|
|
|
}
|
|
|
|
/**
|
|
* Plan Confrim 동기화 배치
|
|
*
|
|
|
|
*/
|
|
@Scheduled(cron = "0 05 04 * * *")
|
|
public String planConfirmJob() throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
|
|
|
|
return executeScheduledJob("planConfirmJob");
|
|
|
|
}
|
|
|
|
/**
|
|
* 견적서 전송 동기화 배치
|
|
*
|
|
|
|
*/
|
|
@Scheduled(cron = "0 20 04 * * *")
|
|
public String estimateSyncJob() throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
|
|
|
|
return executeScheduledJob("estimateSyncJob");
|
|
|
|
}
|
|
|
|
/**
|
|
* 공통 스케줄러 실행 메소드
|
|
*/
|
|
private String executeScheduledJob(String jobName) throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
|
|
Job job = jobs.get(jobName);
|
|
if (job == null) {
|
|
log.error("Job {} not found", jobName);
|
|
return "Job " + jobName + " not found";
|
|
}
|
|
|
|
if (!"Y".equals(scheduler) && !"materialJob".equals(jobName) && !"commonCodeJob".equals(jobName) && !"specialNoteDispItemAdditionalJob".equals(jobName)) {
|
|
log.info("Scheduler disabled, skipping job {}", jobName);
|
|
return "Scheduler disabled";
|
|
}
|
|
|
|
// 실행 중인 Job 확인 (데이터베이스 기반)
|
|
if (isJobRunning(jobName)) {
|
|
log.warn("Job {} is already running, skipping execution", jobName);
|
|
return "Job already running";
|
|
}
|
|
|
|
JobParameters jobParameters =
|
|
new JobParametersBuilder().addDate("time", new Date()).toJobParameters();
|
|
|
|
jobLauncher.run(job, jobParameters);
|
|
|
|
return jobName+ " executed successfully";
|
|
}
|
|
|
|
/**
|
|
* Job 실행 상태 확인
|
|
*/
|
|
private boolean isJobRunning(String jobName) {
|
|
try {
|
|
List<JobInstance> jobInstances = jobExplorer.findJobInstancesByJobName(jobName, 0, 1);
|
|
if (jobInstances.isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
JobInstance latestJobInstance = jobInstances.get(0);
|
|
List<JobExecution> jobExecutions = jobExplorer.getJobExecutions(latestJobInstance);
|
|
|
|
return jobExecutions.stream()
|
|
.anyMatch(execution -> execution.getStatus() == BatchStatus.STARTED
|
|
|| execution.getStatus() == BatchStatus.STARTING);
|
|
} catch (Exception e) {
|
|
log.error("Error checking job running status: {}", e.getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
}
|