Merge pull request '모델 파일 경로 조회, 데이터셋 파일 경로 조회, 디렉토리 용량 체크, 모델별 학습 실행 상태 조회' (#193) from feat/training_260324 into develop
Reviewed-on: #193
This commit was merged in pull request #193.
This commit is contained in:
@@ -11,10 +11,12 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import java.util.UUID;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
@@ -122,4 +124,113 @@ public class FileManagerApiController {
|
|||||||
FileManagerDto.DeleteFileRes response = fileManagerService.deleteFiles(request);
|
FileManagerDto.DeleteFileRes response = fileManagerService.deleteFiles(request);
|
||||||
return ApiResponseDto.ok(response);
|
return ApiResponseDto.ok(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "모델 파일 경로 조회",
|
||||||
|
description =
|
||||||
|
"특정 모델 UUID로 파일 위치 경로와 하위 파일 목록을 조회합니다. "
|
||||||
|
+ "request_path(심볼릭 링크 디렉토리)와 response_path(모델 결과)를 동시에 반환합니다.")
|
||||||
|
@ApiResponses(
|
||||||
|
value = {
|
||||||
|
@ApiResponse(
|
||||||
|
responseCode = "200",
|
||||||
|
description = "조회 성공",
|
||||||
|
content =
|
||||||
|
@Content(
|
||||||
|
mediaType = "application/json",
|
||||||
|
schema = @Schema(implementation = FileManagerDto.ModelFilePathRes.class))),
|
||||||
|
@ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content),
|
||||||
|
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
|
})
|
||||||
|
@GetMapping("/model-path/{modelUuid}")
|
||||||
|
public ApiResponseDto<FileManagerDto.ModelFilePathRes> getModelFilePath(
|
||||||
|
@Parameter(description = "모델 UUID", example = "123e4567-e89b-12d3-a456-426614174000")
|
||||||
|
@PathVariable
|
||||||
|
UUID modelUuid) {
|
||||||
|
|
||||||
|
FileManagerDto.ModelFilePathRes response = fileManagerService.getModelFilePath(modelUuid);
|
||||||
|
return ApiResponseDto.ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "데이터셋 파일 경로 조회",
|
||||||
|
description =
|
||||||
|
"특정 데이터셋 UUID로 파일 위치 경로와 하위 파일 목록을 조회합니다. " + "dataset_path 컬럼의 request_dir 경로를 반환합니다.")
|
||||||
|
@ApiResponses(
|
||||||
|
value = {
|
||||||
|
@ApiResponse(
|
||||||
|
responseCode = "200",
|
||||||
|
description = "조회 성공",
|
||||||
|
content =
|
||||||
|
@Content(
|
||||||
|
mediaType = "application/json",
|
||||||
|
schema = @Schema(implementation = FileManagerDto.DatasetFilePathRes.class))),
|
||||||
|
@ApiResponse(responseCode = "404", description = "데이터셋을 찾을 수 없음", content = @Content),
|
||||||
|
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
|
})
|
||||||
|
@GetMapping("/dataset-path/{datasetUuid}")
|
||||||
|
public ApiResponseDto<FileManagerDto.DatasetFilePathRes> getDatasetFilePath(
|
||||||
|
@Parameter(description = "데이터셋 UUID", example = "123e4567-e89b-12d3-a456-426614174001")
|
||||||
|
@PathVariable
|
||||||
|
UUID datasetUuid) {
|
||||||
|
|
||||||
|
FileManagerDto.DatasetFilePathRes response = fileManagerService.getDatasetFilePath(datasetUuid);
|
||||||
|
return ApiResponseDto.ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "디렉토리 용량 체크",
|
||||||
|
description = "특정 디렉토리의 총 용량, 파일 개수, 디렉토리 개수를 조회합니다. " + "basepath 하위 폴더의 용량을 재귀적으로 계산합니다.")
|
||||||
|
@ApiResponses(
|
||||||
|
value = {
|
||||||
|
@ApiResponse(
|
||||||
|
responseCode = "200",
|
||||||
|
description = "조회 성공",
|
||||||
|
content =
|
||||||
|
@Content(
|
||||||
|
mediaType = "application/json",
|
||||||
|
schema = @Schema(implementation = FileManagerDto.DirectoryCapacityRes.class))),
|
||||||
|
@ApiResponse(responseCode = "400", description = "잘못된 경로", content = @Content),
|
||||||
|
@ApiResponse(responseCode = "404", description = "디렉토리를 찾을 수 없음", content = @Content),
|
||||||
|
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
|
})
|
||||||
|
@GetMapping("/directory-capacity")
|
||||||
|
public ApiResponseDto<FileManagerDto.DirectoryCapacityRes> checkDirectoryCapacity(
|
||||||
|
@Parameter(
|
||||||
|
description = "디렉토리 경로",
|
||||||
|
example = "/home/kcomu/data/request/123e4567-e89b-12d3-a456-426614174001")
|
||||||
|
@RequestParam
|
||||||
|
String directoryPath) {
|
||||||
|
|
||||||
|
FileManagerDto.DirectoryCapacityRes response =
|
||||||
|
fileManagerService.checkDirectoryCapacity(directoryPath);
|
||||||
|
return ApiResponseDto.ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "모델별 학습 실행 상태 조회",
|
||||||
|
description =
|
||||||
|
"G1~G4 모델의 현재 학습 실행 상태를 조회합니다. "
|
||||||
|
+ "step1_state, step2_state를 체크하여 어떤 모델이 학습 중인지 확인합니다. "
|
||||||
|
+ "step1과 step2는 동시 진행되지 않습니다.")
|
||||||
|
@ApiResponses(
|
||||||
|
value = {
|
||||||
|
@ApiResponse(
|
||||||
|
responseCode = "200",
|
||||||
|
description = "조회 성공",
|
||||||
|
content =
|
||||||
|
@Content(
|
||||||
|
mediaType = "application/json",
|
||||||
|
schema =
|
||||||
|
@Schema(
|
||||||
|
implementation = FileManagerDto.AllModelsExecutionStatusRes.class))),
|
||||||
|
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
|
})
|
||||||
|
@GetMapping("/models-execution-status")
|
||||||
|
public ApiResponseDto<FileManagerDto.AllModelsExecutionStatusRes> getModelsExecutionStatus() {
|
||||||
|
|
||||||
|
FileManagerDto.AllModelsExecutionStatusRes response =
|
||||||
|
fileManagerService.getModelsExecutionStatus();
|
||||||
|
return ApiResponseDto.ok(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,4 +131,105 @@ public class FileManagerDto {
|
|||||||
@Schema(description = "사용률 (%)", example = "50.0")
|
@Schema(description = "사용률 (%)", example = "50.0")
|
||||||
private Double usagePercentage;
|
private Double usagePercentage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Schema(description = "모델 파일 경로 정보 응답")
|
||||||
|
public static class ModelFilePathRes {
|
||||||
|
@Schema(description = "모델 UUID", example = "123e4567-e89b-12d3-a456-426614174000")
|
||||||
|
private String modelUuid;
|
||||||
|
|
||||||
|
@Schema(
|
||||||
|
description = "요청 경로 (심볼릭 링크 디렉토리)",
|
||||||
|
example = "/home/kcomu/data/tmp/123e4567-e89b-12d3-a456-426614174000")
|
||||||
|
private String requestPath;
|
||||||
|
|
||||||
|
@Schema(
|
||||||
|
description = "응답 경로 (모델 결과 저장)",
|
||||||
|
example = "/home/kcomu/data/response/123e4567-e89b-12d3-a456-426614174000")
|
||||||
|
private String responsePath;
|
||||||
|
|
||||||
|
@Schema(description = "요청 경로 파일 목록")
|
||||||
|
private List<FileInfo> requestFiles;
|
||||||
|
|
||||||
|
@Schema(description = "응답 경로 파일 목록")
|
||||||
|
private List<FileInfo> responseFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Schema(description = "데이터셋 파일 경로 정보 응답")
|
||||||
|
public static class DatasetFilePathRes {
|
||||||
|
@Schema(description = "데이터셋 UUID", example = "123e4567-e89b-12d3-a456-426614174001")
|
||||||
|
private String datasetUuid;
|
||||||
|
|
||||||
|
@Schema(
|
||||||
|
description = "데이터셋 경로",
|
||||||
|
example = "/home/kcomu/data/request/123e4567-e89b-12d3-a456-426614174001")
|
||||||
|
private String datasetPath;
|
||||||
|
|
||||||
|
@Schema(description = "데이터셋 파일 목록")
|
||||||
|
private List<FileInfo> files;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Schema(description = "디렉토리 용량 체크 응답")
|
||||||
|
public static class DirectoryCapacityRes {
|
||||||
|
@Schema(description = "디렉토리 경로", example = "/home/kcomu/data/request/dataset-uuid")
|
||||||
|
private String directoryPath;
|
||||||
|
|
||||||
|
@Schema(description = "파일 개수", example = "1234")
|
||||||
|
private Integer fileCount;
|
||||||
|
|
||||||
|
@Schema(description = "디렉토리 개수", example = "56")
|
||||||
|
private Integer directoryCount;
|
||||||
|
|
||||||
|
@Schema(description = "총 용량 (bytes)", example = "10485760000")
|
||||||
|
private Long totalSize;
|
||||||
|
|
||||||
|
@Schema(description = "총 용량 (읽기 쉬운 형식)", example = "9.77 GB")
|
||||||
|
private String totalSizeFormatted;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Schema(description = "모델별 학습 실행 상태 응답")
|
||||||
|
public static class ModelExecutionStatusRes {
|
||||||
|
@Schema(description = "모델 번호", example = "G1")
|
||||||
|
private String modelNo;
|
||||||
|
|
||||||
|
@Schema(description = "실행 상태 메시지", example = "G1 모델에 테스트를 진행중입니다.")
|
||||||
|
private String statusMessage;
|
||||||
|
|
||||||
|
@Schema(description = "1단계 상태", example = "COMPLETED")
|
||||||
|
private String step1State;
|
||||||
|
|
||||||
|
@Schema(description = "2단계 상태", example = "IN_PROGRESS")
|
||||||
|
private String step2State;
|
||||||
|
|
||||||
|
@Schema(description = "현재 실행 중인 단계", example = "2")
|
||||||
|
private Integer currentStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Schema(description = "전체 모델 학습 실행 상태 목록 응답")
|
||||||
|
public static class AllModelsExecutionStatusRes {
|
||||||
|
@Schema(description = "모델별 실행 상태 목록")
|
||||||
|
private List<ModelExecutionStatusRes> modelStatuses;
|
||||||
|
|
||||||
|
@Schema(description = "현재 실행 중인 모델 개수", example = "2")
|
||||||
|
private Integer runningCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
package com.kamco.cd.training.filemanager.service;
|
package com.kamco.cd.training.filemanager.service;
|
||||||
|
|
||||||
import com.kamco.cd.training.filemanager.dto.FileManagerDto;
|
import com.kamco.cd.training.filemanager.dto.FileManagerDto;
|
||||||
|
import com.kamco.cd.training.postgres.entity.DatasetEntity;
|
||||||
|
import com.kamco.cd.training.postgres.entity.ModelMasterEntity;
|
||||||
|
import com.kamco.cd.training.postgres.repository.dataset.DatasetRepository;
|
||||||
|
import com.kamco.cd.training.postgres.repository.model.ModelMngRepository;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.FileVisitResult;
|
import java.nio.file.FileVisitResult;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@@ -12,10 +16,13 @@ import java.time.Instant;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -26,6 +33,18 @@ public class FileManagerService {
|
|||||||
private static final String BASE_DATA_PATH = "/data";
|
private static final String BASE_DATA_PATH = "/data";
|
||||||
private static final long MAX_PATH_LENGTH = 500;
|
private static final long MAX_PATH_LENGTH = 500;
|
||||||
|
|
||||||
|
@Value("${train.docker.request_dir}")
|
||||||
|
private String requestDir;
|
||||||
|
|
||||||
|
@Value("${train.docker.response_dir}")
|
||||||
|
private String responseDir;
|
||||||
|
|
||||||
|
@Value("${train.docker.symbolic_link_dir}")
|
||||||
|
private String symbolicLinkDir;
|
||||||
|
|
||||||
|
private final ModelMngRepository modelMngRepository;
|
||||||
|
private final DatasetRepository datasetRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 디렉토리 내 파일 목록 조회
|
* 디렉토리 내 파일 목록 조회
|
||||||
*
|
*
|
||||||
@@ -231,4 +250,228 @@ public class FileManagerService {
|
|||||||
throw new IllegalArgumentException("상대 경로(..)는 사용할 수 없습니다");
|
throw new IllegalArgumentException("상대 경로(..)는 사용할 수 없습니다");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 모델 파일 경로 조회
|
||||||
|
*
|
||||||
|
* @param modelUuid 모델 UUID
|
||||||
|
* @return 모델 파일 경로 및 파일 목록
|
||||||
|
*/
|
||||||
|
public FileManagerDto.ModelFilePathRes getModelFilePath(UUID modelUuid) {
|
||||||
|
// tb_model_master 테이블에서 모델 존재 여부 확인
|
||||||
|
modelMngRepository
|
||||||
|
.findByUuid(modelUuid)
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException("모델을 찾을 수 없습니다: " + modelUuid));
|
||||||
|
|
||||||
|
// request_path: symbolic_link_dir + model_uuid
|
||||||
|
String requestPath = symbolicLinkDir + "/" + modelUuid;
|
||||||
|
|
||||||
|
// response_path: response_dir + model_uuid
|
||||||
|
String responsePath = responseDir + "/" + modelUuid;
|
||||||
|
|
||||||
|
// 파일 목록 조회
|
||||||
|
List<FileManagerDto.FileInfo> requestFiles = getFilesInDirectory(requestPath);
|
||||||
|
List<FileManagerDto.FileInfo> responseFiles = getFilesInDirectory(responsePath);
|
||||||
|
|
||||||
|
return FileManagerDto.ModelFilePathRes.builder()
|
||||||
|
.modelUuid(modelUuid.toString())
|
||||||
|
.requestPath(requestPath)
|
||||||
|
.responsePath(responsePath)
|
||||||
|
.requestFiles(requestFiles)
|
||||||
|
.responseFiles(responseFiles)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 데이터셋 파일 경로 조회
|
||||||
|
*
|
||||||
|
* @param datasetUuid 데이터셋 UUID
|
||||||
|
* @return 데이터셋 파일 경로 및 파일 목록
|
||||||
|
*/
|
||||||
|
public FileManagerDto.DatasetFilePathRes getDatasetFilePath(UUID datasetUuid) {
|
||||||
|
// tb_dataset 테이블에서 데이터셋 조회
|
||||||
|
DatasetEntity dataset =
|
||||||
|
datasetRepository
|
||||||
|
.findByUuid(datasetUuid)
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException("데이터셋을 찾을 수 없습니다: " + datasetUuid));
|
||||||
|
|
||||||
|
// dataset_path 컬럼이 있으면 사용, 없으면 request_dir + uuid 사용
|
||||||
|
String datasetPath = dataset.getDatasetPath();
|
||||||
|
if (datasetPath == null || datasetPath.isEmpty()) {
|
||||||
|
datasetPath = requestDir + "/" + datasetUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 파일 목록 조회
|
||||||
|
List<FileManagerDto.FileInfo> files = getFilesInDirectory(datasetPath);
|
||||||
|
|
||||||
|
return FileManagerDto.DatasetFilePathRes.builder()
|
||||||
|
.datasetUuid(datasetUuid.toString())
|
||||||
|
.datasetPath(datasetPath)
|
||||||
|
.files(files)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 디렉토리 용량 체크
|
||||||
|
*
|
||||||
|
* @param directoryPath 디렉토리 경로
|
||||||
|
* @return 디렉토리 용량 정보
|
||||||
|
*/
|
||||||
|
public FileManagerDto.DirectoryCapacityRes checkDirectoryCapacity(String directoryPath) {
|
||||||
|
validatePath(directoryPath);
|
||||||
|
|
||||||
|
Path directory = Paths.get(directoryPath);
|
||||||
|
if (!Files.exists(directory)) {
|
||||||
|
throw new IllegalArgumentException("디렉토리가 존재하지 않습니다: " + directoryPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Files.isDirectory(directory)) {
|
||||||
|
throw new IllegalArgumentException("디렉토리 경로가 아닙니다: " + directoryPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
final long[] totalSize = {0};
|
||||||
|
final int[] fileCount = {0};
|
||||||
|
final int[] directoryCount = {0};
|
||||||
|
|
||||||
|
try {
|
||||||
|
Files.walkFileTree(
|
||||||
|
directory,
|
||||||
|
new SimpleFileVisitor<>() {
|
||||||
|
@Override
|
||||||
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
|
||||||
|
totalSize[0] += attrs.size();
|
||||||
|
fileCount[0]++;
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
|
||||||
|
if (!dir.equals(directory)) {
|
||||||
|
directoryCount[0]++;
|
||||||
|
}
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("디렉토리 용량 체크 중 오류 발생: {}", directoryPath, e);
|
||||||
|
throw new RuntimeException("디렉토리 용량 체크에 실패했습니다: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return FileManagerDto.DirectoryCapacityRes.builder()
|
||||||
|
.directoryPath(directoryPath)
|
||||||
|
.fileCount(fileCount[0])
|
||||||
|
.directoryCount(directoryCount[0])
|
||||||
|
.totalSize(totalSize[0])
|
||||||
|
.totalSizeFormatted(formatFileSize(totalSize[0]))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 모델별 학습 실행 상태 조회
|
||||||
|
*
|
||||||
|
* @return 모델별 학습 실행 상태 목록
|
||||||
|
*/
|
||||||
|
public FileManagerDto.AllModelsExecutionStatusRes getModelsExecutionStatus() {
|
||||||
|
// G1 ~ G4 모델 조회
|
||||||
|
List<String> modelNumbers = Arrays.asList("G1", "G2", "G3", "G4");
|
||||||
|
List<FileManagerDto.ModelExecutionStatusRes> modelStatuses = new ArrayList<>();
|
||||||
|
int runningCount = 0;
|
||||||
|
|
||||||
|
for (String modelNo : modelNumbers) {
|
||||||
|
// model_no로 가장 최근 모델 조회 (del_yn = false)
|
||||||
|
List<ModelMasterEntity> models =
|
||||||
|
modelMngRepository.findByModelNoAndDelYnOrderByCreatedDttmDesc(modelNo, false);
|
||||||
|
|
||||||
|
if (models.isEmpty()) {
|
||||||
|
// 모델이 없으면 대기 상태
|
||||||
|
modelStatuses.add(
|
||||||
|
FileManagerDto.ModelExecutionStatusRes.builder()
|
||||||
|
.modelNo(modelNo)
|
||||||
|
.statusMessage(modelNo + " 모델은 대기 중입니다.")
|
||||||
|
.step1State(null)
|
||||||
|
.step2State(null)
|
||||||
|
.currentStep(null)
|
||||||
|
.build());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelMasterEntity model = models.getFirst();
|
||||||
|
String step1State = model.getStep1State();
|
||||||
|
String step2State = model.getStep2State();
|
||||||
|
|
||||||
|
String statusMessage;
|
||||||
|
Integer currentStep = null;
|
||||||
|
|
||||||
|
// step1, step2 상태 확인
|
||||||
|
boolean step1Running = "IN_PROGRESS".equals(step1State);
|
||||||
|
boolean step2Running = "IN_PROGRESS".equals(step2State);
|
||||||
|
|
||||||
|
if (step1Running) {
|
||||||
|
statusMessage = modelNo + " 모델에 학습(1단계)을 진행중입니다.";
|
||||||
|
currentStep = 1;
|
||||||
|
runningCount++;
|
||||||
|
} else if (step2Running) {
|
||||||
|
statusMessage = modelNo + " 모델에 테스트(2단계)를 진행중입니다.";
|
||||||
|
currentStep = 2;
|
||||||
|
runningCount++;
|
||||||
|
} else if ("COMPLETED".equals(step1State) && "COMPLETED".equals(step2State)) {
|
||||||
|
statusMessage = modelNo + " 모델은 학습이 완료되었습니다.";
|
||||||
|
} else if ("COMPLETED".equals(step1State)) {
|
||||||
|
statusMessage = modelNo + " 모델은 1단계 학습이 완료되었습니다.";
|
||||||
|
} else {
|
||||||
|
statusMessage = modelNo + " 모델은 대기 중입니다.";
|
||||||
|
}
|
||||||
|
|
||||||
|
modelStatuses.add(
|
||||||
|
FileManagerDto.ModelExecutionStatusRes.builder()
|
||||||
|
.modelNo(modelNo)
|
||||||
|
.statusMessage(statusMessage)
|
||||||
|
.step1State(step1State)
|
||||||
|
.step2State(step2State)
|
||||||
|
.currentStep(currentStep)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
return FileManagerDto.AllModelsExecutionStatusRes.builder()
|
||||||
|
.modelStatuses(modelStatuses)
|
||||||
|
.runningCount(runningCount)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 디렉토리 내 파일 목록 조회 (내부 사용) */
|
||||||
|
private List<FileManagerDto.FileInfo> getFilesInDirectory(String directoryPath) {
|
||||||
|
List<FileManagerDto.FileInfo> files = new ArrayList<>();
|
||||||
|
|
||||||
|
Path directory = Paths.get(directoryPath);
|
||||||
|
if (!Files.exists(directory)) {
|
||||||
|
log.warn("디렉토리가 존재하지 않습니다: {}", directoryPath);
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Files.isDirectory(directory)) {
|
||||||
|
log.warn("디렉토리 경로가 아닙니다: {}", directoryPath);
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
try (Stream<Path> stream = Files.list(directory)) {
|
||||||
|
stream.forEach(path -> files.add(createFileInfo(path)));
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("파일 목록 조회 중 오류 발생: {}", directoryPath, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 파일 크기 포맷팅 (읽기 쉬운 형식) */
|
||||||
|
private String formatFileSize(long size) {
|
||||||
|
if (size < 1024) {
|
||||||
|
return size + " B";
|
||||||
|
} else if (size < 1024 * 1024) {
|
||||||
|
return String.format("%.2f KB", size / 1024.0);
|
||||||
|
} else if (size < 1024 * 1024 * 1024) {
|
||||||
|
return String.format("%.2f MB", size / (1024.0 * 1024.0));
|
||||||
|
} else {
|
||||||
|
return String.format("%.2f GB", size / (1024.0 * 1024.0 * 1024.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.kamco.cd.training.model.dto.ModelTrainMngDto;
|
|||||||
import com.kamco.cd.training.model.dto.ModelTrainMngDto.ListDto;
|
import com.kamco.cd.training.model.dto.ModelTrainMngDto.ListDto;
|
||||||
import com.kamco.cd.training.postgres.entity.ModelMasterEntity;
|
import com.kamco.cd.training.postgres.entity.ModelMasterEntity;
|
||||||
import com.kamco.cd.training.train.dto.TrainRunRequest;
|
import com.kamco.cd.training.train.dto.TrainRunRequest;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@@ -28,4 +29,14 @@ public interface ModelMngRepositoryCustom {
|
|||||||
TrainRunRequest findTrainRunRequest(Long modelId);
|
TrainRunRequest findTrainRunRequest(Long modelId);
|
||||||
|
|
||||||
Long findModelStep1InProgressCnt();
|
Long findModelStep1InProgressCnt();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 모델 번호와 삭제 여부로 모델 조회 (최신순)
|
||||||
|
*
|
||||||
|
* @param modelNo 모델 번호 (G1, G2, G3, G4)
|
||||||
|
* @param delYn 삭제 여부
|
||||||
|
* @return 모델 목록
|
||||||
|
*/
|
||||||
|
List<ModelMasterEntity> findByModelNoAndDelYnOrderByCreatedDttmDesc(
|
||||||
|
String modelNo, Boolean delYn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,4 +211,14 @@ public class ModelMngRepositoryImpl implements ModelMngRepositoryCustom {
|
|||||||
.or(modelMasterEntity.step2State.eq(TrainStatusType.IN_PROGRESS.getId())))
|
.or(modelMasterEntity.step2State.eq(TrainStatusType.IN_PROGRESS.getId())))
|
||||||
.fetchOne();
|
.fetchOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ModelMasterEntity> findByModelNoAndDelYnOrderByCreatedDttmDesc(
|
||||||
|
String modelNo, Boolean delYn) {
|
||||||
|
return queryFactory
|
||||||
|
.selectFrom(modelMasterEntity)
|
||||||
|
.where(modelMasterEntity.modelNo.eq(modelNo), modelMasterEntity.delYn.eq(delYn))
|
||||||
|
.orderBy(modelMasterEntity.createdDttm.desc())
|
||||||
|
.fetch();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user