Skip to content

refactor: 사용하지 않는 의존성 정리 및 AWS SDK v2 전환 - #2521

Merged
BaeJinho4028 merged 2 commits into
developfrom
refactor/2520-aws-sdk-v2-dependency-cleanup
Oct 30, 2026
Merged

BaeJinho4028 merged 2 commits into
developfrom
refactor/2520-aws-sdk-v2-dependency-cleanup

Conversation

@BaeJinho4028

@BaeJinho4028 BaeJinho4028 commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

🔍 개요

  • 실행 jar에 쓰지 않는 라이브러리가 많아 크기가 505MB에 달했습니다. 배포 때 이 파일을 그대로 서버에 올리고, 쓰지 않는 라이브러리도 보안 점검 대상에 포함됩니다.
  • S3, SES는 지원이 끝난 AWS SDK v1을 쓰고 있었고, S3는 presigned URL만 v2로 처리해 SDK가 둘로 나뉘어 있었습니다.
  • 실제로 쓰는 의존성만 남기고 AWS SDK를 v2로 통일해 다음을 얻습니다.
    • 배포 파일 크기 감소 (505MB → 165MB, 라이브러리 632개 → 253개)
    • 지원이 끝난 SDK 제거로 보안 패치를 계속 받을 수 있음
    • v1이 끌고 오던 Jackson 2 의존성이 줄어 Spring Boot 4(Jackson 3) 버전업 부담 감소

🚀 주요 변경 내용

  • 사용하지 않는 의존성 제거: h2, opencsv, rest-assured, 중복 선언된 mysql-connector-j
  • AWS SDK v1(aws-java-sdk) 제거, S3와 SES를 v2로 전환
    • S3Config: v2 S3Client 빈 추가. 인증은 presigner와 같은 EC2 IAM Role 방식
    • AwsSesConfig, SesMailSender, EmailService: v2 SesClient로 교체
    • DiningReportService: AmazonClientException 대신 SdkException 처리
  • v2 S3Client와 이름이 겹쳐 기존 S3Client를 S3ClientWrapper로 변경 (CloudFrontClientWrapper와 같은 규칙)
  • 의존성 제거로 빠진 라이브러리 대체
    • commons-collections → Spring CollectionUtils
    • joda-time → java.time

💬 참고 사항

  • v1과 동작을 맞춘 부분
    • 존재 확인: v2에는 doesObjectExist가 없어, v1처럼 HEAD 요청이 404면 false, 그 외 오류는 예외로 처리
    • 일괄 삭제: v2는 일부 실패를 예외 대신 응답에 담아 주므로, 응답의 실패 목록을 확인해 기존과 같은 예외를 던짐
    • 업로드 Content-Type(application/octet-stream)과 public-read 권한은 기존과 같음
  • 검증
    • ./gradlew build 통과 (테스트 1,702개 실패 0, webAuthHttpTest 통과)
    • localstack에서 업로드, 다운로드, 존재 확인, 단건·일괄 삭제, 메일 발송 확인
    • firebase-admin은 건드리지 않음 (FCM 관련 라이브러리 구성이 기존과 같음)
  • 배포 후 stage에서 확인할 것
    • 이미지 업로드, 삭제 (S3, EC2 IAM Role 인증)
    • 메일 발송 (SES)
    • 식단 품절 신고 이미지 확인
    • 푸시 발송 (FCM)
  • jackson-dataformat-cbor가 빠져 application/cbor 형식 요청은 더 이상 처리하지 않음 (사용처 없음)

📌 후속 작업

  • firebase-admin이 끌고 오는 Firestore/Storage(gRPC) 제외. 단순 제외하면 FCM 발송이 실패해서 필요한 라이브러리를 남기고 stage에서 확인 후 적용
  • AWS SDK v2 버전업 (현재 2.20.56). 2.30 이상은 업로드 체크섬 기본 동작이 바뀌어 확인 필요
  • testcontainers 버전 통일 (1.21.4와 junit-jupiter 1.19.3 혼재)
  • 직접 고정한 오래된 버전 점검 (spring-security-crypto 6.2.2, jsoup 1.15.3, zip4j 2.6.1) — Spring Boot 버전업 때 함께
  • SesMailSender의 @Recover 메서드 인자가 sendMail과 맞지 않아 재시도 실패 시 호출되지 않음 (기존 문제)

✅ Checklist (완료 조건)

  • 코드 스타일 가이드 준수
  • 테스트 코드 포함됨 (기존 테스트를 v2에 맞게 수정, 새 테스트 없음)
  • Reviewers / Assignees / Labels 지정 완료
  • 보안 및 민감 정보 검증 (API 키, 환경 변수, 개인정보 등)

Summary by CodeRabbit

  • Bug Fixes
    • Dining report image checks now return a clear storage-unavailable error when image storage cannot be reached. Existing image validation rules remain unchanged.
  • Service Updates
    • Email delivery and file uploads, downloads, and deletion continue to be supported with updated cloud service integrations. These changes do not alter the existing email content or upload behavior.

- AWS SDK v1 전체 묶음을 s3, ses 모듈로 교체
- 사용하지 않는 h2, opencsv, rest-assured와 중복 선언된 mysql-connector-j 제거
- opencsv 제거로 빠진 commons-collections 대신 Spring CollectionUtils 사용
- S3, SES 클라이언트를 SDK v2로 교체하고 v1 의존성 제거
- v2 S3Client와 이름이 겹쳐 기존 S3Client를 S3ClientWrapper로 변경
- v1을 통해 들어오던 joda-time 대신 java.time 사용
@github-actions github-actions Bot added 공통 백엔드 공통으로 작업할 이슈입니다. 인프라 서버환경과 같은 인프라와 관련된 이슈입니다 리팩터링 리팩터링을 위한 이슈입니다 labels Oct 30, 2026
@coderabbitai

coderabbitai Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4753bec8-56d0-45a4-bc03-f0489ecfbb16
Commits

Reviewing files that changed from the base of the PR and between 3cf7661 and 2e611b6.

Files selected for processing: 20
  • build.gradle
  • src/main/java/in/koreatech/koin/domain/community/article/service/ArticleService.java
  • src/main/java/in/koreatech/koin/domain/community/article/service/summary/ArticleSummarySourceReader.java
  • src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java
  • src/main/java/in/koreatech/koin/domain/dining/service/DiningReportService.java
  • src/main/java/in/koreatech/koin/domain/shop/repository/shop/ShopSearchQueryRepository.java
  • src/main/java/in/koreatech/koin/domain/student/service/StudentValidationService.java
  • src/main/java/in/koreatech/koin/infrastructure/config/AwsSesConfig.java
  • src/main/java/in/koreatech/koin/infrastructure/config/S3Config.java
  • src/main/java/in/koreatech/koin/infrastructure/email/client/SesMailSender.java
  • src/main/java/in/koreatech/koin/infrastructure/email/service/EmailService.java
  • src/main/java/in/koreatech/koin/infrastructure/s3/client/S3ClientWrapper.java
  • src/main/java/in/koreatech/koin/infrastructure/s3/eventlistener/S3EventListener.java
  • src/main/java/in/koreatech/koin/infrastructure/s3/service/UploadService.java
  • src/test/java/in/koreatech/koin/acceptance/domain/DiningSoldOutReportApiTest.java
  • src/test/java/in/koreatech/koin/acceptance/domain/DiningSoldOutReportConcurrencyTest.java
  • src/test/java/in/koreatech/koin/acceptance/domain/UploadServiceTest.java
  • src/test/java/in/koreatech/koin/unit/domain/community/article/service/summary/ArticleSummarySourceReaderTest.java
  • src/test/java/in/koreatech/koin/unit/domain/dining/service/DiningReportImageValidationTest.java
  • src/test/java/in/koreatech/koin/unit/infrastructure/s3/client/S3ClientWrapperTest.java

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

The build removes several dependencies and adjusts dependency scopes. S3 and SES move from AWS SDK v1 to v2. Application services and tests update their S3 client types and calls, and email request construction uses SDK v2 types.

Changes: AWS SDK migration and dependency cleanup

Layer / File(s) Summary
Build dependencies and type updates
build.gradle, src/main/java/in/koreatech/koin/domain/shop/repository/shop/ShopSearchQueryRepository.java, src/main/java/in/koreatech/koin/domain/student/service/StudentValidationService.java
The MySQL connector becomes runtime-only. H2, OpenCSV, Rest Assured, and AWS SDK v1 are removed, and AWS SDK v2 SES is added. The two imports switch to Spring CollectionUtils and java.time.LocalDateTime.
Configure and implement the SDK v2 S3 client
src/main/java/in/koreatech/koin/infrastructure/config/S3Config.java, src/main/java/in/koreatech/koin/infrastructure/s3/client/S3ClientWrapper.java, src/test/java/in/koreatech/koin/unit/infrastructure/s3/client/S3ClientWrapperTest.java
S3 configuration and the wrapper use SDK v2. The wrapper implements upload, deletion, download, and existence checks with SDK v2 requests.
Wire S3 wrapper into services and tests
src/main/java/in/koreatech/koin/domain/community/article/service/ArticleService.java, src/main/java/in/koreatech/koin/domain/community/article/service/summary/ArticleSummarySourceReader.java, src/main/java/in/koreatech/koin/domain/coop/service/CoopService.java, src/main/java/in/koreatech/koin/domain/dining/service/DiningReportService.java, src/main/java/in/koreatech/koin/infrastructure/s3/eventlistener/S3EventListener.java, src/main/java/in/koreatech/koin/infrastructure/s3/service/UploadService.java, src/test/java/in/koreatech/koin/acceptance/domain/*, src/test/java/in/koreatech/koin/unit/domain/community/article/service/summary/ArticleSummarySourceReaderTest.java, src/test/java/in/koreatech/koin/unit/domain/dining/service/DiningReportImageValidationTest.java
The services and listener use S3ClientWrapper. Dining image validation catches SDK v2 exceptions, and affected tests use the wrapper and SDK v2 client requests.
Configure SES and send email
src/main/java/in/koreatech/koin/infrastructure/config/AwsSesConfig.java, src/main/java/in/koreatech/koin/infrastructure/email/client/SesMailSender.java, src/main/java/in/koreatech/koin/infrastructure/email/service/EmailService.java
The SES bean and mail sender use SDK v2. EmailService builds the SDK v2 request while retaining its destination, source, rendered HTML, subject, and UTF-8 charsets.

Priority: Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Refactor

Possibly related issues

  • BCSDLab/KOIN_API_V2#2520 — Its stated goals include removing unused dependencies and moving S3 and SES to AWS SDK v2, which this pull request does.

Suggested reviewers: taejinn

Merge Risk: Minimal · up to 2e611

The S3 and SES migrations have no identified merge-blocking regression. The change is ready to merge after normal checks.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly summarizes the main changes: removing unused dependencies and migrating from AWS SDK v1 to v2.
Linked Issues check Passed Issue #2520 requires two coding changes: (1) remove unused dependencies, and (2) move S3 and SES to AWS SDK v2 and remove the v1 SDK.

(1) Dependency removal: build.gradle at head removes the aws-java…
Out of Scope Changes check Passed Every change maps to the issue scope or supports it:
- Dependency removals in build.gradle (h2, opencsv, rest-assured, duplicate mysql-connector-j, aws-java-sdk v1) match the issue's unused-dependency…
Full details: Linked Issues check

Explanation

Issue #2520 requires two coding changes: (1) remove unused dependencies, and (2) move S3 and SES to AWS SDK v2 and remove the v1 SDK.

(1) Dependency removal: build.gradle at head removes the aws-java-sdk 1.12.672 dependency, the compile-scope mysql-connector-j duplicate (the runtimeOnly declaration remains), the h2 runtime dependency, opencsv, and rest-assured. The PR also replaces the Apache commons-collections and Joda-Time usages with Spring CollectionUtils and java.time in ShopSearchQueryRepository and StudentValidationService.

(2) SDK consolidation: build.gradle adds software.amazon.awssdk:ses and keeps the v2 BOM and s3 module. S3Config (verified at head) defines a v2 S3Client bean using InstanceProfileCredentialsProvider and AP_NORTHEAST_2. S3ClientWrapper (verified at head) uses v2 S3Client for upload, single and batch delete, download, and headObject-based existence checks. The summary reports that AwsSesConfig, SesMailSender, and EmailService use v2 SesClient and SendEmailRequest. Callers (ArticleService, CoopService, DiningReportService, S3EventListener, UploadService, and related tests) use the renamed S3ClientWrapper.

The issue contains no further acceptance criteria. No unmet coding requirement is found. The PR adds no new automated tests. It modifies existing tests for v2 instead. The issue does not require new tests. AwsSesConfig, SesMailSender, and EmailService were assessed from the change summary, not from source inspection at head.

Full details: Out of Scope Changes check

Explanation

Every change maps to the issue scope or supports it:

  • Dependency removals in build.gradle (h2, opencsv, rest-assured, duplicate mysql-connector-j, aws-java-sdk v1) match the issue's unused-dependency and v1-removal goals.
  • The commons-collections and Joda-Time replacements are needed because removing the dependencies that brought them in would otherwise break compilation. They are direct consequences of the cleanup.
  • The S3Client to S3ClientWrapper rename is needed to avoid a type-name clash with the v2 S3Client. It follows the existing CloudFrontClientWrapper naming pattern.
  • Test changes update existing tests to the v2 types and wrapper. They do not add unrelated behavior.
  • The DiningReportService change replaces AmazonClientException handling with SdkException handling, which is required by the v1 removal.
  • firebase-admin is not changed in build.gradle, which matches the PR description.

One side effect is documented in the PR: removing jackson-dataformat-cbor means application/cbor requests are no longer handled. This follows from removing an unused dependency, so it is connected to the issue scope. Reviewers should still confirm that no client sends CBOR requests.

Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 6 functions across 19 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

Unit Test Results

   309 files     309 suites   5m 26s ⏱️
1 658 tests 1 655 ✔️ 3 💤 0 ❌
1 703 runs  1 700 ✔️ 3 💤 0 ❌

Results for commit 2e611b6.

@kongwoojin kongwoojin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어째 재학생이 아닌 취업하신 분이 열일하시는지는 모르겠지만... 고생하셨습니다!

@BaeJinho4028
BaeJinho4028 merged commit e679418 into develop Oct 30, 2026
8 checks passed
@BaeJinho4028
BaeJinho4028 deleted the refactor/2520-aws-sdk-v2-dependency-cleanup branch October 30, 2026 14:59
@BaeJinho4028

Copy link
Copy Markdown
Collaborator Author

📦 develop 배포 결과 비교

머지 후 develop CD(run)가 성공했고, 직전 develop 배포 10회와 비교했습니다.

단계 이전 10회 (최소–최대 / 평균) 이번 배포 차이
jar 빌드 90–140초 / 127초 97초 -30초
서버 업로드 (SCP) 67–91초 / 81초 33초 -48초 (약 59%↓)
배포 스크립트 (기동 + 헬스체크) 150–188초 / 169초 132초 -37초
전체 job 335–419초 / 395초 286초 -109초 (약 28%↓)

stage 앱 기동 시간 (Started KoinApplication in N seconds)

기동 시간
이전 배포 3회 (10/29) 124.3초 / 129.3초 / 129.9초
이번 배포 98.8초
  • 배포된 jar 크기: 165.0MB (이전 약 505MB)
  • stage 상태: readiness UP, 배포 후 앱 로그에 ERROR 없음
  • 이번 배포는 1회 측정값이라 GitHub Actions 러너 상태에 따라 차이가 있을 수 있습니다. 업로드 시간은 jar 크기에 비례해 줄어든 것으로 보입니다.
  • 실제 기능(이미지 업로드·삭제, 메일 발송, 식단 품절 신고, 푸시 발송)은 아직 stage에서 확인하지 않았습니다.

@BaeJinho4028

Copy link
Copy Markdown
Collaborator Author

✅ stage 실제 동작 확인

stage 서버(EC2 IAM Role)에서 배포된 jar의 S3ClientWrapper와 v2 클라이언트로 직접 확인했습니다. 테스트 파일은 확인 후 삭제했습니다.

항목 결과
업로드 (uploadFile) 성공, ACL AllUsers:READ, stage-static.koreatech.in에서 200
존재 확인 (doesFileExist) 있는 파일 true, 없는 파일 false
presigned URL 업로드 PUT 200, 업로드 후 존재 확인 true
다운로드 (downloadS3Object) 70B 그대로 받음
일괄 삭제 (deleteFiles) 삭제 후 존재 확인 false, false
SES 발송 (v2 SesClient, us-west-2) SES가 MessageId를 반환함 (AWS 테스트 주소 success@simulator.amazonses.com)
앱 API 메일 인증 발송 (POST /users/verification/email/send) 200, 실패 로그 없음
FCM (GET /test/notification, 가짜 토큰) Google 인증 통과 후 FCM 서버가 NotRegistered 응답 → 라이브러리와 인증 정상
  • 실제 사용자에게 메일이나 푸시는 가지 않았습니다.
  • 업로드 API(/{domain}/upload/file)는 로그인 없이 호출하면 401이라, 앱 API 대신 같은 코드를 서버에서 직접 실행해 확인했습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

공통 백엔드 공통으로 작업할 이슈입니다. 리팩터링 리팩터링을 위한 이슈입니다 인프라 서버환경과 같은 인프라와 관련된 이슈입니다

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[공통] 사용하지 않는 의존성 정리 및 AWS SDK v2 전환

3 participants