[ADD] StorageTestController 추가 및 파일 업로드/URL 조회 기능 구현, Kubernetes 매니페스트 업데이트 및 Spring Actuator 설정 추가

main
bjkim 1 month ago
parent 254db5108a
commit ec1a890891

@ -4,7 +4,7 @@ MAINTAINER [AutoFlow]
RUN apk --no-cache add tzdata && cp /usr/share/zoneinfo/Asia/Seoul /etc/localtime RUN apk --no-cache add tzdata && cp /usr/share/zoneinfo/Asia/Seoul /etc/localtime
RUN mkdir /server RUN mkdir /server
ADD build/libs/autoflow-0.0.1-SNAPSHOT.jar /server/autoflow-0.0.1-SNAPSHOT.jar COPY build/libs/*.jar /server/app.jar
WORKDIR /server WORKDIR /server
ENTRYPOINT ["java", "-jar", "autoflow-0.0.1-SNAPSHOT.jar"] ENTRYPOINT ["java", "-jar", "app.jar"]

@ -2,7 +2,7 @@ apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: autoflow-server name: autoflow-server
namespace: autoflow namespace: etri
spec: spec:
replicas: 1 replicas: 1
selector: selector:
@ -13,17 +13,16 @@ spec:
labels: labels:
app: autoflow-server app: autoflow-server
spec: spec:
nodeSelector:
nodegroup: cpu
containers: containers:
- name: autoflow-server - name: autoflow-server
# [수정] 외부 레지스트리 주소를 제거하고 로컬 태그만 사용
image: autoflow-server:latest image: autoflow-server:latest
# [추가] 외부에서 이미지를 다운로드하지 않고 로컬 이미지를 사용하도록 강제
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
ports: ports:
- containerPort: 8080 - containerPort: 8080
env: env:
- name: RDS_HOSTNAME - name: RDS_HOSTNAME
# [수정 필요] Outpost 내부 RDS의 Private IP 또는 DNS를 입력하세요.
value: "INTERNAL_RDS_IP_HERE" value: "INTERNAL_RDS_IP_HERE"
- name: RDS_USERNAME - name: RDS_USERNAME
value: "admin" value: "admin"
@ -38,8 +37,19 @@ spec:
name: autoflow-secrets name: autoflow-secrets
key: jwt-secret key: jwt-secret
- name: S3_BUCKET_NAME - name: S3_BUCKET_NAME
# [수정 필요] Outpost 내 생성한 S3 버킷 명을 입력하세요.
value: "autoflow-outpost-bucket" value: "autoflow-outpost-bucket"
livenessProbe:
httpGet:
path: /autoflow-server-mgmt/actuator/health
port: 8080
initialDelaySeconds: 60
periodSeconds: 15
readinessProbe:
httpGet:
path: /autoflow-server-mgmt/actuator/health
port: 8080
initialDelaySeconds: 60
periodSeconds: 15
volumeMounts: volumeMounts:
- name: storage-volume - name: storage-volume
mountPath: /app/storage mountPath: /app/storage
@ -52,10 +62,11 @@ apiVersion: v1
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
metadata: metadata:
name: autoflow-storage-pvc name: autoflow-storage-pvc
namespace: autoflow namespace: etri
spec: spec:
accessModes: accessModes:
- ReadWriteOnce - ReadWriteOnce
storageClassName: gp2
resources: resources:
requests: requests:
storage: 10Gi storage: 10Gi
@ -64,13 +75,45 @@ apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: autoflow-server-svc name: autoflow-server-svc
namespace: autoflow namespace: etri
spec: spec:
# Outpost EKS 환경에 따라 LoadBalancer 또는 NodePort를 선택하세요.
type: LoadBalancer
selector: selector:
app: autoflow-server app: autoflow-server
ports: ports:
- protocol: TCP - protocol: TCP
port: 80 port: 80
targetPort: 8080 targetPort: 8080
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: autoflow-server-ingress
namespace: etri
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/backend-protocol: HTTP
# [수정 필요] 실제 서브넷 ID 및 보안 그룹 ID 입력 필요
alb.ingress.kubernetes.io/subnets: subnet-xxxx, subnet-yyyy
alb.ingress.kubernetes.io/group.name: etri-group
alb.ingress.kubernetes.io/security-groups: sg-xxxx
alb.ingress.kubernetes.io/customer-owned-ipv4-pool: ipv4pool-xxxx
alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
alb.ingress.kubernetes.io/healthcheck-path: /autoflow-server-mgmt/actuator/health
alb.ingress.kubernetes.io/healthcheck-interval-seconds: "15"
alb.ingress.kubernetes.io/healthy-threshold-count: "2"
alb.ingress.kubernetes.io/unhealthy-threshold-count: "3"
alb.ingress.kubernetes.io/success-codes: "200"
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /autoflow-server-mgmt
pathType: Prefix
backend:
service:
name: autoflow-server-svc
port:
number: 80

@ -0,0 +1,47 @@
package kr.re.etri.autoflow.controller;
import kr.re.etri.autoflow.service.storage.StorageProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api/test/storage")
@RequiredArgsConstructor
public class StorageTestController {
private final StorageProvider storageProvider;
@GetMapping("/info")
public ResponseEntity<Map<String, Object>> getInfo() {
Map<String, Object> info = new HashMap<>();
info.put("providerClass", storageProvider.getClass().getSimpleName());
return ResponseEntity.ok(info);
}
@PostMapping("/upload")
public ResponseEntity<String> testUpload(@RequestParam("file") MultipartFile file) {
try (InputStream is = file.getInputStream()) {
String objectName = "test/" + file.getOriginalFilename();
storageProvider.uploadFileToDefault(objectName, is, file.getContentType(), file.getSize());
return ResponseEntity.ok("Upload successful: " + objectName);
} catch (Exception e) {
return ResponseEntity.internalServerError().body("Upload failed: " + e.getMessage());
}
}
@GetMapping("/url")
public ResponseEntity<String> getUrl(@RequestParam("name") String name) {
try {
String url = storageProvider.getFileUrl(null, name, null);
return ResponseEntity.ok(url);
} catch (Exception e) {
return ResponseEntity.internalServerError().body("Failed to get URL: " + e.getMessage());
}
}
}

@ -110,9 +110,11 @@ public class WebSecurityConfig { // extends WebSecurityConfigurerAdapter {
.exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler)) .exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> .authorizeHttpRequests(auth ->
auth.anyRequest().permitAll() // 모든 요청 허용 auth.requestMatchers("/actuator/**").permitAll() // Actuator endpoints
.anyRequest().permitAll() // 모든 요청 허용
); );
http.authenticationProvider(authenticationProvider()); http.authenticationProvider(authenticationProvider());
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class); http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);

@ -86,3 +86,8 @@ cloud.aws.region.static=ap-northeast-2
cloud.aws.credentials.access-key=AKIA2UC3EPERDDR4UOWN cloud.aws.credentials.access-key=AKIA2UC3EPERDDR4UOWN
cloud.aws.credentials.secret-key=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 cloud.aws.credentials.secret-key=Ps7ShmtcemhhTmZi+aUCpSpfZxjqFGyy51qgDSGD
cloud.aws.s3.bucket=mlpipeline cloud.aws.s3.bucket=mlpipeline
# Spring Actuator Configuration
management.endpoints.web.exposure.include=health
management.endpoint.health.show-details=always
management.health.defaults.enabled=true
Loading…
Cancel
Save