From f44e0a5ac0234c95cf51d514fadb3f82c0554f8f Mon Sep 17 00:00:00 2001 From: JiinHong Date: Mon, 28 Oct 2024 14:31:37 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=ED=95=A0=20=EB=95=8C,=20Presigned=20URL=20?= =?UTF-8?q?=EB=B0=9C=EA=B8=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/{image => }/config/AwsS3Config.java | 2 +- .../file}/FileDeleteException.java | 2 +- .../file}/FileExtensionException.java | 2 +- .../file}/FileUploadException.java | 2 +- .../file}/ImageErrorCode.java | 2 +- .../file}/ImageException.java | 2 +- .../pocket/core/image/S3TestController.java | 25 ------ .../core/image/service/AwsS3Service.java | 81 ------------------- .../domain/dto/file}/PresignedUrlRequest.java | 2 +- .../dto/file}/PresignedUrlResponse.java | 2 +- .../dto/review/ReviewGetResponseDto.java | 1 + .../domain/port/file/FileDownloadPort.java | 7 ++ .../domain/port/file/FileUploadPort.java | 9 +++ .../domain/service/album/AlbumService.java | 2 +- .../domain/service/file/FileService.java | 22 +++++ .../domain/service/review/ReviewService.java | 55 ++++++++++++- .../AlbumRegisterUseCase.java | 2 +- .../usecase/file/FileDownloadUseCase.java | 7 ++ .../usecase/file/FileUploadUseCase.java | 9 +++ .../album/presentation/AlbumController.java | 2 +- .../file/presentation/FileController.java | 6 +- .../file/presentation/FileControllerDocs.java | 4 +- .../inbounds/user/response/UserResponse.java | 2 - .../file/adapter/FileDownloadAdapter.java | 52 ++++++++++++ .../file/adapter/FileUploadAdapter.java | 37 ++++----- .../outbound/config/SecurityConfig.java | 1 + 26 files changed, 190 insertions(+), 150 deletions(-) rename core/src/main/java/com/pocket/core/{image => }/config/AwsS3Config.java (96%) rename core/src/main/java/com/pocket/core/{image/exception => exception/file}/FileDeleteException.java (88%) rename core/src/main/java/com/pocket/core/{image/exception => exception/file}/FileExtensionException.java (88%) rename core/src/main/java/com/pocket/core/{image/exception => exception/file}/FileUploadException.java (88%) rename core/src/main/java/com/pocket/core/{image/exception => exception/file}/ImageErrorCode.java (95%) rename core/src/main/java/com/pocket/core/{image/exception => exception/file}/ImageException.java (92%) delete mode 100644 core/src/main/java/com/pocket/core/image/S3TestController.java delete mode 100644 core/src/main/java/com/pocket/core/image/service/AwsS3Service.java rename {core/src/main/java/com/pocket/core/image/dto => domain/src/main/java/com/pocket/domain/dto/file}/PresignedUrlRequest.java (89%) rename {core/src/main/java/com/pocket/core/image/dto => domain/src/main/java/com/pocket/domain/dto/file}/PresignedUrlResponse.java (93%) create mode 100644 domain/src/main/java/com/pocket/domain/port/file/FileDownloadPort.java create mode 100644 domain/src/main/java/com/pocket/domain/port/file/FileUploadPort.java create mode 100644 domain/src/main/java/com/pocket/domain/service/file/FileService.java rename domain/src/main/java/com/pocket/domain/usecase/{image => album}/AlbumRegisterUseCase.java (86%) create mode 100644 domain/src/main/java/com/pocket/domain/usecase/file/FileDownloadUseCase.java create mode 100644 domain/src/main/java/com/pocket/domain/usecase/file/FileUploadUseCase.java create mode 100644 outbound/src/main/java/com/pocket/outbound/adapter/file/adapter/FileDownloadAdapter.java rename core/src/main/java/com/pocket/core/image/service/FileService.java => outbound/src/main/java/com/pocket/outbound/adapter/file/adapter/FileUploadAdapter.java (72%) diff --git a/core/src/main/java/com/pocket/core/image/config/AwsS3Config.java b/core/src/main/java/com/pocket/core/config/AwsS3Config.java similarity index 96% rename from core/src/main/java/com/pocket/core/image/config/AwsS3Config.java rename to core/src/main/java/com/pocket/core/config/AwsS3Config.java index 40c4528..237b114 100644 --- a/core/src/main/java/com/pocket/core/image/config/AwsS3Config.java +++ b/core/src/main/java/com/pocket/core/config/AwsS3Config.java @@ -1,4 +1,4 @@ -package com.pocket.core.image.config; +package com.pocket.core.config; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.AWSStaticCredentialsProvider; diff --git a/core/src/main/java/com/pocket/core/image/exception/FileDeleteException.java b/core/src/main/java/com/pocket/core/exception/file/FileDeleteException.java similarity index 88% rename from core/src/main/java/com/pocket/core/image/exception/FileDeleteException.java rename to core/src/main/java/com/pocket/core/exception/file/FileDeleteException.java index b33a8de..b98ddee 100644 --- a/core/src/main/java/com/pocket/core/image/exception/FileDeleteException.java +++ b/core/src/main/java/com/pocket/core/exception/file/FileDeleteException.java @@ -1,4 +1,4 @@ -package com.pocket.core.image.exception; +package com.pocket.core.exception.file; import com.pocket.core.exception.common.BaseErrorCode; diff --git a/core/src/main/java/com/pocket/core/image/exception/FileExtensionException.java b/core/src/main/java/com/pocket/core/exception/file/FileExtensionException.java similarity index 88% rename from core/src/main/java/com/pocket/core/image/exception/FileExtensionException.java rename to core/src/main/java/com/pocket/core/exception/file/FileExtensionException.java index c4f52bd..e60ac99 100644 --- a/core/src/main/java/com/pocket/core/image/exception/FileExtensionException.java +++ b/core/src/main/java/com/pocket/core/exception/file/FileExtensionException.java @@ -1,4 +1,4 @@ -package com.pocket.core.image.exception; +package com.pocket.core.exception.file; import com.pocket.core.exception.common.BaseErrorCode; diff --git a/core/src/main/java/com/pocket/core/image/exception/FileUploadException.java b/core/src/main/java/com/pocket/core/exception/file/FileUploadException.java similarity index 88% rename from core/src/main/java/com/pocket/core/image/exception/FileUploadException.java rename to core/src/main/java/com/pocket/core/exception/file/FileUploadException.java index 7b87f8c..ee45b7c 100644 --- a/core/src/main/java/com/pocket/core/image/exception/FileUploadException.java +++ b/core/src/main/java/com/pocket/core/exception/file/FileUploadException.java @@ -1,4 +1,4 @@ -package com.pocket.core.image.exception; +package com.pocket.core.exception.file; import com.pocket.core.exception.common.BaseErrorCode; diff --git a/core/src/main/java/com/pocket/core/image/exception/ImageErrorCode.java b/core/src/main/java/com/pocket/core/exception/file/ImageErrorCode.java similarity index 95% rename from core/src/main/java/com/pocket/core/image/exception/ImageErrorCode.java rename to core/src/main/java/com/pocket/core/exception/file/ImageErrorCode.java index c028fb9..3c2b2d5 100644 --- a/core/src/main/java/com/pocket/core/image/exception/ImageErrorCode.java +++ b/core/src/main/java/com/pocket/core/exception/file/ImageErrorCode.java @@ -1,4 +1,4 @@ -package com.pocket.core.image.exception; +package com.pocket.core.exception.file; import com.pocket.core.exception.common.ApiResponse; import com.pocket.core.exception.common.BaseErrorCode; diff --git a/core/src/main/java/com/pocket/core/image/exception/ImageException.java b/core/src/main/java/com/pocket/core/exception/file/ImageException.java similarity index 92% rename from core/src/main/java/com/pocket/core/image/exception/ImageException.java rename to core/src/main/java/com/pocket/core/exception/file/ImageException.java index a73ad22..d58e093 100644 --- a/core/src/main/java/com/pocket/core/image/exception/ImageException.java +++ b/core/src/main/java/com/pocket/core/exception/file/ImageException.java @@ -1,4 +1,4 @@ -package com.pocket.core.image.exception; +package com.pocket.core.exception.file; import com.pocket.core.exception.common.BaseErrorCode; import lombok.Getter; diff --git a/core/src/main/java/com/pocket/core/image/S3TestController.java b/core/src/main/java/com/pocket/core/image/S3TestController.java deleted file mode 100644 index e469421..0000000 --- a/core/src/main/java/com/pocket/core/image/S3TestController.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.pocket.core.image; - -import com.pocket.core.exception.common.ApiResponse; -import com.pocket.core.image.service.AwsS3Service; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -@Slf4j -@RequiredArgsConstructor -@RestController -@RequestMapping("/api/v1/test") -public class S3TestController { - - private final AwsS3Service awsS3Service; - - @PostMapping(value = "/uploadFile", consumes = "multipart/form-data") - public ApiResponse uploadFile(@RequestPart(value = "file", required = false) MultipartFile file) { - return ApiResponse.onSuccess(awsS3Service.uploadFile(file)); - } -} diff --git a/core/src/main/java/com/pocket/core/image/service/AwsS3Service.java b/core/src/main/java/com/pocket/core/image/service/AwsS3Service.java deleted file mode 100644 index 2ef8a58..0000000 --- a/core/src/main/java/com/pocket/core/image/service/AwsS3Service.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.pocket.core.image.service; - -import com.amazonaws.AmazonServiceException; -import com.amazonaws.services.s3.AmazonS3; -import com.amazonaws.services.s3.model.ObjectMetadata; -import com.amazonaws.services.s3.model.PutObjectRequest; -import com.pocket.core.image.exception.FileDeleteException; -import com.pocket.core.image.exception.FileExtensionException; -import com.pocket.core.image.exception.FileUploadException; -import com.pocket.core.image.exception.ImageErrorCode; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Objects; -import java.util.UUID; - -@Service -@RequiredArgsConstructor -public class AwsS3Service { - - private final AmazonS3 amazonS3; - @Value("${cloud.aws.s3.bucket}") - private String bucketName; - - /** - * file upload - */ - public String uploadFile(MultipartFile multipartFile) { - if (Objects.isNull(multipartFile)) return null; - if (multipartFile.isEmpty()) return null; - - String fileName = createFileName(multipartFile.getOriginalFilename()); - - ObjectMetadata objectMetadata = new ObjectMetadata(); - objectMetadata.setContentType(multipartFile.getContentType()); - - try (InputStream inputStream = multipartFile.getInputStream()) { - amazonS3.putObject(new PutObjectRequest(bucketName, fileName, inputStream, objectMetadata)); - } catch (IOException e) { - throw new FileUploadException(ImageErrorCode.FILE_UPLOAD_FAIL); - } - - return amazonS3.getUrl(bucketName, fileName).toString(); - } - - - /** - * 파일 삭제 메서드 - */ - public void deleteFile(String fileUrl) { - if (fileUrl == null) return; - try { - amazonS3.deleteObject(bucketName, fileUrl); - } catch (AmazonServiceException e) { - throw new FileDeleteException(ImageErrorCode.FILE_DELETE_FAIL); - } - } - - /** - * 파일 업로드 시에 파일명을 난수화하는 메서드 - */ - private String createFileName(String fileName) { - return UUID.randomUUID().toString().concat(getFileExtension(fileName)); - } - - /** - * 파일 확장자 가져오는 메서드 - */ - private String getFileExtension(String fileName) { - try { - return fileName.substring(fileName.lastIndexOf(".")); - } catch (StringIndexOutOfBoundsException e) { - throw new FileExtensionException(ImageErrorCode.WRONG_FILE_FORMAT); - } - } - -} diff --git a/core/src/main/java/com/pocket/core/image/dto/PresignedUrlRequest.java b/domain/src/main/java/com/pocket/domain/dto/file/PresignedUrlRequest.java similarity index 89% rename from core/src/main/java/com/pocket/core/image/dto/PresignedUrlRequest.java rename to domain/src/main/java/com/pocket/domain/dto/file/PresignedUrlRequest.java index edacda7..bc924b4 100644 --- a/core/src/main/java/com/pocket/core/image/dto/PresignedUrlRequest.java +++ b/domain/src/main/java/com/pocket/domain/dto/file/PresignedUrlRequest.java @@ -1,4 +1,4 @@ -package com.pocket.core.image.dto; +package com.pocket.domain.dto.file; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; diff --git a/core/src/main/java/com/pocket/core/image/dto/PresignedUrlResponse.java b/domain/src/main/java/com/pocket/domain/dto/file/PresignedUrlResponse.java similarity index 93% rename from core/src/main/java/com/pocket/core/image/dto/PresignedUrlResponse.java rename to domain/src/main/java/com/pocket/domain/dto/file/PresignedUrlResponse.java index 8979739..ba165cb 100644 --- a/core/src/main/java/com/pocket/core/image/dto/PresignedUrlResponse.java +++ b/domain/src/main/java/com/pocket/domain/dto/file/PresignedUrlResponse.java @@ -1,4 +1,4 @@ -package com.pocket.core.image.dto; +package com.pocket.domain.dto.file; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; diff --git a/domain/src/main/java/com/pocket/domain/dto/review/ReviewGetResponseDto.java b/domain/src/main/java/com/pocket/domain/dto/review/ReviewGetResponseDto.java index dad6032..c75ef52 100644 --- a/domain/src/main/java/com/pocket/domain/dto/review/ReviewGetResponseDto.java +++ b/domain/src/main/java/com/pocket/domain/dto/review/ReviewGetResponseDto.java @@ -6,4 +6,5 @@ public record ReviewGetResponseDto( int reviewCount, List reviews ) { + } diff --git a/domain/src/main/java/com/pocket/domain/port/file/FileDownloadPort.java b/domain/src/main/java/com/pocket/domain/port/file/FileDownloadPort.java new file mode 100644 index 0000000..3f5d104 --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/port/file/FileDownloadPort.java @@ -0,0 +1,7 @@ +package com.pocket.domain.port.file; + +public interface FileDownloadPort { + + String getDownloadPresignedUrl(String filePath); + +} diff --git a/domain/src/main/java/com/pocket/domain/port/file/FileUploadPort.java b/domain/src/main/java/com/pocket/domain/port/file/FileUploadPort.java new file mode 100644 index 0000000..ebd2260 --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/port/file/FileUploadPort.java @@ -0,0 +1,9 @@ +package com.pocket.domain.port.file; + +import com.pocket.domain.dto.file.PresignedUrlResponse; + +public interface FileUploadPort { + + PresignedUrlResponse getUploadPresignedUrl(String prefix, String fileName); + +} diff --git a/domain/src/main/java/com/pocket/domain/service/album/AlbumService.java b/domain/src/main/java/com/pocket/domain/service/album/AlbumService.java index f83a5f7..6e59407 100644 --- a/domain/src/main/java/com/pocket/domain/service/album/AlbumService.java +++ b/domain/src/main/java/com/pocket/domain/service/album/AlbumService.java @@ -4,7 +4,7 @@ import com.pocket.domain.dto.album.AlbumRegisterRequestDto; import com.pocket.domain.dto.album.AlbumRegisterResponseDto; import com.pocket.domain.port.album.AlbumRegisterPort; -import com.pocket.domain.usecase.image.AlbumRegisterUseCase; +import com.pocket.domain.usecase.album.AlbumRegisterUseCase; import lombok.RequiredArgsConstructor; @DomainService diff --git a/domain/src/main/java/com/pocket/domain/service/file/FileService.java b/domain/src/main/java/com/pocket/domain/service/file/FileService.java new file mode 100644 index 0000000..f19959e --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/service/file/FileService.java @@ -0,0 +1,22 @@ +package com.pocket.domain.service.file; + + +import com.pocket.domain.dto.file.PresignedUrlResponse; +import com.pocket.domain.port.file.FileDownloadPort; +import com.pocket.domain.port.file.FileUploadPort; +import com.pocket.domain.usecase.file.FileDownloadUseCase; +import com.pocket.domain.usecase.file.FileUploadUseCase; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class FileService implements FileUploadUseCase { + + private final FileUploadPort fileUploadPort; + + @Override + public PresignedUrlResponse getUploadPresignedUrl(String prefix, String fileName) { + return fileUploadPort.getUploadPresignedUrl(prefix, fileName); + } +} diff --git a/domain/src/main/java/com/pocket/domain/service/review/ReviewService.java b/domain/src/main/java/com/pocket/domain/service/review/ReviewService.java index a6ee621..1f4c27c 100644 --- a/domain/src/main/java/com/pocket/domain/service/review/ReviewService.java +++ b/domain/src/main/java/com/pocket/domain/service/review/ReviewService.java @@ -3,12 +3,14 @@ import com.pocket.core.aop.annotation.DomainService; import com.pocket.domain.dto.review.*; +import com.pocket.domain.port.file.FileDownloadPort; import com.pocket.domain.port.review.*; import com.pocket.domain.usecase.review.*; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import java.util.List; +import java.util.stream.Collectors; @DomainService @RequiredArgsConstructor @@ -25,6 +27,7 @@ public class ReviewService implements ReviewRegisterUseCase, ReviewGet6ImagesUse private final ReviewGetBoothFeaturePort reviewGetBoothFeaturePort; private final ReviewGetPhotoFeaturePort reviewGetPhotoFeaturePort; private final ReviewGetAllPort reviewGetAllPort; + private final FileDownloadPort fileDownloadPort; @Override public ReviewRegisterResponseDto registerReviewResponse(ReviewRegisterRequestDto reviewRegisterRequestDto, String name) { @@ -33,17 +36,44 @@ public ReviewRegisterResponseDto registerReviewResponse(ReviewRegisterRequestDto @Override public ReviewGet6ImagesResponseDto get6Images(Long photoboothId) { - return reviewGet6ImagesPort.get6Images(photoboothId); + ReviewGet6ImagesResponseDto response = reviewGet6ImagesPort.get6Images(photoboothId); + + List presignedUrls = response.filePaths().stream() + .map(fileDownloadPort::getDownloadPresignedUrl) + .collect(Collectors.toList()); + + return new ReviewGet6ImagesResponseDto(presignedUrls, response.totalImageCount()); } @Override public ReviewGetResponseDto getRecentReview(Long photoboothId) { - return reviewGetRecentPort.getRecentReview(photoboothId); + ReviewGetResponseDto response = reviewGetRecentPort.getRecentReview(photoboothId); + + List reviewPreviewsWithPresignedUrls = response.reviews().stream().map(review -> { + String presignedUrl = review.imageUrl().isEmpty() ? "" : fileDownloadPort.getDownloadPresignedUrl(review.imageUrl()); + return new ReviewPreviewDto( + review.photoboothId(), + review.name(), + review.year(), + review.month(), + review.date(), + review.contents(), + review.features(), + presignedUrl, + review.imageCount() + ); + }).collect(Collectors.toList()); + + return new ReviewGetResponseDto(response.reviewCount(), reviewPreviewsWithPresignedUrls); } @Override public List getAllImages(Long photoboothId, Pageable pageable) { - return reviewGetAllImagesPort.getAllImages(photoboothId, pageable); + List rawImagePaths = reviewGetAllImagesPort.getAllImages(photoboothId, pageable); + + return rawImagePaths.stream() + .map(fileDownloadPort::getDownloadPresignedUrl) + .collect(Collectors.toList()); } @Override @@ -68,6 +98,23 @@ public List getPhotoFeatures() { @Override public ReviewGetResponseDto getAllReviews(Long photoboothId, Pageable pageable) { - return reviewGetAllPort.getAllReviews(photoboothId, pageable); + ReviewGetResponseDto response = reviewGetAllPort.getAllReviews(photoboothId, pageable); + + List reviewPreviewsWithPresignedUrls = response.reviews().stream().map(review -> { + String presignedUrl = review.imageUrl().isEmpty() ? "" : fileDownloadPort.getDownloadPresignedUrl(review.imageUrl()); + return new ReviewPreviewDto( + review.photoboothId(), + review.name(), + review.year(), + review.month(), + review.date(), + review.contents(), + review.features(), + presignedUrl, + review.imageCount() + ); + }).collect(Collectors.toList()); + + return new ReviewGetResponseDto(response.reviewCount(), reviewPreviewsWithPresignedUrls); } } diff --git a/domain/src/main/java/com/pocket/domain/usecase/image/AlbumRegisterUseCase.java b/domain/src/main/java/com/pocket/domain/usecase/album/AlbumRegisterUseCase.java similarity index 86% rename from domain/src/main/java/com/pocket/domain/usecase/image/AlbumRegisterUseCase.java rename to domain/src/main/java/com/pocket/domain/usecase/album/AlbumRegisterUseCase.java index da1f497..acb746a 100644 --- a/domain/src/main/java/com/pocket/domain/usecase/image/AlbumRegisterUseCase.java +++ b/domain/src/main/java/com/pocket/domain/usecase/album/AlbumRegisterUseCase.java @@ -1,4 +1,4 @@ -package com.pocket.domain.usecase.image; +package com.pocket.domain.usecase.album; import com.pocket.domain.dto.album.AlbumRegisterRequestDto; import com.pocket.domain.dto.album.AlbumRegisterResponseDto; diff --git a/domain/src/main/java/com/pocket/domain/usecase/file/FileDownloadUseCase.java b/domain/src/main/java/com/pocket/domain/usecase/file/FileDownloadUseCase.java new file mode 100644 index 0000000..35d0427 --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/usecase/file/FileDownloadUseCase.java @@ -0,0 +1,7 @@ +package com.pocket.domain.usecase.file; + +public interface FileDownloadUseCase { + + String getDownloadPresignedUrl(String filePath); + +} diff --git a/domain/src/main/java/com/pocket/domain/usecase/file/FileUploadUseCase.java b/domain/src/main/java/com/pocket/domain/usecase/file/FileUploadUseCase.java new file mode 100644 index 0000000..52b283e --- /dev/null +++ b/domain/src/main/java/com/pocket/domain/usecase/file/FileUploadUseCase.java @@ -0,0 +1,9 @@ +package com.pocket.domain.usecase.file; + +import com.pocket.domain.dto.file.PresignedUrlResponse; + +public interface FileUploadUseCase { + + PresignedUrlResponse getUploadPresignedUrl(String prefix, String fileName); + +} diff --git a/inbounds/src/main/java/com/pocket/inbounds/album/presentation/AlbumController.java b/inbounds/src/main/java/com/pocket/inbounds/album/presentation/AlbumController.java index b286d3e..46cd288 100644 --- a/inbounds/src/main/java/com/pocket/inbounds/album/presentation/AlbumController.java +++ b/inbounds/src/main/java/com/pocket/inbounds/album/presentation/AlbumController.java @@ -4,7 +4,7 @@ import com.pocket.domain.dto.album.AlbumRegisterRequestDto; import com.pocket.domain.dto.album.AlbumRegisterResponseDto; import com.pocket.domain.dto.user.UserInfoDTO; -import com.pocket.domain.usecase.image.AlbumRegisterUseCase; +import com.pocket.domain.usecase.album.AlbumRegisterUseCase; import lombok.RequiredArgsConstructor; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.PostMapping; diff --git a/inbounds/src/main/java/com/pocket/inbounds/file/presentation/FileController.java b/inbounds/src/main/java/com/pocket/inbounds/file/presentation/FileController.java index 0597144..fb9a742 100644 --- a/inbounds/src/main/java/com/pocket/inbounds/file/presentation/FileController.java +++ b/inbounds/src/main/java/com/pocket/inbounds/file/presentation/FileController.java @@ -1,9 +1,9 @@ package com.pocket.inbounds.file.presentation; import com.pocket.core.exception.common.ApplicationResponse; -import com.pocket.core.image.dto.PresignedUrlRequest; -import com.pocket.core.image.dto.PresignedUrlResponse; -import com.pocket.core.image.service.FileService; +import com.pocket.domain.dto.file.PresignedUrlRequest; +import com.pocket.domain.dto.file.PresignedUrlResponse; +import com.pocket.domain.service.file.FileService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; diff --git a/inbounds/src/main/java/com/pocket/inbounds/file/presentation/FileControllerDocs.java b/inbounds/src/main/java/com/pocket/inbounds/file/presentation/FileControllerDocs.java index 88e7221..03648dc 100644 --- a/inbounds/src/main/java/com/pocket/inbounds/file/presentation/FileControllerDocs.java +++ b/inbounds/src/main/java/com/pocket/inbounds/file/presentation/FileControllerDocs.java @@ -2,8 +2,8 @@ import com.nimbusds.oauth2.sdk.ErrorResponse; import com.pocket.core.exception.common.ApplicationResponse; -import com.pocket.core.image.dto.PresignedUrlRequest; -import com.pocket.core.image.dto.PresignedUrlResponse; +import com.pocket.domain.dto.file.PresignedUrlRequest; +import com.pocket.domain.dto.file.PresignedUrlResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; diff --git a/inbounds/src/main/java/com/pocket/inbounds/user/response/UserResponse.java b/inbounds/src/main/java/com/pocket/inbounds/user/response/UserResponse.java index 05ca083..0d3fa34 100644 --- a/inbounds/src/main/java/com/pocket/inbounds/user/response/UserResponse.java +++ b/inbounds/src/main/java/com/pocket/inbounds/user/response/UserResponse.java @@ -1,7 +1,5 @@ package com.pocket.inbounds.user.response; -import com.pocket.domain.dto.user.UserInfoDTO; - public record UserResponse( String name, String email, diff --git a/outbound/src/main/java/com/pocket/outbound/adapter/file/adapter/FileDownloadAdapter.java b/outbound/src/main/java/com/pocket/outbound/adapter/file/adapter/FileDownloadAdapter.java new file mode 100644 index 0000000..1aa870a --- /dev/null +++ b/outbound/src/main/java/com/pocket/outbound/adapter/file/adapter/FileDownloadAdapter.java @@ -0,0 +1,52 @@ +package com.pocket.outbound.adapter.file.adapter; + +import com.amazonaws.HttpMethod; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest; +import com.pocket.core.aop.annotation.AdapterService; +import com.pocket.domain.port.file.FileDownloadPort; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; + +import java.net.URL; +import java.util.Date; + +@AdapterService +@RequiredArgsConstructor +public class FileDownloadAdapter implements FileDownloadPort { + + @Value("${cloud.aws.s3.bucket}") + private String bucket; + + @Value("${cloud.aws.s3.expTime}") + private Long expTime; + + private final AmazonS3 amazonS3; + + @Override + public String getDownloadPresignedUrl(String filePath) { + if (filePath != null && filePath.startsWith("/images/")) { + GeneratePresignedUrlRequest generatePresignedUrlRequest = getGeneratePresignedUrlRequest(bucket, filePath, HttpMethod.GET); + URL url = amazonS3.generatePresignedUrl(generatePresignedUrlRequest); + return url.toString(); + } + + return filePath; + } + + private GeneratePresignedUrlRequest getGeneratePresignedUrlRequest(String bucket, String fileName, HttpMethod method) { + + return new GeneratePresignedUrlRequest(bucket, fileName) + .withMethod(method) + .withExpiration(getPresignedUrlExpiration()); + } + + private Date getPresignedUrlExpiration() { + Date expiration = new Date(); + long expTimeMillis = expiration.getTime(); + expTimeMillis += expTime; + expiration.setTime(expTimeMillis); + + return expiration; + } +} diff --git a/core/src/main/java/com/pocket/core/image/service/FileService.java b/outbound/src/main/java/com/pocket/outbound/adapter/file/adapter/FileUploadAdapter.java similarity index 72% rename from core/src/main/java/com/pocket/core/image/service/FileService.java rename to outbound/src/main/java/com/pocket/outbound/adapter/file/adapter/FileUploadAdapter.java index 194d784..fe23616 100644 --- a/core/src/main/java/com/pocket/core/image/service/FileService.java +++ b/outbound/src/main/java/com/pocket/outbound/adapter/file/adapter/FileUploadAdapter.java @@ -1,21 +1,23 @@ -package com.pocket.core.image.service; +package com.pocket.outbound.adapter.file.adapter; + import com.amazonaws.HttpMethod; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest; -import com.pocket.core.image.dto.PresignedUrlResponse; +import com.pocket.core.aop.annotation.AdapterService; +import com.pocket.domain.dto.file.PresignedUrlResponse; +import com.pocket.domain.port.file.FileUploadPort; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; import java.net.URL; import java.text.SimpleDateFormat; import java.util.Date; import java.util.UUID; -@Service +@AdapterService @RequiredArgsConstructor -public class FileService { +public class FileUploadAdapter implements FileUploadPort { @Value("${cloud.aws.s3.bucket}") private String bucket; @@ -23,27 +25,17 @@ public class FileService { @Value("${cloud.aws.s3.expTime}") private Long expTime; - private final AmazonS3 amazonS3; - public PresignedUrlResponse getUploadPresignedUrl(String prefix, String originalFileName) { - String filePath = createPath(prefix, originalFileName); + @Override + public PresignedUrlResponse getUploadPresignedUrl(String prefix, String fileName) { + String filePath = createPath(prefix, fileName); GeneratePresignedUrlRequest generatePresignedUrlRequest = getGeneratePresignedUrlRequest(bucket, filePath, HttpMethod.PUT); URL url = amazonS3.generatePresignedUrl(generatePresignedUrlRequest); return new PresignedUrlResponse(url.toString(), filePath); } - public String getDownloadPresignedUrl(String filePath) { - if (filePath != null && filePath.startsWith("images/")) { - GeneratePresignedUrlRequest generatePresignedUrlRequest = getGeneratePresignedUrlRequest(bucket, filePath, HttpMethod.GET); - URL url = amazonS3.generatePresignedUrl(generatePresignedUrlRequest); - return url.toString(); - } - - return filePath; - } - private GeneratePresignedUrlRequest getGeneratePresignedUrlRequest(String bucket, String fileName, HttpMethod method) { return new GeneratePresignedUrlRequest(bucket, fileName) @@ -60,13 +52,14 @@ private Date getPresignedUrlExpiration() { return expiration; } - private String createFileId() { - return UUID.randomUUID().toString(); - } - private String createPath(String prefix, String fileName) { String fileId = createFileId(); String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); return String.format("%s/%s-%s-%s", prefix, timestamp, fileId, fileName); } + + private String createFileId() { + return UUID.randomUUID().toString(); + } + } diff --git a/outbound/src/main/java/com/pocket/outbound/config/SecurityConfig.java b/outbound/src/main/java/com/pocket/outbound/config/SecurityConfig.java index f96791c..314745a 100644 --- a/outbound/src/main/java/com/pocket/outbound/config/SecurityConfig.java +++ b/outbound/src/main/java/com/pocket/outbound/config/SecurityConfig.java @@ -69,6 +69,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .authenticationEntryPoint(jwtAuthenticationEntryPoint) .accessDeniedHandler(jwtAccessDeniedHandler)); + return http.build(); }