From def84d2b1ced1c4364e256cef1b7a1eb71baaf62 Mon Sep 17 00:00:00 2001 From: teddy Date: Fri, 6 Feb 2026 10:33:12 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=ED=95=99=EC=8A=B5=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20obj=20=EC=82=AD=EC=A0=9C=20=EC=8A=A4=EC=9B=A8?= =?UTF-8?q?=EA=B1=B0=20=EB=AC=B8=EA=B5=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/kamco/cd/training/dataset/DatasetApiController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/kamco/cd/training/dataset/DatasetApiController.java b/src/main/java/com/kamco/cd/training/dataset/DatasetApiController.java index ec0fd07..8910a65 100644 --- a/src/main/java/com/kamco/cd/training/dataset/DatasetApiController.java +++ b/src/main/java/com/kamco/cd/training/dataset/DatasetApiController.java @@ -177,12 +177,12 @@ public class DatasetApiController { return ApiResponseDto.ok(datasetService.searchDatasetObjectList(searchReq)); } - @Operation(summary = "학습데이터 관리 목록 조회", description = "학습데이터 목록을 조회합니다.") + @Operation(summary = "학습데이터 관리 obj 삭제", description = "학습데이터 관리 obj 삭제 API") @ApiResponses( value = { @ApiResponse( responseCode = "200", - description = "조회 성공", + description = "삭제 성공", content = @Content( mediaType = "application/json", From 7cc339285676d5a928684cdeedd86075ed1f6c3e Mon Sep 17 00:00:00 2001 From: teddy Date: Fri, 6 Feb 2026 11:09:13 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=EC=82=AC=EC=9A=A9=20=EA=B0=80=EB=8A=A5=20?= =?UTF-8?q?=EA=B3=B5=EA=B0=84=20=EC=A1=B0=ED=9A=8C=20API=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/service/FormatStorage.java | 50 +++++++++++++++++++ .../dataset/DatasetApiController.java | 19 +++++++ .../training/dataset/dto/DatasetObjDto.java | 6 +++ .../dataset/service/DatasetService.java | 27 ++++++++++ 4 files changed, 102 insertions(+) create mode 100644 src/main/java/com/kamco/cd/training/common/service/FormatStorage.java diff --git a/src/main/java/com/kamco/cd/training/common/service/FormatStorage.java b/src/main/java/com/kamco/cd/training/common/service/FormatStorage.java new file mode 100644 index 0000000..6bce01f --- /dev/null +++ b/src/main/java/com/kamco/cd/training/common/service/FormatStorage.java @@ -0,0 +1,50 @@ +package com.kamco.cd.training.common.service; + +import java.nio.file.FileStore; +import java.nio.file.Files; +import java.nio.file.Path; + +public class FormatStorage { + + private FormatStorage() {} + + /** 디스크 사용량 조회 */ + public static DiskUsage getDiskUsage(Path path) throws Exception { + FileStore store = Files.getFileStore(path); + + long total = store.getTotalSpace(); + long usable = store.getUsableSpace(); + + return new DiskUsage(path.toString(), total, usable); + } + + /** 디스크 사용량 DTO */ + public record DiskUsage(String path, long totalBytes, long usableBytes) { + + public long usedBytes() { + return totalBytes - usableBytes; + } + + public double usedPercent() { + return totalBytes == 0 ? 0.0 : (usedBytes() * 100.0) / totalBytes; + } + + public String totalText() { + return formatStorageSize(totalBytes); + } + + public String usableText() { + return formatStorageSize(usableBytes); + } + + /** 저장공간을 사람이 읽기 좋은 단위로 변환 (GB / MB) */ + private static String formatStorageSize(long bytes) { + double gb = bytes / 1024.0 / 1024 / 1024; + if (gb >= 1) { + return String.format("%.1f GB", gb); + } + double mb = bytes / 1024.0 / 1024; + return String.format("%.0f MB", mb); + } + } +} diff --git a/src/main/java/com/kamco/cd/training/dataset/DatasetApiController.java b/src/main/java/com/kamco/cd/training/dataset/DatasetApiController.java index 8910a65..46c9d15 100644 --- a/src/main/java/com/kamco/cd/training/dataset/DatasetApiController.java +++ b/src/main/java/com/kamco/cd/training/dataset/DatasetApiController.java @@ -4,6 +4,7 @@ import com.kamco.cd.training.config.api.ApiResponseDto; import com.kamco.cd.training.dataset.dto.DatasetDto; import com.kamco.cd.training.dataset.dto.DatasetObjDto; import com.kamco.cd.training.dataset.dto.DatasetObjDto.DatasetClass; +import com.kamco.cd.training.dataset.dto.DatasetObjDto.DatasetStorage; import com.kamco.cd.training.dataset.service.DatasetService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -216,4 +217,22 @@ public class DatasetApiController { @Parameter(description = "compare, target", example = "compare") @RequestParam String type) { return ApiResponseDto.ok(datasetService.getDatasetObjByUuid(uuid, type)); } + + @Operation(summary = "남은 저장공간 조회", description = "남은 저장공간 조회 API") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "조회 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Page.class))), + @ApiResponse(responseCode = "404", description = "저장 공간 조회 오류", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + @GetMapping("/usable-bytes") + public ApiResponseDto getUsableBytes() { + return ApiResponseDto.ok(datasetService.getUsableBytes()); + } } diff --git a/src/main/java/com/kamco/cd/training/dataset/dto/DatasetObjDto.java b/src/main/java/com/kamco/cd/training/dataset/dto/DatasetObjDto.java index 54c392a..0c6c1c5 100644 --- a/src/main/java/com/kamco/cd/training/dataset/dto/DatasetObjDto.java +++ b/src/main/java/com/kamco/cd/training/dataset/dto/DatasetObjDto.java @@ -121,4 +121,10 @@ public class DatasetObjDto { return DetectionClassification.valueOf(classCd.toUpperCase()).getDesc(); } } + + @Getter + @Setter + public static class DatasetStorage { + private String usableBytes; + } } diff --git a/src/main/java/com/kamco/cd/training/dataset/service/DatasetService.java b/src/main/java/com/kamco/cd/training/dataset/service/DatasetService.java index 0971f7b..24b3c37 100644 --- a/src/main/java/com/kamco/cd/training/dataset/service/DatasetService.java +++ b/src/main/java/com/kamco/cd/training/dataset/service/DatasetService.java @@ -1,15 +1,20 @@ package com.kamco.cd.training.dataset.service; +import com.kamco.cd.training.common.exception.CustomApiException; +import com.kamco.cd.training.common.service.FormatStorage; import com.kamco.cd.training.dataset.dto.DatasetDto; import com.kamco.cd.training.dataset.dto.DatasetObjDto; import com.kamco.cd.training.dataset.dto.DatasetObjDto.DatasetClass; +import com.kamco.cd.training.dataset.dto.DatasetObjDto.DatasetStorage; import com.kamco.cd.training.dataset.dto.DatasetObjDto.SearchReq; import com.kamco.cd.training.postgres.core.DatasetCoreService; +import java.nio.file.Path; import java.util.List; import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -105,4 +110,26 @@ public class DatasetService { public List getDatasetObjByUuid(UUID uuid, String type) { return datasetCoreService.findDatasetObjClassByUuid(uuid, type); } + + /** + * 사용 가능 공간 조회 + * + * @return + */ + public DatasetStorage getUsableBytes() { + // 현재 실행 위치가 속한 디스크 기준 + try { + FormatStorage.DiskUsage usage = FormatStorage.getDiskUsage(Path.of(".")); + log.debug("경로 : {}", usage.path()); + log.debug("총 저장공간 : {}", usage.totalText()); + log.debug("남은 저장공간 : {}", usage.usableText()); + log.debug("사용률 : {}", usage.usedPercent()); + + DatasetStorage datasetStorage = new DatasetStorage(); + datasetStorage.setUsableBytes(usage.usableText()); + return datasetStorage; + } catch (Exception e) { + throw new CustomApiException("NOT_FOUND", HttpStatus.NOT_FOUND); + } + } }