-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #59 from taco-official/KL-119/상품사진-s-3-등록
feat(KL-119): add s3 image
- Loading branch information
Showing
60 changed files
with
1,070 additions
and
208 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
src/main/java/taco/klkl/domain/image/controller/ImageController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package taco.klkl.domain.image.controller; | ||
|
||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import jakarta.validation.Valid; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import taco.klkl.domain.image.dto.request.ImageUploadRequest; | ||
import taco.klkl.domain.image.dto.response.PresignedUrlResponse; | ||
import taco.klkl.domain.image.service.ImageService; | ||
|
||
@Slf4j | ||
@RestController | ||
@Tag(name = "0. 이미지", description = "이미지 관련 API") | ||
@RequiredArgsConstructor | ||
public class ImageController { | ||
|
||
private final ImageService imageService; | ||
|
||
@Operation( | ||
summary = "유저 이미지 업로드 Presigned URL 생성", | ||
description = "유저 이미지 업로드를 위한 Presigned URL를 생성합니다." | ||
) | ||
@PostMapping("/v1/users/me/upload-url") | ||
public PresignedUrlResponse createUserImageUploadUrl( | ||
@Valid @RequestBody final ImageUploadRequest request | ||
) { | ||
return imageService.createUserImageUploadUrl(request); | ||
} | ||
|
||
@Operation( | ||
summary = "유저 이미지 업로드 완료 처리", | ||
description = "유저 이미지 업로드를 완료 처리합니다." | ||
) | ||
@PostMapping("/v1/users/me/upload-complete") | ||
public ResponseEntity<Void> uploadCompleteUserImage() { | ||
imageService.uploadCompleteUserImage(); | ||
return ResponseEntity.ok().build(); | ||
} | ||
|
||
@Operation( | ||
summary = "상품 이미지 업로드 Presigned URL 생성", | ||
description = "상품 이미지 업로드를 위한 Presigned URL를 생성합니다." | ||
) | ||
@PostMapping("/v1/products/{productId}/upload-url") | ||
public PresignedUrlResponse createProductImageUploadUrl( | ||
@PathVariable final Long productId, | ||
@Valid @RequestBody final ImageUploadRequest request | ||
) { | ||
return imageService.createProductImageUploadUrl(productId, request); | ||
} | ||
|
||
@Operation( | ||
summary = "상품 이미지 업로드 완료 처리", | ||
description = "상품 이미지 업로드를 완료 처리합니다." | ||
) | ||
@PostMapping("/v1/products/{productId}/upload-complete") | ||
public ResponseEntity<Void> uploadCompleteProductImage( | ||
@PathVariable final Long productId | ||
) { | ||
imageService.uploadCompleteProductImage(productId); | ||
return ResponseEntity.ok().build(); | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/main/java/taco/klkl/domain/image/dao/ImageRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package taco.klkl.domain.image.dao; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
import taco.klkl.domain.image.domain.Image; | ||
import taco.klkl.domain.image.domain.ImageType; | ||
|
||
public interface ImageRepository extends JpaRepository<Image, Long> { | ||
Optional<Image> findByImageTypeAndTargetId(final ImageType imageType, final Long targetId); | ||
|
||
List<Image> findAllByImageTypeAndTargetId(final ImageType imageType, final Long targetId); | ||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/taco/klkl/domain/image/domain/FileExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package taco.klkl.domain.image.domain; | ||
|
||
import java.util.Arrays; | ||
|
||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
import taco.klkl.domain.image.exception.FileExtensionNotFoundException; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
public enum FileExtension { | ||
JPG("jpeg"), | ||
JPEG("jpeg"), | ||
PNG("png"), | ||
WEBP("webp"), | ||
; | ||
|
||
private final String value; | ||
|
||
public static FileExtension from(final String fileExtension) throws FileExtensionNotFoundException { | ||
return Arrays.stream(FileExtension.values()) | ||
.filter(extension -> extension.getValue().equals(fileExtension)) | ||
.findFirst() | ||
.orElseThrow(FileExtensionNotFoundException::new); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package taco.klkl.domain.image.domain; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.EnumType; | ||
import jakarta.persistence.Enumerated; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import lombok.AccessLevel; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@Entity(name = "image") | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class Image { | ||
|
||
@Id | ||
@Column(name = "image_id", | ||
nullable = false | ||
) | ||
@GeneratedValue(strategy = GenerationType.AUTO) | ||
private Long id; | ||
|
||
@Enumerated(EnumType.STRING) | ||
@Column( | ||
name = "image_type", | ||
nullable = false | ||
) | ||
private ImageType imageType; | ||
|
||
@Column( | ||
name = "target_id", | ||
nullable = false | ||
) | ||
private Long targetId; | ||
|
||
@Column( | ||
name = "image_key", | ||
nullable = false | ||
) | ||
private String imageKey; | ||
|
||
@Enumerated(EnumType.STRING) | ||
@Column( | ||
name = "file_extension", | ||
nullable = false | ||
) | ||
private FileExtension fileExtension; | ||
|
||
@Enumerated(EnumType.STRING) | ||
@Column( | ||
name = "upload_state", | ||
nullable = false | ||
) | ||
private UploadState uploadState; | ||
|
||
@Column( | ||
name = "created_at", | ||
nullable = false, | ||
updatable = false | ||
) | ||
private LocalDateTime createdAt; | ||
|
||
private Image( | ||
final ImageType imageType, | ||
final Long targetId, | ||
final String imageKey, | ||
final FileExtension fileExtension | ||
) { | ||
this.imageType = imageType; | ||
this.targetId = targetId; | ||
this.imageKey = imageKey; | ||
this.fileExtension = fileExtension; | ||
this.uploadState = UploadState.PENDING; | ||
this.createdAt = LocalDateTime.now(); | ||
} | ||
|
||
public static Image of( | ||
final ImageType imageType, | ||
final Long targetId, | ||
final String imageUuid, | ||
final FileExtension fileExtension | ||
) { | ||
return new Image(imageType, targetId, imageUuid, fileExtension); | ||
} | ||
|
||
public void uploadComplete() { | ||
this.uploadState = UploadState.COMPLETE; | ||
} | ||
|
||
public void markAsOutdated() { | ||
this.uploadState = UploadState.OUTDATED; | ||
} | ||
|
||
public String createFileName() { | ||
return imageType.getValue() + "/" | ||
+ targetId + "/" | ||
+ imageKey + "." | ||
+ fileExtension.getValue(); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/main/java/taco/klkl/domain/image/domain/ImageType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package taco.klkl.domain.image.domain; | ||
|
||
import java.util.Arrays; | ||
|
||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
import taco.klkl.domain.image.exception.ImageTypeNotFoundException; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
public enum ImageType { | ||
USER_IMAGE("user_image"), | ||
PRODUCT_IMAGE("product_image"), | ||
; | ||
|
||
private final String value; | ||
|
||
public static ImageType from(final String value) throws ImageTypeNotFoundException { | ||
return Arrays.stream(ImageType.values()) | ||
.filter(type -> type.getValue().equals(value)) | ||
.findFirst() | ||
.orElseThrow(ImageTypeNotFoundException::new); | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
src/main/java/taco/klkl/domain/image/domain/UploadState.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package taco.klkl.domain.image.domain; | ||
|
||
import java.util.Arrays; | ||
|
||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
import taco.klkl.domain.image.exception.UploadStateNotFoundException; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
public enum UploadState { | ||
PENDING("대기중"), | ||
COMPLETE("완료"), | ||
OUTDATED("폐기예정"), | ||
; | ||
|
||
private final String value; | ||
|
||
public static UploadState from(final String value) throws UploadStateNotFoundException { | ||
return Arrays.stream(UploadState.values()) | ||
.filter(state -> state.getValue().equals(value)) | ||
.findFirst() | ||
.orElseThrow(UploadStateNotFoundException::new); | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/taco/klkl/domain/image/dto/request/ImageUploadRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package taco.klkl.domain.image.dto.request; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
import taco.klkl.global.common.constants.ImageValidationMessages; | ||
|
||
public record ImageUploadRequest( | ||
@NotBlank(message = ImageValidationMessages.FILE_EXTENSION_NOT_BLANK) | ||
String fileExtension | ||
) { | ||
} |
9 changes: 9 additions & 0 deletions
9
src/main/java/taco/klkl/domain/image/dto/response/PresignedUrlResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package taco.klkl.domain.image.dto.response; | ||
|
||
public record PresignedUrlResponse( | ||
String presignedUrl | ||
) { | ||
public static PresignedUrlResponse from(final String presignedUrl) { | ||
return new PresignedUrlResponse(presignedUrl); | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/taco/klkl/domain/image/exception/FileExtensionNotFoundException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package taco.klkl.domain.image.exception; | ||
|
||
import taco.klkl.global.error.exception.CustomException; | ||
import taco.klkl.global.error.exception.ErrorCode; | ||
|
||
public class FileExtensionNotFoundException extends CustomException { | ||
public FileExtensionNotFoundException() { | ||
super(ErrorCode.FILE_EXTENSION_NOT_FOUND); | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/taco/klkl/domain/image/exception/ImageNotFoundException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package taco.klkl.domain.image.exception; | ||
|
||
import taco.klkl.global.error.exception.CustomException; | ||
import taco.klkl.global.error.exception.ErrorCode; | ||
|
||
public class ImageNotFoundException extends CustomException { | ||
public ImageNotFoundException() { | ||
super(ErrorCode.IMAGE_NOT_FOUND); | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/taco/klkl/domain/image/exception/ImageTypeNotFoundException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package taco.klkl.domain.image.exception; | ||
|
||
import taco.klkl.global.error.exception.CustomException; | ||
import taco.klkl.global.error.exception.ErrorCode; | ||
|
||
public class ImageTypeNotFoundException extends CustomException { | ||
public ImageTypeNotFoundException() { | ||
super(ErrorCode.IMAGE_TYPE_NOT_FOUND); | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/taco/klkl/domain/image/exception/ImageUploadNotCompleteException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package taco.klkl.domain.image.exception; | ||
|
||
import taco.klkl.global.error.exception.CustomException; | ||
import taco.klkl.global.error.exception.ErrorCode; | ||
|
||
public class ImageUploadNotCompleteException extends CustomException { | ||
public ImageUploadNotCompleteException() { | ||
super(ErrorCode.IMAGE_UPLOAD_NOT_COMPLETE); | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/taco/klkl/domain/image/exception/ImageUrlInvalidException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package taco.klkl.domain.image.exception; | ||
|
||
import taco.klkl.global.error.exception.CustomException; | ||
import taco.klkl.global.error.exception.ErrorCode; | ||
|
||
public class ImageUrlInvalidException extends CustomException { | ||
public ImageUrlInvalidException() { | ||
super(ErrorCode.IMAGE_URL_INVALID); | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/taco/klkl/domain/image/exception/UploadStateNotFoundException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package taco.klkl.domain.image.exception; | ||
|
||
import taco.klkl.global.error.exception.CustomException; | ||
import taco.klkl.global.error.exception.ErrorCode; | ||
|
||
public class UploadStateNotFoundException extends CustomException { | ||
public UploadStateNotFoundException() { | ||
super(ErrorCode.UPLOAD_STATE_NOT_FOUND); | ||
} | ||
} |
Oops, something went wrong.