This commit is contained in:
2026-04-08 15:23:48 +09:00
parent 593db69245
commit 61d28c4ce3

View File

@@ -56,7 +56,7 @@ public class FileManagerService {
*/ */
public FileManagerDto.ListFilesRes listFiles(FileManagerDto.ListFilesReq request) { public FileManagerDto.ListFilesRes listFiles(FileManagerDto.ListFilesReq request) {
String targetPath = String targetPath =
request.getDirectoryPath() != null ? request.getDirectoryPath() : BASE_DATA_PATH; request.getDirectoryPath() != null ? request.getDirectoryPath() : BASE_DATA_PATH;
boolean recursive = request.getRecursive() != null && request.getRecursive(); boolean recursive = request.getRecursive() != null && request.getRecursive();
@@ -66,32 +66,32 @@ public class FileManagerService {
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
log.debug("유효하지 않은 경로: {}", targetPath); log.debug("유효하지 않은 경로: {}", targetPath);
return FileManagerDto.ListFilesRes.builder() return FileManagerDto.ListFilesRes.builder()
.directoryPath(targetPath) .directoryPath(targetPath)
.files(new ArrayList<>()) .files(new ArrayList<>())
.totalCount(0) .totalCount(0)
.totalSize(0L) .totalSize(0L)
.build(); .build();
} }
Path directory = Paths.get(targetPath); Path directory = Paths.get(targetPath);
if (!Files.exists(directory)) { if (!Files.exists(directory)) {
log.debug("디렉토리가 존재하지 않습니다: {}", targetPath); log.debug("디렉토리가 존재하지 않습니다: {}", targetPath);
return FileManagerDto.ListFilesRes.builder() return FileManagerDto.ListFilesRes.builder()
.directoryPath(targetPath) .directoryPath(targetPath)
.files(new ArrayList<>()) .files(new ArrayList<>())
.totalCount(0) .totalCount(0)
.totalSize(0L) .totalSize(0L)
.build(); .build();
} }
if (!Files.isDirectory(directory)) { if (!Files.isDirectory(directory)) {
log.debug("디렉토리 경로가 아닙니다: {}", targetPath); log.debug("디렉토리 경로가 아닙니다: {}", targetPath);
return FileManagerDto.ListFilesRes.builder() return FileManagerDto.ListFilesRes.builder()
.directoryPath(targetPath) .directoryPath(targetPath)
.files(new ArrayList<>()) .files(new ArrayList<>())
.totalCount(0) .totalCount(0)
.totalSize(0L) .totalSize(0L)
.build(); .build();
} }
List<FileManagerDto.FileInfo> files = new ArrayList<>(); List<FileManagerDto.FileInfo> files = new ArrayList<>();
@@ -101,22 +101,22 @@ public class FileManagerService {
if (recursive) { if (recursive) {
// 재귀적으로 모든 하위 파일 조회 // 재귀적으로 모든 하위 파일 조회
Files.walkFileTree( Files.walkFileTree(
directory, directory,
new SimpleFileVisitor<>() { new SimpleFileVisitor<>() {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
files.add(createFileInfo(file)); files.add(createFileInfo(file));
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
if (!dir.equals(directory)) {
files.add(createFileInfo(dir));
} }
return FileVisitResult.CONTINUE;
} @Override
}); public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
if (!dir.equals(directory)) {
files.add(createFileInfo(dir));
}
return FileVisitResult.CONTINUE;
}
});
} else { } else {
// 현재 디렉토리의 파일만 조회 // 현재 디렉토리의 파일만 조회
try (Stream<Path> stream = Files.list(directory)) { try (Stream<Path> stream = Files.list(directory)) {
@@ -134,19 +134,19 @@ public class FileManagerService {
} catch (IOException e) { } catch (IOException e) {
log.debug("파일 목록 조회 중 오류 발생: {}", targetPath, e); log.debug("파일 목록 조회 중 오류 발생: {}", targetPath, e);
return FileManagerDto.ListFilesRes.builder() return FileManagerDto.ListFilesRes.builder()
.directoryPath(targetPath) .directoryPath(targetPath)
.files(new ArrayList<>()) .files(new ArrayList<>())
.totalCount(0) .totalCount(0)
.totalSize(0L) .totalSize(0L)
.build(); .build();
} }
return FileManagerDto.ListFilesRes.builder() return FileManagerDto.ListFilesRes.builder()
.directoryPath(targetPath) .directoryPath(targetPath)
.files(files) .files(files)
.totalCount(files.size()) .totalCount(files.size())
.totalSize(totalSize) .totalSize(totalSize)
.build(); .build();
} }
/** /**
@@ -208,15 +208,15 @@ public class FileManagerService {
} }
String message = String message =
String.format("%d개 파일 삭제 성공, %d개 파일 삭제 실패", deletedFiles.size(), failedFiles.size()); String.format("%d개 파일 삭제 성공, %d개 파일 삭제 실패", deletedFiles.size(), failedFiles.size());
return FileManagerDto.DeleteFileRes.builder() return FileManagerDto.DeleteFileRes.builder()
.deletedFiles(deletedFiles) .deletedFiles(deletedFiles)
.failedFiles(failedFiles) .failedFiles(failedFiles)
.successCount(deletedFiles.size()) .successCount(deletedFiles.size())
.failureCount(failedFiles.size()) .failureCount(failedFiles.size())
.message(message) .message(message)
.build(); .build();
} }
/** FileInfo 객체 생성 */ /** FileInfo 객체 생성 */
@@ -225,45 +225,45 @@ public class FileManagerService {
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class); BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
return FileManagerDto.FileInfo.builder() return FileManagerDto.FileInfo.builder()
.fileName(path.getFileName().toString()) .fileName(path.getFileName().toString())
.filePath(path.toString()) .filePath(path.toString())
.fileSize(attrs.isRegularFile() ? attrs.size() : null) .fileSize(attrs.isRegularFile() ? attrs.size() : null)
.isFile(attrs.isRegularFile()) .isFile(attrs.isRegularFile())
.isDirectory(attrs.isDirectory()) .isDirectory(attrs.isDirectory())
.lastModified( .lastModified(
LocalDateTime.ofInstant( LocalDateTime.ofInstant(
Instant.ofEpochMilli(attrs.lastModifiedTime().toMillis()), Instant.ofEpochMilli(attrs.lastModifiedTime().toMillis()),
ZoneId.systemDefault())) ZoneId.systemDefault()))
.readable(Files.isReadable(path)) .readable(Files.isReadable(path))
.writable(Files.isWritable(path)) .writable(Files.isWritable(path))
.build(); .build();
} catch (IOException e) { } catch (IOException e) {
log.warn("파일 정보 조회 실패: {}", path, e); log.warn("파일 정보 조회 실패: {}", path, e);
return FileManagerDto.FileInfo.builder() return FileManagerDto.FileInfo.builder()
.fileName(path.getFileName().toString()) .fileName(path.getFileName().toString())
.filePath(path.toString()) .filePath(path.toString())
.build(); .build();
} }
} }
/** 디렉토리 재귀 삭제 */ /** 디렉토리 재귀 삭제 */
private void deleteDirectoryRecursively(Path directory) throws IOException { private void deleteDirectoryRecursively(Path directory) throws IOException {
Files.walkFileTree( Files.walkFileTree(
directory, directory,
new SimpleFileVisitor<>() { new SimpleFileVisitor<>() {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException { throws IOException {
Files.delete(file); Files.delete(file);
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }
@Override @Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir); Files.delete(dir);
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }
}); });
} }
/** 디렉토리가 비어있는지 확인 */ /** 디렉토리가 비어있는지 확인 */
@@ -302,12 +302,12 @@ public class FileManagerService {
// 모델이 존재하지 않으면 빈 데이터 반환 // 모델이 존재하지 않으면 빈 데이터 반환
if (model == null) { if (model == null) {
return FileManagerDto.ModelFilePathRes.builder() return FileManagerDto.ModelFilePathRes.builder()
.modelUuid(modelUuid.toString()) .modelUuid(modelUuid.toString())
.requestPath(null) .requestPath(null)
.responsePath(null) .responsePath(null)
.requestFiles(new ArrayList<>()) .requestFiles(new ArrayList<>())
.responseFiles(new ArrayList<>()) .responseFiles(new ArrayList<>())
.build(); .build();
} }
// request_path: tb_model_master.request_path 컬럼 값 사용 // request_path: tb_model_master.request_path 컬럼 값 사용
@@ -330,12 +330,12 @@ public class FileManagerService {
List<FileManagerDto.FileInfo> responseFiles = getFilesInDirectory(responsePath); List<FileManagerDto.FileInfo> responseFiles = getFilesInDirectory(responsePath);
return FileManagerDto.ModelFilePathRes.builder() return FileManagerDto.ModelFilePathRes.builder()
.modelUuid(modelUuid.toString()) .modelUuid(modelUuid.toString())
.requestPath(requestPath) .requestPath(requestPath)
.responsePath(responsePath) .responsePath(responsePath)
.requestFiles(requestFiles) .requestFiles(requestFiles)
.responseFiles(responseFiles) .responseFiles(responseFiles)
.build(); .build();
} }
/** /**
@@ -351,10 +351,10 @@ public class FileManagerService {
// 데이터셋이 존재하지 않으면 빈 데이터 반환 // 데이터셋이 존재하지 않으면 빈 데이터 반환
if (dataset == null) { if (dataset == null) {
return FileManagerDto.DatasetFilePathRes.builder() return FileManagerDto.DatasetFilePathRes.builder()
.datasetUuid(datasetUuid.toString()) .datasetUuid(datasetUuid.toString())
.datasetPath(null) .datasetPath(null)
.files(new ArrayList<>()) .files(new ArrayList<>())
.build(); .build();
} }
// dataset_path 컬럼이 있으면 사용, 없으면 request_dir + uuid 사용 // dataset_path 컬럼이 있으면 사용, 없으면 request_dir + uuid 사용
@@ -367,10 +367,10 @@ public class FileManagerService {
List<FileManagerDto.FileInfo> files = getFilesInDirectory(datasetPath); List<FileManagerDto.FileInfo> files = getFilesInDirectory(datasetPath);
return FileManagerDto.DatasetFilePathRes.builder() return FileManagerDto.DatasetFilePathRes.builder()
.datasetUuid(datasetUuid.toString()) .datasetUuid(datasetUuid.toString())
.datasetPath(datasetPath) .datasetPath(datasetPath)
.files(files) .files(files)
.build(); .build();
} }
/** /**
@@ -386,35 +386,35 @@ public class FileManagerService {
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
log.debug("유효하지 않은 경로: {}", directoryPath); log.debug("유효하지 않은 경로: {}", directoryPath);
return FileManagerDto.DirectoryCapacityRes.builder() return FileManagerDto.DirectoryCapacityRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(0) .fileCount(0)
.directoryCount(0) .directoryCount(0)
.totalSize(0L) .totalSize(0L)
.totalSizeFormatted("0 B") .totalSizeFormatted("0 B")
.build(); .build();
} }
Path directory = Paths.get(directoryPath); Path directory = Paths.get(directoryPath);
if (!Files.exists(directory)) { if (!Files.exists(directory)) {
log.debug("디렉토리가 존재하지 않습니다: {}", directoryPath); log.debug("디렉토리가 존재하지 않습니다: {}", directoryPath);
return FileManagerDto.DirectoryCapacityRes.builder() return FileManagerDto.DirectoryCapacityRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(0) .fileCount(0)
.directoryCount(0) .directoryCount(0)
.totalSize(0L) .totalSize(0L)
.totalSizeFormatted("0 B") .totalSizeFormatted("0 B")
.build(); .build();
} }
if (!Files.isDirectory(directory)) { if (!Files.isDirectory(directory)) {
log.debug("디렉토리 경로가 아닙니다: {}", directoryPath); log.debug("디렉토리 경로가 아닙니다: {}", directoryPath);
return FileManagerDto.DirectoryCapacityRes.builder() return FileManagerDto.DirectoryCapacityRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(0) .fileCount(0)
.directoryCount(0) .directoryCount(0)
.totalSize(0L) .totalSize(0L)
.totalSizeFormatted("0 B") .totalSizeFormatted("0 B")
.build(); .build();
} }
final long[] totalSize = {0}; final long[] totalSize = {0};
@@ -423,41 +423,41 @@ public class FileManagerService {
try { try {
Files.walkFileTree( Files.walkFileTree(
directory, directory,
new SimpleFileVisitor<>() { new SimpleFileVisitor<>() {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
totalSize[0] += attrs.size(); totalSize[0] += attrs.size();
fileCount[0]++; fileCount[0]++;
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
if (!dir.equals(directory)) {
directoryCount[0]++;
} }
return FileVisitResult.CONTINUE;
} @Override
}); public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
if (!dir.equals(directory)) {
directoryCount[0]++;
}
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) { } catch (IOException e) {
log.debug("디렉토리 용량 체크 중 오류 발생: {}", directoryPath, e); log.debug("디렉토리 용량 체크 중 오류 발생: {}", directoryPath, e);
return FileManagerDto.DirectoryCapacityRes.builder() return FileManagerDto.DirectoryCapacityRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(0) .fileCount(0)
.directoryCount(0) .directoryCount(0)
.totalSize(0L) .totalSize(0L)
.totalSizeFormatted("0 B") .totalSizeFormatted("0 B")
.build(); .build();
} }
return FileManagerDto.DirectoryCapacityRes.builder() return FileManagerDto.DirectoryCapacityRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(fileCount[0]) .fileCount(fileCount[0])
.directoryCount(directoryCount[0]) .directoryCount(directoryCount[0])
.totalSize(totalSize[0]) .totalSize(totalSize[0])
.totalSizeFormatted(formatFileSize(totalSize[0])) .totalSizeFormatted(formatFileSize(totalSize[0]))
.build(); .build();
} }
/** /**
@@ -474,18 +474,18 @@ public class FileManagerService {
for (String modelNo : modelNumbers) { for (String modelNo : modelNumbers) {
// model_no로 가장 최근 모델 조회 (del_yn = false) // model_no로 가장 최근 모델 조회 (del_yn = false)
List<ModelMasterEntity> models = List<ModelMasterEntity> models =
modelMngRepository.findByModelNoAndDelYnOrderByCreatedDttmDesc(modelNo, false); modelMngRepository.findByModelNoAndDelYnOrderByCreatedDttmDesc(modelNo, false);
if (models.isEmpty()) { if (models.isEmpty()) {
// 모델이 없으면 대기 상태 // 모델이 없으면 대기 상태
modelStatuses.add( modelStatuses.add(
FileManagerDto.ModelExecutionStatusRes.builder() FileManagerDto.ModelExecutionStatusRes.builder()
.modelNo(modelNo) .modelNo(modelNo)
.statusMessage(modelNo + " 모델은 대기 중입니다.") .statusMessage(modelNo + " 모델은 대기 중입니다.")
.step1State(null) .step1State(null)
.step2State(null) .step2State(null)
.currentStep(null) .currentStep(null)
.build()); .build());
continue; continue;
} }
@@ -517,19 +517,19 @@ public class FileManagerService {
} }
modelStatuses.add( modelStatuses.add(
FileManagerDto.ModelExecutionStatusRes.builder() FileManagerDto.ModelExecutionStatusRes.builder()
.modelNo(modelNo) .modelNo(modelNo)
.statusMessage(statusMessage) .statusMessage(statusMessage)
.step1State(step1State) .step1State(step1State)
.step2State(step2State) .step2State(step2State)
.currentStep(currentStep) .currentStep(currentStep)
.build()); .build());
} }
return FileManagerDto.AllModelsExecutionStatusRes.builder() return FileManagerDto.AllModelsExecutionStatusRes.builder()
.modelStatuses(modelStatuses) .modelStatuses(modelStatuses)
.runningCount(runningCount) .runningCount(runningCount)
.build(); .build();
} }
/** 디렉토리 내 파일 목록 조회 (내부 사용) */ /** 디렉토리 내 파일 목록 조회 (내부 사용) */
@@ -582,37 +582,37 @@ public class FileManagerService {
if (!Files.exists(directory)) { if (!Files.exists(directory)) {
log.debug("디렉토리가 존재하지 않습니다: {}", directoryPath); log.debug("디렉토리가 존재하지 않습니다: {}", directoryPath);
return FileManagerDto.StorageSpaceRes.builder() return FileManagerDto.StorageSpaceRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(0) .fileCount(0)
.directoryCount(0) .directoryCount(0)
.usedSize(0L) .usedSize(0L)
.usedSizeFormatted("0 B") .usedSizeFormatted("0 B")
.totalDiskSpace(0L) .totalDiskSpace(0L)
.totalDiskSpaceFormatted("0 B") .totalDiskSpaceFormatted("0 B")
.freeSpace(0L) .freeSpace(0L)
.freeSpaceFormatted("0 B") .freeSpaceFormatted("0 B")
.usableSpace(0L) .usableSpace(0L)
.usableSpaceFormatted("0 B") .usableSpaceFormatted("0 B")
.usagePercentage(0.0) .usagePercentage(0.0)
.build(); .build();
} }
if (!Files.isDirectory(directory)) { if (!Files.isDirectory(directory)) {
log.debug("디렉토리 경로가 아닙니다: {}", directoryPath); log.debug("디렉토리 경로가 아닙니다: {}", directoryPath);
return FileManagerDto.StorageSpaceRes.builder() return FileManagerDto.StorageSpaceRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(0) .fileCount(0)
.directoryCount(0) .directoryCount(0)
.usedSize(0L) .usedSize(0L)
.usedSizeFormatted("0 B") .usedSizeFormatted("0 B")
.totalDiskSpace(0L) .totalDiskSpace(0L)
.totalDiskSpaceFormatted("0 B") .totalDiskSpaceFormatted("0 B")
.freeSpace(0L) .freeSpace(0L)
.freeSpaceFormatted("0 B") .freeSpaceFormatted("0 B")
.usableSpace(0L) .usableSpace(0L)
.usableSpaceFormatted("0 B") .usableSpaceFormatted("0 B")
.usagePercentage(0.0) .usagePercentage(0.0)
.build(); .build();
} }
// 디렉토리 사용량 계산 (재귀적으로 모든 파일 크기 합산) // 디렉토리 사용량 계산 (재귀적으로 모든 파일 크기 합산)
@@ -622,39 +622,39 @@ public class FileManagerService {
try { try {
Files.walkFileTree( Files.walkFileTree(
directory, directory,
new SimpleFileVisitor<>() { new SimpleFileVisitor<>() {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
usedSize[0] += attrs.size(); usedSize[0] += attrs.size();
fileCount[0]++; fileCount[0]++;
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
if (!dir.equals(directory)) {
directoryCount[0]++;
} }
return FileVisitResult.CONTINUE;
} @Override
}); public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
if (!dir.equals(directory)) {
directoryCount[0]++;
}
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) { } catch (IOException e) {
log.debug("디렉토리 용량 계산 중 오류 발생: {}", directoryPath, e); log.debug("디렉토리 용량 계산 중 오류 발생: {}", directoryPath, e);
return FileManagerDto.StorageSpaceRes.builder() return FileManagerDto.StorageSpaceRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(0) .fileCount(0)
.directoryCount(0) .directoryCount(0)
.usedSize(0L) .usedSize(0L)
.usedSizeFormatted("0 B") .usedSizeFormatted("0 B")
.totalDiskSpace(0L) .totalDiskSpace(0L)
.totalDiskSpaceFormatted("0 B") .totalDiskSpaceFormatted("0 B")
.freeSpace(0L) .freeSpace(0L)
.freeSpaceFormatted("0 B") .freeSpaceFormatted("0 B")
.usableSpace(0L) .usableSpace(0L)
.usableSpaceFormatted("0 B") .usableSpaceFormatted("0 B")
.usagePercentage(0.0) .usagePercentage(0.0)
.build(); .build();
} }
// 디스크 공간 정보 조회 (FileStore 사용) // 디스크 공간 정보 조회 (FileStore 사용)
@@ -680,18 +680,18 @@ public class FileManagerService {
} }
return FileManagerDto.StorageSpaceRes.builder() return FileManagerDto.StorageSpaceRes.builder()
.directoryPath(directoryPath) .directoryPath(directoryPath)
.fileCount(fileCount[0]) .fileCount(fileCount[0])
.directoryCount(directoryCount[0]) .directoryCount(directoryCount[0])
.usedSize(usedSize[0]) .usedSize(usedSize[0])
.usedSizeFormatted(formatFileSize(usedSize[0])) .usedSizeFormatted(formatFileSize(usedSize[0]))
.totalDiskSpace(totalDiskSpace) .totalDiskSpace(totalDiskSpace)
.totalDiskSpaceFormatted(formatFileSize(totalDiskSpace)) .totalDiskSpaceFormatted(formatFileSize(totalDiskSpace))
.freeSpace(freeSpace) .freeSpace(freeSpace)
.freeSpaceFormatted(formatFileSize(freeSpace)) .freeSpaceFormatted(formatFileSize(freeSpace))
.usableSpace(usableSpace) .usableSpace(usableSpace)
.usableSpaceFormatted(formatFileSize(usableSpace)) .usableSpaceFormatted(formatFileSize(usableSpace))
.usagePercentage(Math.round(usagePercentage * 100.0) / 100.0) .usagePercentage(Math.round(usagePercentage * 100.0) / 100.0)
.build(); .build();
} }
} }