qcast-api/src/main/java/com/interplug/qcast/batch/BatchMonitorController.java
2025-07-16 17:37:22 +09:00

108 lines
3.8 KiB
Java

package com.interplug.qcast.batch;
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.JobOperator;
import org.springframework.web.bind.annotation.*;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
@RestController
@RequiredArgsConstructor
@Slf4j
public class BatchMonitorController {
private final JobExplorer jobExplorer;
private final JobOperator jobOperator;
@GetMapping("/batch/status")
public Map<String, Object> getBatchStatus() {
Map<String, Object> status = new HashMap<>();
String[] jobNames = {"storeAdditionalJob", "priceJob", "materialJob", "bomJob",
"businessChargerJob", "adminUserJob", "commonCodeJob",
"specialNoteDispItemAdditionalJob", "planConfirmJob", "estimateSyncJob"};
for (String jobName : jobNames) {
status.put(jobName, getJobStatus(jobName));
}
return status;
}
private Map<String, Object> getJobStatus(String jobName) {
Map<String, Object> jobStatus = new HashMap<>();
try {
List<JobInstance> jobInstances = jobExplorer.findJobInstancesByJobName(jobName, 0, 1);
if (jobInstances.isEmpty()) {
jobStatus.put("status", "NEVER_EXECUTED");
return jobStatus;
}
JobInstance latestJobInstance = jobInstances.get(0);
List<JobExecution> jobExecutions = jobExplorer.getJobExecutions(latestJobInstance);
if (!jobExecutions.isEmpty()) {
JobExecution latestExecution = jobExecutions.get(0);
jobStatus.put("status", latestExecution.getStatus().toString());
jobStatus.put("startTime", latestExecution.getStartTime());
jobStatus.put("endTime", latestExecution.getEndTime());
// Duration 계산 (LocalDateTime용)
if (latestExecution.getEndTime() != null && latestExecution.getStartTime() != null) {
Duration duration = Duration.between(latestExecution.getStartTime(), latestExecution.getEndTime());
jobStatus.put("durationSeconds", duration.getSeconds());
jobStatus.put("durationMinutes", duration.toMinutes());
} else if (latestExecution.getStartTime() != null) {
// 실행 중인 경우 현재까지의 경과 시간
Duration duration = Duration.between(latestExecution.getStartTime(), LocalDateTime.now());
jobStatus.put("runningDurationSeconds", duration.getSeconds());
jobStatus.put("runningDurationMinutes", duration.toMinutes());
}
}
} catch (Exception e) {
jobStatus.put("status", "ERROR");
jobStatus.put("error", e.getMessage());
}
return jobStatus;
}
/**
* 강제 Job 중지
*/
@PostMapping("/batch/stop/{jobName}")
public Map<String, Object> stopJob(@PathVariable String jobName) {
Map<String, Object> result = new HashMap<>();
try {
Set<Long> runningExecutions = jobOperator.getRunningExecutions(jobName);
if (runningExecutions.isEmpty()) {
result.put("code", "NO_RUNNING_JOBS");
result.put("message", "No running executions found for job: " + jobName);
return result;
}
List<String> stopResults = new ArrayList<>();
for (Long executionId : runningExecutions) {
boolean stopped = jobOperator.stop(executionId);
stopResults.add("Execution " + executionId + ": " + (stopped ? "STOPPED" : "FAILED_TO_STOP"));
}
result.put("code", "SUCCESS");
result.put("message", "Stop commands sent");
result.put("results", stopResults);
} catch (Exception e) {
result.put("code", "ERROR");
result.put("message", "Error stopping job: " + e.getMessage());
}
return result;
}
}