Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: #BBB-125 AWS S3 multipart 방식 영상 업로드 API 구현 #52

Merged
merged 6 commits into from
Nov 14, 2024

Conversation

platinouss
Copy link
Contributor

@platinouss platinouss commented Sep 1, 2024

작업 개요

image

구현

AWS S3에 multipart 방식으로 영상 업로드를 위해서 3가지를 적용했습니다.

  1. initiate 과정 (uploadId 생성)
  2. presigned-url 생성 및 응답 (partNumber 마다 생성)
  3. multipart upload 완료 요청 전달

전달 사항

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AddPerm",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"  // 추가
            ],
            ...
        }
    ]
}
  • 파일을 업로드 하기 위해서는, S3에서 버킷 정책과 CORS 설정을 추가 해줘야함
...
"ExposeHeaders": [
  "ETag"
]
...
  • partNumber 마다 업로드 성공 시 eTag를 반환하는데, header에서 eTag를 정상적으로 받아오기 위해서는 CORS 설정 ExposeHeaders에 ETag를 추가해줘야 함
  • 또한 put 요청으로 chunk된 데이터를 보낼 때, formData로 래핑해서 보낼 필요 없이, 원시 데이터를 그대로 보내야함

참고 자료

spring cloud aws 참고자료

https://docs.awspring.io/spring-cloud-aws/docs/3.1.0/reference/html/index.html#spring-cloud-aws-s3
https://github.com/awspring/spring-cloud-aws?tab=readme-ov-file

presigned-url 생성 관련 aws 공식 문서

https://docs.aws.amazon.com/AmazonS3/latest/userguide/example_s3_Scenario_PresignedUrl_section.html

AWS Multipart upload 제한 조건

https://docs.aws.amazon.com/AmazonS3/latest/userguide/qfacts.html

AWS S3 multipart upload 흐름 이해를 위한 공식 문서 (Java SDK)

https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/userguide/S3OutpostsMPU.html

@platinouss platinouss added the ✨Feat 새로운 기능 추가 label Sep 1, 2024
@platinouss platinouss self-assigned this Sep 1, 2024
@platinouss platinouss marked this pull request as draft September 1, 2024 05:15

public String generatePreSignedGetUrl(Long userId, String fileName) {
ObjectMetadata metadata = ObjectMetadata.builder()
.metadata("userId", String.valueOf(userId))
Copy link
Contributor Author

@platinouss platinouss Sep 2, 2024

Choose a reason for hiding this comment

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

파일 명으로 구분 또는 사용자 정의 태그 설정 가능. 2kb까지, object tagging 권한이 있어야 함?
유효기간 동안 누구나 접근할 수 있는 문제 또는 유효 기간이 넘으면 볼 수 없는 문제
s3 버킷 이름 production, dev 환경 (보통 /production, /dev 이런식으로 작명)
파일 5gb 이상인경우 multipart 형식으로 올려야함 (파일 여러개 올리는 방법 찾아보기)
https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html
헤더 설정 Content-Type: video/*

@platinouss platinouss changed the title Feat: #BBB-125 S3에 영상 업로드를 위한 presigned-url 생성 API Feat: #BBB-125 AWS S3 multipart 방식 영상 업로드 API 구현 Sep 9, 2024
@platinouss platinouss force-pushed the feat/generate_presigned_url#BBB-125 branch from 6010fc7 to 2efb8aa Compare September 10, 2024 09:46
@platinouss platinouss marked this pull request as ready for review September 10, 2024 09:46
Copy link
Contributor

@msjang4 msjang4 left a comment

Choose a reason for hiding this comment

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

고생하셨습니다.
generateUpload 때 partSize는 어떤 값으로 설정하는지, 또 presignedUrl에 Put요청을 보낼 때 원본파일을 어떻게 partSize만큼만 잘라서 보낼 수 있는지 궁금하네요.

}

public GeneratePresignedUrlResponse generatePresignedUrl(GeneratePresignedUrlRequest request) {
try (S3Presigner presigner = S3Presigner.create()) {
Copy link
Contributor

@msjang4 msjang4 Sep 18, 2024

Choose a reason for hiding this comment

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

try 구문이 이런식으로도 되는지 첨알았네요 배워갑니다

@platinouss
Copy link
Contributor Author

platinouss commented Sep 18, 2024

고생하셨습니다. generateUpload 때 partSize는 어떤 값으로 설정하는지, 또 presignedUrl에 Put요청을 보낼 때 원본파일을 어떻게 partSize만큼만 잘라서 보낼 수 있는지 궁금하네요.

@msjang4
https://docs.aws.amazon.com/AmazonS3/latest/userguide/qfacts.html

  • partSize는 5MB ~ 5GB로만 설정할 수 있고, 범위 내라면 사용자가 원하는 크기로 설정할 수 있어요. (마지막 파트는 제한 조건에 걸리지 않아요)
  • 특정 파트 업로드가 네트워크 문제 등으로 실패하면, 해당 파트 업로드를 다시 처음부터 진행해야 하기 때문에 너무 크게 설정하지 않는게 좋다고 생각했어요. 하지만 너무 작게 설정하면 호출횟수가 증가하는 문제는 있지만 API 서버를 거치지 않고 AWS에 다이렉트로 보내는 거다 보니 보통 100MB 이내로 설정하는 것 같더라구요
  • partSize만큼 쪼개는 부분은 실제 파일을 설정된 바이트 단위로 읽어서 AWS에 요청하게 돼요. 아직 기술 서적 대시보드 로드되는 부분이 완전히 완료되지 않아서 프론트 코드는 임시로 만들어 두어서 PR은 업로드 하지 않았는데, 완전히 완성되면 제가 영상 업로드 버튼이랑 연동 완료 후 PR 업로드 할게요

@msjang4 msjang4 closed this Sep 18, 2024
@msjang4 msjang4 reopened this Sep 18, 2024
@msjang4 msjang4 force-pushed the feat/generate_presigned_url#BBB-125 branch from 2e6bf04 to 9b476df Compare November 1, 2024 11:44
@platinouss platinouss force-pushed the feat/generate_presigned_url#BBB-125 branch from 9b476df to a7e37a5 Compare November 14, 2024 13:57
@platinouss platinouss merged commit 7368e5b into develop Nov 14, 2024
1 check passed
@platinouss platinouss deleted the feat/generate_presigned_url#BBB-125 branch December 5, 2024 09:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨Feat 새로운 기능 추가
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

2 participants