diff --git a/src/main/java/kr/re/etri/autoflow/controllers/DynamicMinioAttachmentController.java b/src/main/java/kr/re/etri/autoflow/controllers/DynamicMinioAttachmentController.java index 0dc2af3..0a19656 100644 --- a/src/main/java/kr/re/etri/autoflow/controllers/DynamicMinioAttachmentController.java +++ b/src/main/java/kr/re/etri/autoflow/controllers/DynamicMinioAttachmentController.java @@ -14,6 +14,8 @@ import org.springframework.web.multipart.MultipartFile; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -82,6 +84,21 @@ public class DynamicMinioAttachmentController { } } + @PostMapping("/download-to-server") + public String downloadFileToServer( + @RequestParam String objectName, + @RequestParam String type, + @RequestParam String localPath + ) { + try { + minioService.downloadFileToServer(objectName, type, localPath); + return "파일 다운로드 성공: " + localPath; + } catch (Exception e) { + log.error("서버 파일 다운로드 실패", e); + return "파일 다운로드 실패: " + e.getMessage(); + } + } + /** * YAML 텍스트 읽기 */ diff --git a/src/main/java/kr/re/etri/autoflow/service/DynamicMinioAttachmentService.java b/src/main/java/kr/re/etri/autoflow/service/DynamicMinioAttachmentService.java index 30978f5..34d29c9 100644 --- a/src/main/java/kr/re/etri/autoflow/service/DynamicMinioAttachmentService.java +++ b/src/main/java/kr/re/etri/autoflow/service/DynamicMinioAttachmentService.java @@ -18,8 +18,11 @@ import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import java.io.File; +import java.io.FileOutputStream; import java.io.InputStream; import java.nio.charset.StandardCharsets; +import java.nio.file.Paths; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; @@ -143,6 +146,56 @@ public class DynamicMinioAttachmentService { } } + /** + * MinIO에서 파일을 다운로드하여 서버 로컬에 저장 + * @param objectName MinIO 객체 경로 + * @param type MinIO 타입 + * @param localPath 서버에 저장할 로컬 경로 (예: /tmp/artifacts/) + * @return 저장된 로컬 파일 + */ + public File downloadFileToServer(String objectName, String type, String localPath) { + MinioClient client = getClientByType(type); + String bucketName = getBucketByType(type); + + try { + // mlflow-artifacts:/ 접두어 제거 + String cleanObjectName = objectName.replaceFirst("^mlflow-artifacts:/", "") + .replaceAll("^/+", "").replaceAll("/+$", ""); + + // 파일 확장자 체크 + if (!cleanObjectName.matches(".*\\.[a-zA-Z0-9]+$")) { + throw new RuntimeException("요청된 객체가 파일이 아닙니다: " + cleanObjectName); + } + + // 파일명 추출 + String fileName = Paths.get(cleanObjectName).getFileName().toString(); + File localDir = new File(localPath); + if (!localDir.exists()) localDir.mkdirs(); + File localFile = new File(localDir, fileName); + + try (InputStream is = client.getObject( + GetObjectArgs.builder() + .bucket(bucketName) + .object(cleanObjectName) + .build() + ); + FileOutputStream fos = new FileOutputStream(localFile) + ) { + byte[] buffer = new byte[8192]; + int bytesRead; + while ((bytesRead = is.read(buffer)) != -1) { + fos.write(buffer, 0, bytesRead); + } + } + + return localFile; + + } catch (Exception e) { + throw new RuntimeException("MinIO 파일 다운로드 실패: " + objectName, e); + } + } + + /** YAML 텍스트 읽기 */ public String readYamlText(String objectName, String type) { MinioClient client = getClientByType(type);