From 8580e510c3ae9f29eb945af814feaf7f10a44a83 Mon Sep 17 00:00:00 2001 From: dong2ast Date: Mon, 15 Jan 2024 02:06:49 +0900 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20[FEAT]=20=EA=B8=B0=EC=A1=B4=20S3=20?= =?UTF-8?q?url=EC=9D=84=20CloudFront=EB=A5=BC=20=ED=86=B5=ED=95=9C=20url?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/sopt/lequuServer/InitDb.java | 31 +++++++++---------- .../domain/book/facade/BookFacade.java | 13 ++++---- .../domain/note/facade/NoteFacade.java | 7 +++-- .../global/s3/dto/PreSignedUrlResponse.java | 2 +- .../global/s3/service/S3Service.java | 27 ++++++++++------ src/main/resources/application.yml | 1 + 6 files changed, 45 insertions(+), 36 deletions(-) diff --git a/src/main/java/org/sopt/lequuServer/InitDb.java b/src/main/java/org/sopt/lequuServer/InitDb.java index 96b5eb1..51b31dd 100644 --- a/src/main/java/org/sopt/lequuServer/InitDb.java +++ b/src/main/java/org/sopt/lequuServer/InitDb.java @@ -29,12 +29,12 @@ public void init() { } private static final List CHARACTER_STICKERS = Arrays.asList( - "https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/character_1.svg", - "https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/character_2.svg", - "https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/character_3.svg", - "https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/character_4.svg", - "https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/character_5.svg", - "https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/character_6.svg" + "https://dzfv99wxq6tx0.cloudfront.net/stickers/character_1.svg", + "https://dzfv99wxq6tx0.cloudfront.net/stickers/character_2.svg", + "https://dzfv99wxq6tx0.cloudfront.net/stickers/character_3.svg", + "https://dzfv99wxq6tx0.cloudfront.net/stickers/character_4.svg", + "https://dzfv99wxq6tx0.cloudfront.net/stickers/character_5.svg", + "https://dzfv99wxq6tx0.cloudfront.net/stickers/character_6.svg" ); @Component @@ -55,14 +55,13 @@ public void dbInit() { .socialPlatform(SocialPlatform.KAKAO) .socialId("3251153440") .build(); - member1.updateNickname("레큐"); member1.updateSocialInfo("레큐", "http://k.kakaocdn.net/dn/1G9kp/btsAot8liOn/8CWudi3uy07rvFNUkk3ER0/img_640x640.jpg"); em.persist(member1); Book book1 = Book.builder() .uuid("ee4f66f9-9cf4-4b28-90f4-f71d0ecba021") .favoriteName("LeoJ") - .favoriteImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/books/favorite_image/b4006561-382b-479e-ae1d-e841922e883f.jpg") + .favoriteImage("https://dzfv99wxq6tx0.cloudfront.net/books/favorite_image/b4006561-382b-479e-ae1d-e841922e883f.jpg") .title("1번째 레큐북") .description("레큐북의 내용입니다!") .backgroundColor(1) @@ -74,7 +73,7 @@ public void dbInit() { Book book = Book.builder() .uuid("ee4f66f9-9cf4-4b28-90f4-f71d0ecba02" + String.valueOf(i + 1)) .favoriteName("LeoJ") - .favoriteImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/books/favorite_image/b4006561-382b-479e-ae1d-e841922e883f.jpg") + .favoriteImage("https://dzfv99wxq6tx0.cloudfront.net/books/favorite_image/b4006561-382b-479e-ae1d-e841922e883f.jpg") .title(String.valueOf(i + 1) + "번째 레큐북") .description("레큐북의 내용입니다!") .backgroundColor(1) @@ -87,7 +86,7 @@ public void dbInit() { for (int i = 0; i < 3; i++) { Note note = Note.builder() .content("레큐노트 내용입니다 블라블라블라 블라블라블라 블라블라블라 블라블라블라 블라블라블라 블라블라블라 블라블라블라") - .background("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/notes/background_image/676c2ca3-f868-423f-8000-a0bcb67dc797.jpg") + .background("https://dzfv99wxq6tx0.cloudfront.net/notes/background_image/676c2ca3-f868-423f-8000-a0bcb67dc797.jpg") .textColor(0) .member(member1) .book(book1) @@ -108,14 +107,14 @@ public void dbInit() { Sticker sticker1 = Sticker.builder() .bookId(0L) .category(BIRTHDAY) - .stickerImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/birth_1.svg") + .stickerImage("https://dzfv99wxq6tx0.cloudfront.net/stickers/birth_1.svg") .build(); em.persist(sticker1); for (int i = 0; i < 3; i++) { Sticker sticker = Sticker.builder() .bookId(0L) .category(ALPHABET) - .stickerImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg") + .stickerImage("https://dzfv99wxq6tx0.cloudfront.net/stickers/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg") .build(); em.persist(sticker); } @@ -123,7 +122,7 @@ public void dbInit() { Sticker sticker = Sticker.builder() .bookId(0L) .category(BIRTHDAY) - .stickerImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg") + .stickerImage("https://dzfv99wxq6tx0.cloudfront.net/stickers/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg") .build(); em.persist(sticker); } @@ -140,7 +139,7 @@ public void dbInit() { Sticker sticker = Sticker.builder() .bookId(1L) .category(ALPHABET) - .stickerImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg") + .stickerImage("https://dzfv99wxq6tx0.cloudfront.net/stickers/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg") .build(); em.persist(sticker); } @@ -148,7 +147,7 @@ public void dbInit() { Sticker sticker = Sticker.builder() .bookId(1L) .category(BIRTHDAY) - .stickerImage("https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/stickers/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg") + .stickerImage("https://dzfv99wxq6tx0.cloudfront.net/stickers/8d83b1c1-1e2c-437b-a2f5-e3ce96ce6d35.jpg") .build(); em.persist(sticker); } @@ -169,4 +168,4 @@ private boolean isDatabaseEmpty() { return count == 0; } } -} +} \ No newline at end of file diff --git a/src/main/java/org/sopt/lequuServer/domain/book/facade/BookFacade.java b/src/main/java/org/sopt/lequuServer/domain/book/facade/BookFacade.java index 673f893..4421410 100644 --- a/src/main/java/org/sopt/lequuServer/domain/book/facade/BookFacade.java +++ b/src/main/java/org/sopt/lequuServer/domain/book/facade/BookFacade.java @@ -1,5 +1,9 @@ package org.sopt.lequuServer.domain.book.facade; +import static org.sopt.lequuServer.global.s3.enums.ImageFolderName.BOOK_FAVORITE_IMAGE_FOLDER_NAME; + +import java.util.List; +import java.util.UUID; import lombok.RequiredArgsConstructor; import org.sopt.lequuServer.domain.book.dto.request.BookCreateRequestDto; import org.sopt.lequuServer.domain.book.dto.response.BookCreateResponseDto; @@ -18,11 +22,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; -import java.util.UUID; - -import static org.sopt.lequuServer.global.s3.enums.ImageFolderName.BOOK_FAVORITE_IMAGE_FOLDER_NAME; - @Service @RequiredArgsConstructor public class BookFacade { @@ -50,7 +49,9 @@ public BookCreateResponseDto createBook(BookCreateRequestDto request, Long membe // UUID 생성 String bookUuid = UUID.randomUUID().toString(); // Presigned URL 이미지 업로드하기 위한 이미지 파일명 가져오기 - String imageUrl = s3Service.getURL(BOOK_FAVORITE_IMAGE_FOLDER_NAME.getValue() + request.favoriteImage()); +// String imageUrl = s3Service.getURL(BOOK_FAVORITE_IMAGE_FOLDER_NAME.getValue() + request.favoriteImage()); + String imageUrl = s3Service.getCloudFrontURL( + BOOK_FAVORITE_IMAGE_FOLDER_NAME.getValue() + request.favoriteImage()); Book book = Book.builder() .uuid(bookUuid) diff --git a/src/main/java/org/sopt/lequuServer/domain/note/facade/NoteFacade.java b/src/main/java/org/sopt/lequuServer/domain/note/facade/NoteFacade.java index 4a5ac96..2295e3a 100644 --- a/src/main/java/org/sopt/lequuServer/domain/note/facade/NoteFacade.java +++ b/src/main/java/org/sopt/lequuServer/domain/note/facade/NoteFacade.java @@ -1,5 +1,7 @@ package org.sopt.lequuServer.domain.note.facade; +import static org.sopt.lequuServer.global.s3.enums.ImageFolderName.NOTE_BACKGROUND_IMAGE_FOLDER_NAME; + import lombok.RequiredArgsConstructor; import org.sopt.lequuServer.domain.book.model.Book; import org.sopt.lequuServer.domain.book.repository.BookRepository; @@ -12,8 +14,6 @@ import org.sopt.lequuServer.global.s3.service.S3Service; import org.springframework.stereotype.Service; -import static org.sopt.lequuServer.global.s3.enums.ImageFolderName.NOTE_BACKGROUND_IMAGE_FOLDER_NAME; - @Service @RequiredArgsConstructor public class NoteFacade { @@ -29,7 +29,8 @@ public NoteCreateResponseDto createNote(Long userId, NoteCreateDto noteCreateDto String background = noteCreateDto.background(); if (background.endsWith(".jpg")) { - background = s3Service.getURL(NOTE_BACKGROUND_IMAGE_FOLDER_NAME.getValue() + noteCreateDto.background()); +// background = s3Service.getURL(NOTE_BACKGROUND_IMAGE_FOLDER_NAME.getValue() + noteCreateDto.background()); + background = s3Service.getCloudFrontURL(NOTE_BACKGROUND_IMAGE_FOLDER_NAME.getValue() + noteCreateDto.background()); } return noteService.saveNote(Note.of(noteCreateDto.content(), background, noteCreateDto.textColor(), member, book), member, book); diff --git a/src/main/java/org/sopt/lequuServer/global/s3/dto/PreSignedUrlResponse.java b/src/main/java/org/sopt/lequuServer/global/s3/dto/PreSignedUrlResponse.java index 72cff3a..1980b26 100644 --- a/src/main/java/org/sopt/lequuServer/global/s3/dto/PreSignedUrlResponse.java +++ b/src/main/java/org/sopt/lequuServer/global/s3/dto/PreSignedUrlResponse.java @@ -11,7 +11,7 @@ public class PreSignedUrlResponse { @Schema(description = "반환된 Presigned URL로 PUT 하면 저장될 이미지 제목", example = "60c49750-0b2f-4fad-b340-9ffbb0074ebf.jpg") private String fileName; - @Schema(description = "PUT 해야하는 Presigned URL", example = "https://lequu-server-bucket.s3.ap-northeast-2.amazonaws.com/books/favorite_image/60c49750-0b2f-4fad-b340-9ffbb0074ebf.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240109T033832Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=AKIA522AYZTVU66QK4A2%2F20240109%2Fap-northeast-2%2Fs3%2Faws4_request&X-Amz-Signature=eb628c3d15f9056b82436ff73dd8714071fa43ad97b0073ef0ca182d5ee074c2") + @Schema(description = "PUT 해야하는 Presigned URL", example = "https://dzfv99wxq6tx0.cloudfront.net/books/favorite_image/60c49750-0b2f-4fad-b340-9ffbb0074ebf.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240109T033832Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=AKIA522AYZTVU66QK4A2%2F20240109%2Fap-northeast-2%2Fs3%2Faws4_request&X-Amz-Signature=eb628c3d15f9056b82436ff73dd8714071fa43ad97b0073ef0ca182d5ee074c2") private String url; public static PreSignedUrlResponse of(String fileName, String url) { diff --git a/src/main/java/org/sopt/lequuServer/global/s3/service/S3Service.java b/src/main/java/org/sopt/lequuServer/global/s3/service/S3Service.java index b2dffaa..2c48344 100644 --- a/src/main/java/org/sopt/lequuServer/global/s3/service/S3Service.java +++ b/src/main/java/org/sopt/lequuServer/global/s3/service/S3Service.java @@ -1,5 +1,15 @@ package org.sopt.lequuServer.global.s3.service; +import static org.sopt.lequuServer.global.exception.enums.ErrorType.GET_UPLOAD_PRESIGNED_URL_ERROR; +import static org.sopt.lequuServer.global.exception.enums.ErrorType.IMAGE_EXTENSION_ERROR; +import static org.sopt.lequuServer.global.exception.enums.ErrorType.IMAGE_SIZE_ERROR; + +import java.io.IOException; +import java.net.URL; +import java.time.Duration; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; import lombok.val; import org.sopt.lequuServer.global.config.AWSConfig; import org.sopt.lequuServer.global.exception.model.CustomException; @@ -16,19 +26,11 @@ import software.amazon.awssdk.services.s3.presigner.S3Presigner; import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest; -import java.io.IOException; -import java.net.URL; -import java.time.Duration; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; - -import static org.sopt.lequuServer.global.exception.enums.ErrorType.*; - @Service public class S3Service { private final String bucketName; + private final String cloudFront; private final AWSConfig awsConfig; // 파일 확장자 제한 jpeg, png, jpg, webp @@ -38,8 +40,9 @@ public class S3Service { // PreSigned URL 만료시간 60분 private static final Long PRE_SIGNED_URL_EXPIRE_MINUTE = 60L; - public S3Service(@Value("${cloud.aws.credentials.s3-bucket-name}") final String bucketName, AWSConfig awsConfig) { + public S3Service(@Value("${cloud.aws.credentials.s3-bucket-name}") final String bucketName, @Value("${cloud.aws.credentials.cloud-front}") final String cloudFront, AWSConfig awsConfig) { this.bucketName = bucketName; + this.cloudFront = cloudFront; this.awsConfig = awsConfig; } @@ -150,4 +153,8 @@ public String getURL(final String imageKey) { throw new RuntimeException(e.getMessage()); } } + + public String getCloudFrontURL(final String imageKey) { + return "https://" + cloudFront + "/" + imageKey; + } } \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 344132b..c7adc76 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -18,6 +18,7 @@ cloud: secretKey: ${SECRET_KEY} aws-region: ap-northeast-2 s3-bucket-name: ${BUCKET_NAME} + cloud-front: ${CLOUD_FRONT} springdoc: packages-to-scan: org.sopt.lequuServer