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

main
bjkim 1 month ago
parent 254db5108a
commit ec1a890891

@ -1,10 +1,10 @@
FROM openjdk:17-jdk-alpine FROM openjdk:17-jdk-alpine
MAINTAINER [AutoFlow] 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);

@ -1,88 +1,93 @@
#????? ?? ?? #????? ?? ??
server.port = 8080 server.port = 8080
spring.profiles.active=local spring.profiles.active=local
spring.datasource.url=jdbc:mariadb://192.168.10.143:3306/autoflow spring.datasource.url=jdbc:mariadb://192.168.10.143:3306/autoflow
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.username=cuuva spring.datasource.username=cuuva
spring.datasource.password=cuuva spring.datasource.password=cuuva
spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect
spring.jpa.defer-datasource-initialization=true spring.jpa.defer-datasource-initialization=true
#spring.batch.jdbc.schema=classpath:org/springframework/batch/core/schema-mariadb.sql #spring.batch.jdbc.schema=classpath:org/springframework/batch/core/schema-mariadb.sql
#spring.batch.jdbc.initialize-schema=always #spring.batch.jdbc.initialize-schema=always
# App Properties # App Properties
cuuva.app.jwtCookieName=cuuva-jwt cuuva.app.jwtCookieName=cuuva-jwt
cuuva.app.jwtRefreshCookieName=cuuva-jwt-refresh cuuva.app.jwtRefreshCookieName=cuuva-jwt-refresh
cuuva.app.jwtSecret= 275511b31c520562d69802ce4a913773102563891563a24062f44b3f312ca2bd034440e81836d1b4ccf4195f43db4c81a4e489a41f1ae0967afe468c9a361f4d cuuva.app.jwtSecret= 275511b31c520562d69802ce4a913773102563891563a24062f44b3f312ca2bd034440e81836d1b4ccf4195f43db4c81a4e489a41f1ae0967afe468c9a361f4d
## For test ## For test
cuuva.app.jwtExpirationMs= 900000 cuuva.app.jwtExpirationMs= 900000
cuuva.app.jwtRefreshExpirationMs= 8640000 cuuva.app.jwtRefreshExpirationMs= 8640000
spring.jpa.show-sql=true spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.type.descriptor.sql=TRACE logging.level.org.hibernate.type.descriptor.sql=TRACE
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
spring.datasource.hikari.connection-timeout=30000 spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.idle-timeout=60000 spring.datasource.hikari.idle-timeout=60000
spring.datasource.hikari.max-lifetime=1800000 spring.datasource.hikari.max-lifetime=1800000
springdoc.api-docs.enabled=true springdoc.api-docs.enabled=true
springdoc.api-docs.path=/v3/api-docs springdoc.api-docs.path=/v3/api-docs
springdoc.swagger-ui.path=/swagger-ui springdoc.swagger-ui.path=/swagger-ui
springdoc.swagger-ui.config-url=/autoflow-server-mgmt/v3/api-docs/swagger-config springdoc.swagger-ui.config-url=/autoflow-server-mgmt/v3/api-docs/swagger-config
springdoc.swagger-ui.url=/autoflow-server-mgmt/v3/api-docs springdoc.swagger-ui.url=/autoflow-server-mgmt/v3/api-docs
springdoc.swagger-ui.doc-expansion=none springdoc.swagger-ui.doc-expansion=none
springdoc.swagger-ui.disable-swagger-default-url=true springdoc.swagger-ui.disable-swagger-default-url=true
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
springdoc.swagger-ui.tags-sorter=alpha springdoc.swagger-ui.tags-sorter=alpha
# Storage Provider (minio, s3, or filesystem) # Storage Provider (minio, s3, or filesystem)
storage.provider=minio storage.provider=minio
# Local FileSystem ?? # Local FileSystem ??
storage.local.base-path=/app/storage storage.local.base-path=/app/storage
storage.local.default-bucket=mlpipeline storage.local.default-bucket=mlpipeline
# MinIO ?? # MinIO ??
minio.endpoint=http://192.168.10.135:31795 minio.endpoint=http://192.168.10.135:31795
minio.access-key=minio minio.access-key=minio
minio.secret-key=minio123 minio.secret-key=minio123
minio.bucket=mlpipeline minio.bucket=mlpipeline
# Kubeflow # Kubeflow
kubeflow.url=http://192.168.10.135:32473/ kubeflow.url=http://192.168.10.135:32473/
# MLflow # MLflow
mlflow.url=http://192.168.10.135:30128/ mlflow.url=http://192.168.10.135:30128/
mlflow.user=user mlflow.user=user
mlflow.password=WjWjIi13KEkO mlflow.password=WjWjIi13KEkO
server.servlet.encoding.charset=UTF-8 server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true server.servlet.encoding.enabled=true
server.servlet.encoding.force=true server.servlet.encoding.force=true
spring.servlet.multipart.enabled=true spring.servlet.multipart.enabled=true
#OTA?? #OTA??
external.auth.signin-url=https://a659120d3e2ff43ff94087b29396fd96-1057696791.ap-northeast-2.elb.amazonaws.com/api/datamanager/user/signin external.auth.signin-url=https://a659120d3e2ff43ff94087b29396fd96-1057696791.ap-northeast-2.elb.amazonaws.com/api/datamanager/user/signin
external.auth.edge-search-url=https://a659120d3e2ff43ff94087b29396fd96-1057696791.ap-northeast-2.elb.amazonaws.com/api/datamanager/edge-pkg/search external.auth.edge-search-url=https://a659120d3e2ff43ff94087b29396fd96-1057696791.ap-northeast-2.elb.amazonaws.com/api/datamanager/edge-pkg/search
external.auth.sw-search-url=https://a659120d3e2ff43ff94087b29396fd96-1057696791.ap-northeast-2.elb.amazonaws.com/api/datamanager/advehicle-pkg/search external.auth.sw-search-url=https://a659120d3e2ff43ff94087b29396fd96-1057696791.ap-northeast-2.elb.amazonaws.com/api/datamanager/advehicle-pkg/search
cloud.aws.region.static=ap-northeast-2 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