Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package site.icebang.domain.workflow.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;

import site.icebang.common.dto.ApiResponse;
import site.icebang.domain.workflow.dto.WorkflowRunDetailResponse;
import site.icebang.domain.workflow.service.WorkflowHistoryService;

@RestController
@RequestMapping("/v0/workflow-runs")
@RequiredArgsConstructor
public class WorkflowHistoryController {
private final WorkflowHistoryService workflowHistoryService;

/**
* 워크플로우 실행 상세 조회
*
* @param runId workflow_run.id
* @return WorkflowRunDetailResponse
*/
@GetMapping("/{runId}")
public ApiResponse<WorkflowRunDetailResponse> getWorkflowRunDetail(@PathVariable Long runId) {
WorkflowRunDetailResponse response = workflowHistoryService.getWorkflowRunDetail(runId);
return ApiResponse.success(response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package site.icebang.domain.workflow.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ExecutionLogDto {
private Long id; // execution_log.id
private String executionType; // workflow, job, task
private Long sourceId; // 모든 데이터에 대한 ID
private Long runId; // 실행 ID (workflow_run, job_run, task_run)
private String logLevel; // info, success, warning, error
private String status; // running, success, failed, etc
private String logMessage;
private String executedAt;
private Integer durationMs;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package site.icebang.domain.workflow.dto;

import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class JobRunDto {
private Long id; // job_run.id (Job 실행 ID)
private Long workflowRunId; // workflow_run.id (관계)
private Long jobId; // job.id (Job 설계 ID)
private String jobName;
private String jobDescription;
private String status;
private Integer executionOrder;
private String startedAt;
private String finishedAt;
private Integer durationMs;
private List<TaskRunDto> taskRuns;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package site.icebang.domain.workflow.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TaskRunDto {
private Long id; // task_run.id (Task 실행 ID)
private Long jobRunId; // job_run.id (관계)
private Long taskId; // task.id (Task 설계 ID)
private String taskName;
private String taskDescription;
private String taskType;
private String status;
private Integer executionOrder;
private String startedAt;
private String finishedAt;
private Integer durationMs;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package site.icebang.domain.workflow.dto;

import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WorkflowRunDetailResponse {
private String traceId;
private WorkflowRunDto workflowRun;
private List<JobRunDto> jobRuns;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package site.icebang.domain.workflow.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WorkflowRunDto {
private Long id; // workflow_run.id (실행 ID)
private Long workflowId; // workflow.id (설계 ID)
private String workflowName;
private String workflowDescription;
private String runNumber;
private String status;
private String triggerType;
private String startedAt;
private String finishedAt;
private Integer durationMs;
private Long createdBy;
private String createdAt;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package site.icebang.domain.workflow.dto;

import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WorkflowRunLogsResponse {
private String traceId;
private List<ExecutionLogDto> logs;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package site.icebang.domain.workflow.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;

import site.icebang.domain.workflow.dto.JobRunDto;
import site.icebang.domain.workflow.dto.TaskRunDto;
import site.icebang.domain.workflow.dto.WorkflowRunDto;

@Mapper
public interface WorkflowHistoryMapper {
/**
* 워크플로우 실행 정보 조회
*
* @param runId workflow_run.id
* @return WorkflowRunDto
*/
WorkflowRunDto selectWorkflowRun(Long runId);

/**
* 워크플로우 실행의 Job 목록 조회
*
* @param workflowRunId workflow_run.id
* @return List<JobRunDto>
*/
List<JobRunDto> selectJobRunsByWorkflowRunId(Long workflowRunId);

/**
* Job 실행의 Task 목록 조회
*
* @param jobRunId job_run.id
* @return List<TaskRunDto>
*/
List<TaskRunDto> selectTaskRunsByJobRunId(Long jobRunId);

/**
* 워크플로우 실행 TraceId 조회
*
* @param runId workflow_run.id
* @return String traceId
*/
String selectTraceIdByRunId(Long runId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package site.icebang.domain.workflow.service;

import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import lombok.RequiredArgsConstructor;

import site.icebang.domain.workflow.dto.*;
import site.icebang.domain.workflow.mapper.WorkflowHistoryMapper;

@Service
@RequiredArgsConstructor
public class WorkflowHistoryService {
private final WorkflowHistoryMapper workflowHistoryMapper;

/**
* 워크플로우 실행 상세 조회
*
* @param runId workflow_run.id
* @return WorkflowRunDetailResponse
*/
@Transactional(readOnly = true)
public WorkflowRunDetailResponse getWorkflowRunDetail(Long runId) {
// 1. 워크플로우 실행 정보 조회
WorkflowRunDto workflowRunDto = workflowHistoryMapper.selectWorkflowRun(runId);

// 2. Job 실행 목록 조회
List<JobRunDto> jobRunDtos = workflowHistoryMapper.selectJobRunsByWorkflowRunId(runId);

// 3. 각 Job의 Task 실행 목록 조회
if (jobRunDtos != null) {
jobRunDtos.forEach(
jobRun -> {
List<TaskRunDto> taskRuns =
workflowHistoryMapper.selectTaskRunsByJobRunId(jobRun.getId());
jobRun.setTaskRuns(taskRuns);
});
}

// 4. TraceId 조회
String traceId = workflowHistoryMapper.selectTraceIdByRunId(runId);

return WorkflowRunDetailResponse.builder()
.workflowRun(workflowRunDto)
.jobRuns(jobRunDtos)
.traceId(traceId)
.build();
}

/**
* 워크플로우 실행 로그 조회
*
* @param runId workflow_run.id
* @return WorkflowRunLogsResponse
*/
public WorkflowRunLogsResponse getWorkflowRunLogs(Long runId) {
// TODO: 구현 예정
return null;
}

/**
* TraceId로 워크플로우 실행 조회
*
* @param traceId workflow_run.trace_id
* @return WorkflowRunDetailResponse
*/
public WorkflowRunDetailResponse getWorkflowRunByTraceId(String traceId) {
// TODO: 구현 예정
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?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="site.icebang.domain.workflow.mapper.WorkflowHistoryMapper">

<!-- WorkflowRunDto 조회 -->
<select id="selectWorkflowRun" parameterType="Long" resultType="site.icebang.domain.workflow.dto.WorkflowRunDto">
SELECT
wr.id,
wr.workflow_id AS workflowId,
w.name AS workflowName,
w.description AS workflowDescription,
wr.run_number AS runNumber,
wr.status,
wr.trigger_type AS triggerType,
wr.started_at AS startedAt,
wr.finished_at AS finishedAt,
TIMESTAMPDIFF(MICROSECOND, wr.started_at, wr.finished_at) / 1000 AS durationMs,
wr.created_by AS createdBy,
wr.created_at AS createdAt
FROM workflow_run wr
JOIN workflow w ON wr.workflow_id = w.id
WHERE wr.id = #{runId}
</select>

<!-- JobRunDto 목록 조회 -->
<select id="selectJobRunsByWorkflowRunId" parameterType="Long" resultType="site.icebang.domain.workflow.dto.JobRunDto">
SELECT
jr.id,
jr.workflow_run_id AS workflowRunId,
jr.job_id AS jobId,
j.name AS jobName,
j.description AS jobDescription,
jr.status,
jr.execution_order AS executionOrder,
jr.started_at AS startedAt,
jr.finished_at AS finishedAt,
TIMESTAMPDIFF(MICROSECOND, jr.started_at, jr.finished_at) / 1000 AS durationMs
FROM job_run jr
JOIN job j ON jr.job_id = j.id
WHERE jr.workflow_run_id = #{workflowRunId}
ORDER BY jr.execution_order
</select>

<!-- TaskRunDto 목록 조회 -->
<select id="selectTaskRunsByJobRunId" parameterType="Long" resultType="site.icebang.domain.workflow.dto.TaskRunDto">
SELECT
tr.id,
tr.job_run_id AS jobRunId,
tr.task_id AS taskId,
t.name AS taskName,
t.type AS taskType,
tr.status,
tr.execution_order AS executionOrder,
tr.started_at AS startedAt,
tr.finished_at AS finishedAt,
TIMESTAMPDIFF(MICROSECOND, tr.started_at, tr.finished_at) / 1000 AS durationMs
FROM task_run tr
JOIN task t ON tr.task_id = t.id
WHERE tr.job_run_id = #{jobRunId}
ORDER BY tr.execution_order
</select>

<!-- TraceId 조회 -->
<select id="selectTraceIdByRunId" parameterType="Long" resultType="String">
SELECT trace_id
FROM workflow_run
WHERE id = #{runId}
</select>

</mapper>
Loading
Loading