diff --git a/src/main/java/com/kamco/cd/kamcoback/common/utils/FIleChecker.java b/src/main/java/com/kamco/cd/kamcoback/common/utils/FIleChecker.java index 21f0f669..feb6c224 100644 --- a/src/main/java/com/kamco/cd/kamcoback/common/utils/FIleChecker.java +++ b/src/main/java/com/kamco/cd/kamcoback/common/utils/FIleChecker.java @@ -5,6 +5,8 @@ import static java.lang.String.CASE_INSENSITIVE_ORDER; import io.swagger.v3.oas.annotations.media.Schema; import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; @@ -31,6 +33,8 @@ import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.gce.geotiff.GeoTiffReader; import org.springframework.util.FileSystemUtils; import org.springframework.web.multipart.MultipartFile; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; public class FIleChecker { @@ -517,6 +521,65 @@ public class FIleChecker { return true; } + + public static void unzip(String fileName, String destDirectory ) throws IOException { + File destDir = new File(destDirectory); + if (!destDir.exists()) { + destDir.mkdirs(); // 대상 폴더가 없으면 생성 + } + + String zipFilePath = destDirectory+"/"+fileName; + + try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFilePath))) { + ZipEntry zipEntry = zis.getNextEntry(); + + while (zipEntry != null) { + File newFile = newFile(destDir, zipEntry); + + if (zipEntry.isDirectory()) { + if (!newFile.isDirectory() && !newFile.mkdirs()) { + throw new IOException("디렉토리 생성 실패: " + newFile); + } + + } else { + + // 상위 디렉토리가 없는 경우 생성 + File parent = newFile.getParentFile(); + if (!parent.exists() && !parent.mkdirs()) { + throw new IOException("상위 디렉토리 생성 실패: " + parent); + } + + // 실제 파일 쓰기 + try (FileOutputStream fos = new FileOutputStream(newFile)) { + byte[] buffer = new byte[1024]; + int len; + while ((len = zis.read(buffer)) > 0) { + fos.write(buffer, 0, len); + } + } + } + zipEntry = zis.getNextEntry(); + } + zis.closeEntry(); + } + } + + + public static File newFile(File destinationDir, ZipEntry zipEntry) throws IOException { + File destFile = new File(destinationDir, zipEntry.getName()); + + String destDirPath = destinationDir.getCanonicalPath(); + String destFilePath = destFile.getCanonicalPath(); + + if (!destFilePath.startsWith(destDirPath + File.separator)) { + throw new IOException("엔트리가 대상 디렉토리를 벗어남: " + zipEntry.getName()); + } + + return destFile; + } + + + public static boolean checkExtensions(String fileName, String ext) { if (fileName == null) return false; diff --git a/src/main/java/com/kamco/cd/kamcoback/model/ModelMngApiController.java b/src/main/java/com/kamco/cd/kamcoback/model/ModelMngApiController.java index 28914ec1..4a09286c 100644 --- a/src/main/java/com/kamco/cd/kamcoback/model/ModelMngApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/model/ModelMngApiController.java @@ -3,6 +3,7 @@ package com.kamco.cd.kamcoback.model; import com.kamco.cd.kamcoback.common.utils.zip.ZipUtils; import com.kamco.cd.kamcoback.config.api.ApiResponseDto; import com.kamco.cd.kamcoback.model.dto.ModelMngDto; +import com.kamco.cd.kamcoback.model.dto.ModelMngDto.ModelUploadResDto; import com.kamco.cd.kamcoback.model.service.ModelMngService; import com.kamco.cd.kamcoback.upload.dto.UploadDto; import io.swagger.v3.oas.annotations.Operation; @@ -136,7 +137,7 @@ public class ModelMngApiController { @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) @PostMapping(value = "/file-chunk-upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public ApiResponseDto fileChunkUpload( + public ApiResponseDto fileChunkUpload( @RequestParam("uuid") UUID uuid, @RequestParam("fileName") String fileName, @RequestParam("fileSize") long fileSize, diff --git a/src/main/java/com/kamco/cd/kamcoback/model/dto/ModelMngDto.java b/src/main/java/com/kamco/cd/kamcoback/model/dto/ModelMngDto.java index 28008c68..79f73e33 100644 --- a/src/main/java/com/kamco/cd/kamcoback/model/dto/ModelMngDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/model/dto/ModelMngDto.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.kamco.cd.kamcoback.common.utils.enums.CodeExpose; import com.kamco.cd.kamcoback.common.utils.enums.EnumType; import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; +import com.kamco.cd.kamcoback.upload.dto.UploadDto; import io.swagger.v3.oas.annotations.media.Schema; import java.math.BigDecimal; import java.time.ZonedDateTime; @@ -65,6 +66,8 @@ public class ModelMngDto { private String cdModelConfigFileName; private String clsModelPath; private String clsModelFileName; + private String clsModelVersion; + private double priority; private String memo; public Basic( @@ -86,6 +89,8 @@ public class ModelMngDto { String cdModelConfigFileName, String clsModelPath, String clsModelFileName, + String clsModelVersion, + double priority, String memo) { this.modelUid = modelUid; this.modelVer = modelVer; @@ -105,6 +110,8 @@ public class ModelMngDto { this.cdModelConfigFileName = cdModelConfigFileName; this.clsModelPath = clsModelPath; this.clsModelFileName = clsModelFileName; + this.clsModelVersion = clsModelVersion; + this.priority = priority; this.memo = memo; } } @@ -128,6 +135,14 @@ public class ModelMngDto { private String memo; private Boolean deleted; private UUID uuid; + private String cdModelPath; + private String cdModelFileName; + private String cdModelConfigPath; + private String cdModelConfigFileName; + private String clsModelPath; + private String clsModelFileName; + private String clsModelVersion; + private double priority; } @Schema(name = "ModelAddReq", description = "모델 등록 req") @@ -149,6 +164,8 @@ public class ModelMngDto { private String clsModelFileName; private String memo; + @JsonIgnore private String clsModelVersion; + @JsonIgnore private double priority; @JsonIgnore private UUID uuid; } @@ -176,6 +193,7 @@ public class ModelMngDto { } } + @Schema(name = "ModelMetricAddReq", description = "모델 등록 req") @Getter @Setter @@ -190,4 +208,33 @@ public class ModelMngDto { private double loss; private double iou; } + + @Schema(name = "ModelUploadResDto", description = "모델 등록 req") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class ModelUploadResDto { + private String res; + private String resMsg; + private UUID uuid; + private String filePath; + private String fileName; + private String cdModelPath; + private String cdModelFileName; + private String cdModelConfigPath; + private String cdModelConfigFileName; + private String clsModelPath; + private String clsModelFileName; + private int chunkIndex; + private int chunkTotalIndex; + + public double getUploadRate() { + if (this.chunkTotalIndex == 0) { + return 0.0; + } + return (double) (this.chunkIndex + 1) / (this.chunkTotalIndex + 1) * 100.0; + } + } + } diff --git a/src/main/java/com/kamco/cd/kamcoback/model/service/ModelMngService.java b/src/main/java/com/kamco/cd/kamcoback/model/service/ModelMngService.java index b0d6b3f0..312a5895 100644 --- a/src/main/java/com/kamco/cd/kamcoback/model/service/ModelMngService.java +++ b/src/main/java/com/kamco/cd/kamcoback/model/service/ModelMngService.java @@ -1,12 +1,19 @@ package com.kamco.cd.kamcoback.model.service; +import com.kamco.cd.kamcoback.common.utils.FIleChecker; +import com.kamco.cd.kamcoback.common.utils.FIleChecker.Basic; import com.kamco.cd.kamcoback.config.api.ApiResponseDto; +import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.FilesDto; +import com.kamco.cd.kamcoback.mapsheet.dto.FileDto.SrchFilesDto; import com.kamco.cd.kamcoback.model.dto.ModelMngDto; import com.kamco.cd.kamcoback.model.dto.ModelMngDto.ModelMetricAddReq; +import com.kamco.cd.kamcoback.model.dto.ModelMngDto.ModelUploadResDto; import com.kamco.cd.kamcoback.postgres.core.ModelMngCoreService; import com.kamco.cd.kamcoback.upload.dto.UploadDto; import com.kamco.cd.kamcoback.upload.service.UploadService; +import java.io.IOException; import java.time.LocalDate; +import java.util.List; import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; @@ -63,6 +70,8 @@ public class ModelMngService { public ApiResponseDto.ResponseObj insertModel(ModelMngDto.AddReq addReq) { UUID uuid = UUID.randomUUID(); addReq.setUuid(uuid); + addReq.setClsModelVersion(addReq.getModelVer()); + addReq.setPriority(0L); Long modelUid = modelMngCoreService.insertModel(addReq); ModelMetricAddReq modelMetricAddReq = new ModelMetricAddReq(); @@ -74,15 +83,80 @@ public class ModelMngService { modelMetricAddReq.setLoss(0); modelMetricAddReq.setIou(0); + modelMngCoreService.insertModelResultMetric(modelMetricAddReq); return new ApiResponseDto.ResponseObj(ApiResponseDto.ApiResponseCode.OK, "등록되었습니다."); } - public UploadDto.UploadRes uploadChunkModelFile( + public ModelUploadResDto uploadChunkModelFile( UploadDto.UploadAddReq upAddReqDto, MultipartFile chunkFile) { - UploadDto.UploadRes upRes = uploadService.uploadChunk(upAddReqDto, chunkFile); + UploadDto.UploadRes upRes = uploadService.uploadChunk(upAddReqDto, chunkFile); - return upRes; + + ModelUploadResDto modelUploadResDto = new ModelUploadResDto(); + modelUploadResDto.setRes(upRes.getRes()); + modelUploadResDto.setResMsg(upRes.getResMsg()); + modelUploadResDto.setUuid(upRes.getUuid()); + modelUploadResDto.setFilePath(upRes.getFilePath()); + modelUploadResDto.setFileName(upRes.getFileName()); + modelUploadResDto.setChunkIndex(upRes.getChunkIndex()); + modelUploadResDto.setChunkTotalIndex(upRes.getChunkTotalIndex()); + //압축풀기 (String zipFilePath, String destDirectory) + + if( upRes.getChunkIndex() == upRes.getChunkTotalIndex() ) { + try { + FIleChecker.unzip(upRes.getFileName(), upRes.getFilePath()); + + this.getUnzipModelFiles(upRes.getFilePath(), modelUploadResDto); + + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + + + return modelUploadResDto; + } + + public ModelUploadResDto getUnzipModelFiles(String dirPath, ModelUploadResDto modelUploadResDto) { + + //String dirPath = srchDto.getDirPath(); + int startPos = 0; + int endPos = 20; + + List files = + FIleChecker.getFilesFromAllDepth( + dirPath, + "*", + "pth,py", + 10, + "name", + startPos, + endPos); + + for (Basic dto : files) { + // 예: 파일명 출력 및 추가 작업 + String foldNm = dto.getFullPath().replace(dto.getFileNm(), ""); + + if( dto.getExtension().equals("pth") ) { + modelUploadResDto.setCdModelPath(foldNm); + modelUploadResDto.setCdModelFileName(dto.getFileNm()); + }else if( dto.getExtension().equals("py") ) { + modelUploadResDto.setCdModelConfigPath(foldNm); + modelUploadResDto.setCdModelConfigFileName(dto.getFileNm()); + }else if( dto.getExtension().equals("json") ) { + modelUploadResDto.setClsModelPath(foldNm); + modelUploadResDto.setClsModelFileName(dto.getFileNm()); + } + + } + + //int fileListPos = 0; + //int fileTotCnt = files.size(); + //long fileTotSize = FIleChecker.getFileTotSize(files); + + return modelUploadResDto; } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/ModelMngCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/ModelMngCoreService.java index 411197d6..0b05413e 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/ModelMngCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/ModelMngCoreService.java @@ -4,6 +4,7 @@ import com.kamco.cd.kamcoback.model.dto.ModelMngDto; import com.kamco.cd.kamcoback.postgres.entity.ModelMngEntity; import com.kamco.cd.kamcoback.postgres.repository.model.ModelMngRepository; import java.time.LocalDate; +import java.time.ZonedDateTime; import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; @@ -55,6 +56,9 @@ public class ModelMngCoreService { addEntity.setClsModelPath(addReq.getClsModelPath()); addEntity.setClsModelFileName(addReq.getClsModelFileName()); addEntity.setDeleted(false); + addEntity.setClsModelVersion(addReq.getClsModelVersion()); + addEntity.setPriority(addReq.getPriority()); + addEntity.setCreateCompleteDttm(ZonedDateTime.now()); // modelMngRepository.insertModel(addReq); ModelMngEntity entity = modelMngRepository.save(addEntity); diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/model/ModelMngRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/model/ModelMngRepositoryImpl.java index 83e2bf28..6da27b60 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/model/ModelMngRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/model/ModelMngRepositoryImpl.java @@ -81,7 +81,16 @@ public class ModelMngRepositoryImpl extends QuerydslRepositorySupport roundNumericToPercent(modelResultMetricEntity.iou), modelMngEntity.memo, modelMngEntity.deleted, - modelMngEntity.uuid)) + modelMngEntity.uuid, + modelMngEntity.cdModelPath, + modelMngEntity.cdModelFileName, + modelMngEntity.cdModelConfigPath, + modelMngEntity.cdModelConfigFileName, + modelMngEntity.clsModelPath, + modelMngEntity.clsModelFileName, + modelMngEntity.clsModelVersion, + modelMngEntity.priority + )) .from(modelMngEntity) .innerJoin(modelResultMetricEntity) .on(modelMngEntity.modelUid.eq(modelResultMetricEntity.modelUid)) diff --git a/src/main/resources/static/chunk_upload_test.html b/src/main/resources/static/chunk_upload_test.html index e05993e7..2c331d44 100644 --- a/src/main/resources/static/chunk_upload_test.html +++ b/src/main/resources/static/chunk_upload_test.html @@ -37,7 +37,7 @@ fileHash :

-->


* 결과메세지

-
+