[ADD] StorageStaticConfig 추가 및 로컬 스토리지 경로를 HTTP로 매핑, FileSystemStorageProvider URL 포맷 변경, Kubernetes PVC 설정 추가, MinIO 표현을 스토리지로 수정

main
bjkim 2 months ago
parent 92250f29d8
commit 254db5108a

@ -40,6 +40,25 @@ spec:
- name: S3_BUCKET_NAME - name: S3_BUCKET_NAME
# [수정 필요] Outpost 내 생성한 S3 버킷 명을 입력하세요. # [수정 필요] Outpost 내 생성한 S3 버킷 명을 입력하세요.
value: "autoflow-outpost-bucket" value: "autoflow-outpost-bucket"
volumeMounts:
- name: storage-volume
mountPath: /app/storage
volumes:
- name: storage-volume
persistentVolumeClaim:
claimName: autoflow-storage-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: autoflow-storage-pvc
namespace: autoflow
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
--- ---
apiVersion: v1 apiVersion: v1
kind: Service kind: Service

@ -0,0 +1,36 @@
package kr.re.etri.autoflow.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.io.File;
@Configuration
public class StorageStaticConfig implements WebMvcConfigurer {
@Value("${storage.local.base-path:/app/storage}")
private String basePath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// PVC 마운트 경로를 HTTP로 접근 가능하도록 설정
// 예: /api/storage/mlpipeline/test.txt -> /app/storage/mlpipeline/test.txt 호출
String location = basePath;
if (!location.endsWith("/")) {
location += "/";
}
// Windows 환경 고려 (C:/... 형식일 경우 file:///C:/...)
if (!location.startsWith("/") && location.contains(":")) {
location = "file:///" + location;
} else {
location = "file:" + location;
}
registry.addResourceHandler("/api/storage/**")
.addResourceLocations(location);
}
}

@ -92,7 +92,7 @@ public class PipelineUploadController {
response.put("pipeline", result); response.put("pipeline", result);
response.put("workflow", workflow); response.put("workflow", workflow);
response.put("attachment", attachment); response.put("attachment", attachment);
response.put("minioUrl", minioUrl); response.put("storageUrl", minioUrl);
return ResponseEntity.ok(response); return ResponseEntity.ok(response);

@ -38,7 +38,7 @@ import java.util.*;
@RequestMapping("/api/attachments") @RequestMapping("/api/attachments")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
@Tag(name = "첨부파일", description = "MinIO 첨부파일 관리 API") @Tag(name = "첨부파일", description = "첨부파일 관리 API")
public class StorageAttachmentController { public class StorageAttachmentController {
private final StorageAttachmentService storageAttachmentService; private final StorageAttachmentService storageAttachmentService;
@ -87,7 +87,7 @@ public class StorageAttachmentController {
return ResponseEntity.notFound().build(); return ResponseEntity.notFound().build();
} }
@Operation(summary = "파일 다운로드", description = "MinIO에서 파일을 다운로드합니다.") @Operation(summary = "파일 다운로드", description = "스토리지에서 파일을 다운로드합니다.")
@GetMapping("/download") @GetMapping("/download")
public ResponseEntity<byte[]> downloadFile(@RequestParam String objectName) { public ResponseEntity<byte[]> downloadFile(@RequestParam String objectName) {
try { try {
@ -135,7 +135,7 @@ public class StorageAttachmentController {
// } // }
@Operation(summary = "MinIO YAML 파일 읽기", description = "MinIO에서 YAML 파일을 다운로드하여 텍스트로 반환합니다.") @Operation(summary = "YAML 파일 읽기", description = "스토리지에서 YAML 파일을 다운로드하여 텍스트로 반환합니다.")
@GetMapping(value = "/readYamlText", produces = MediaType.TEXT_PLAIN_VALUE) @GetMapping(value = "/readYamlText", produces = MediaType.TEXT_PLAIN_VALUE)
public ResponseEntity<String> readYamlTextFromMinio(@RequestParam String objectName) { public ResponseEntity<String> readYamlTextFromMinio(@RequestParam String objectName) {
try { try {
@ -169,7 +169,7 @@ public class StorageAttachmentController {
Map<String, Object> response = new HashMap<>(); Map<String, Object> response = new HashMap<>();
response.put("attachment", saved); response.put("attachment", saved);
response.put("minioUrl", storageAttachmentService.getFileUrl(saved.getStoragePath())); response.put("storageUrl", storageAttachmentService.getFileUrl(saved.getStoragePath()));
return ResponseEntity.ok(response); return ResponseEntity.ok(response);
@ -199,7 +199,7 @@ public class StorageAttachmentController {
Map<String, Object> response = new HashMap<>(); Map<String, Object> response = new HashMap<>();
response.put("attachment", updated); response.put("attachment", updated);
response.put("minioUrl", storageAttachmentService.getFileUrl(updated.getStoragePath())); response.put("storageUrl", storageAttachmentService.getFileUrl(updated.getStoragePath()));
return ResponseEntity.ok(response); return ResponseEntity.ok(response);

@ -97,9 +97,8 @@ public class FileSystemStorageProvider implements StorageProvider {
@Override @Override
public String getFileUrl(String bucketName, String objectName, String type) { public String getFileUrl(String bucketName, String objectName, String type) {
// 로컬 파일 경로를 URL로 반환하거나 상대 경로로 반환 String bucket = (bucketName == null || bucketName.isEmpty()) ? defaultBucket : bucketName;
// 프론트엔드에서 접근 가능한 경로여야 할 경우 추가적인 서블릿 설정이 필요할 수 있음 // /api/storage/bucket/object_name 형식으로 반환하여 프론트엔드에서 편리하게 접근 가능하게 함
String targetDir = getTargetDir(bucketName); return String.format("/api/storage/%s/%s", bucket, objectName);
return Paths.get(targetDir, objectName).toAbsolutePath().toUri().toString();
} }
} }

@ -38,3 +38,6 @@ springdoc.swagger-ui.disable-swagger-default-url=true
# Multipart limit # Multipart limit
spring.servlet.multipart.max-file-size=500MB spring.servlet.multipart.max-file-size=500MB
spring.servlet.multipart.max-request-size=500MB spring.servlet.multipart.max-request-size=500MB
# ALB / Forwarded Headers
server.forward-headers-strategy=native

@ -7,3 +7,6 @@ springdoc.swagger-ui.doc-expansion=none
springdoc.swagger-ui.disable-swagger-default-url=true springdoc.swagger-ui.disable-swagger-default-url=true
spring.jpa.hibernate.ddl-auto=none spring.jpa.hibernate.ddl-auto=none
spring.sql.init.mode=never spring.sql.init.mode=never
# ALB / Forwarded Headers
server.forward-headers-strategy=native

@ -54,7 +54,7 @@ springdoc.swagger-ui.tags-sorter=alpha
storage.provider=minio storage.provider=minio
# Local FileSystem ?? # Local FileSystem ??
storage.local.base-path=./storage storage.local.base-path=/app/storage
storage.local.default-bucket=mlpipeline storage.local.default-bucket=mlpipeline
# MinIO ?? # MinIO ??

Loading…
Cancel
Save