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); + } + } }