-
Notifications
You must be signed in to change notification settings - Fork 3
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 #27 from mash-up-kr/yaeoni/presigned-url-image
feat; 이미지 업로드 정보 조회 API 작성해요 (presigned url 활용)
- Loading branch information
Showing
12 changed files
with
195 additions
and
5 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"local": { | ||
"host": "localhost:8080" | ||
} | ||
} |
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,2 @@ | ||
### 이미지 업로드 url 조회하기 | ||
GET {{host}}/image-upload-url?contentType=PNG |
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,48 @@ | ||
package com.mashup.dojo | ||
|
||
import com.mashup.dojo.common.DojoApiResponse | ||
import com.mashup.dojo.external.aws.ImageContentType | ||
import com.mashup.dojo.external.aws.ImageUploadUrlProvider | ||
import com.mashup.dojo.usecase.ImageUseCase | ||
import io.github.oshai.kotlinlogging.KotlinLogging | ||
import io.swagger.v3.oas.annotations.Operation | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse | ||
import io.swagger.v3.oas.annotations.tags.Tag | ||
import org.springframework.web.bind.annotation.GetMapping | ||
import org.springframework.web.bind.annotation.RestController | ||
|
||
private val logger = KotlinLogging.logger { } | ||
|
||
@Tag(name = "Image", description = "이미지 API") | ||
@RestController | ||
class ImageController( | ||
private val imageUploadUrlProvider: ImageUploadUrlProvider, | ||
private val imageUseCase: ImageUseCase, | ||
) { | ||
@GetMapping("image-upload-url") | ||
@Operation( | ||
summary = "단일 이미지 업로드 정보 조회 (URL, UUID)", | ||
description = "이미지 파일을 업로드하기 위한 presigned url 과 uuid 를 반환합니다. PUT API를 통해 호출해주세요", | ||
responses = [ | ||
ApiResponse(responseCode = "200", description = "업로드된 이미지 id") | ||
] | ||
) | ||
fun uploadInfo(contentType: ImageContentType): DojoApiResponse<ImageUploadUrlResponse> { | ||
logger.info { "read image upload info, contentType: ${contentType.value}" } | ||
|
||
val uploadUrlInfo = imageUploadUrlProvider.createUploadUrl(contentType) | ||
imageUseCase.uploadImage(uploadUrlInfo.uuid, uploadUrlInfo.imageUrl) | ||
|
||
return DojoApiResponse.success( | ||
ImageUploadUrlResponse( | ||
uuid = uploadUrlInfo.uuid, | ||
uploadUrl = uploadUrlInfo.uploadUrl.toString() | ||
) | ||
) | ||
} | ||
|
||
data class ImageUploadUrlResponse( | ||
val uuid: String, | ||
val uploadUrl: String, | ||
) | ||
} |
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
33 changes: 33 additions & 0 deletions
33
common/src/main/kotlin/com/mashup/dojo/external/ExternalConfiguration.kt
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,33 @@ | ||
package com.mashup.dojo.external | ||
|
||
import com.amazonaws.auth.AWSStaticCredentialsProvider | ||
import com.amazonaws.auth.BasicAWSCredentials | ||
import com.amazonaws.regions.Regions | ||
import com.amazonaws.services.s3.AmazonS3Client | ||
import com.amazonaws.services.s3.AmazonS3ClientBuilder | ||
import com.mashup.dojo.external.aws.ImageUploadUrlProvider | ||
import com.mashup.dojo.external.aws.S3ImageUploadUrlProvider | ||
import org.springframework.context.annotation.Bean | ||
import org.springframework.context.annotation.Configuration | ||
import org.springframework.core.env.Environment | ||
|
||
@Configuration | ||
class ExternalConfiguration { | ||
@Bean | ||
fun s3Client(environment: Environment): AmazonS3Client { | ||
val accessKey = environment.getProperty("aws.access-key") | ||
val secretKey = environment.getProperty("aws.secret-key") | ||
val credential = BasicAWSCredentials(accessKey, secretKey) | ||
return AmazonS3ClientBuilder.standard() | ||
.withCredentials( | ||
AWSStaticCredentialsProvider(credential) | ||
) | ||
.withRegion(Regions.AP_NORTHEAST_2) | ||
.build() as AmazonS3Client | ||
} | ||
|
||
@Bean | ||
fun imageUploader(s3Client: AmazonS3Client): ImageUploadUrlProvider { | ||
return S3ImageUploadUrlProvider(s3Client) | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
common/src/main/kotlin/com/mashup/dojo/external/aws/ImageUploadUrlProvider.kt
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,50 @@ | ||
package com.mashup.dojo.external.aws | ||
|
||
import com.amazonaws.HttpMethod | ||
import com.amazonaws.services.s3.AmazonS3Client | ||
import java.net.URL | ||
import java.time.Duration | ||
import java.util.Date | ||
import java.util.UUID | ||
|
||
interface ImageUploadUrlProvider { | ||
fun createUploadUrl(contentType: ImageContentType): ImageUploadUrl | ||
} | ||
|
||
data class ImageUploadUrl( | ||
val uuid: String, | ||
val imageUrl: String, | ||
val uploadUrl: URL, | ||
) | ||
|
||
enum class ImageContentType(val value: String) { | ||
PNG("png"), | ||
JPEG("jpeg"), | ||
} | ||
|
||
class S3ImageUploadUrlProvider( | ||
private val client: AmazonS3Client, | ||
) : ImageUploadUrlProvider { | ||
override fun createUploadUrl(contentType: ImageContentType): ImageUploadUrl { | ||
val uuid = UUID.randomUUID().toString() | ||
val path = "images/$uuid.${contentType.value}" | ||
|
||
val uploadUrl = | ||
client.generatePresignedUrl( | ||
IMAGE_BUCKET_NAME, | ||
path, | ||
Date(System.currentTimeMillis() + Duration.ofMinutes(5).toMillis()), | ||
HttpMethod.PUT | ||
) | ||
|
||
return ImageUploadUrl( | ||
uuid = uuid, | ||
imageUrl = "https://$IMAGE_BUCKET_NAME.s3.ap-northeast-2.amazonaws.com/$path", | ||
uploadUrl = uploadUrl | ||
) | ||
} | ||
|
||
companion object { | ||
private const val IMAGE_BUCKET_NAME = "dojo-backend-source-bundle" | ||
} | ||
} |
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,3 @@ | ||
aws: | ||
access-key: ${AWS_ACCESS_KEY} | ||
secret-key: ${AWS_SECRET_KEY} |
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 com.mashup.dojo | ||
|
||
import com.mashup.dojo.base.BaseEntity | ||
import jakarta.persistence.Entity | ||
import org.springframework.data.jpa.repository.JpaRepository | ||
import org.springframework.stereotype.Repository | ||
|
||
@Repository | ||
interface ImageRepository : JpaRepository<ImageEntity, Long> | ||
|
||
@Entity | ||
class ImageEntity( | ||
val uuid: String, | ||
val url: String, | ||
) : BaseEntity() |
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
25 changes: 23 additions & 2 deletions
25
service/src/main/kotlin/com/mashup/dojo/service/ImageService.kt
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 |
---|---|---|
@@ -1,16 +1,37 @@ | ||
package com.mashup.dojo.service | ||
|
||
import com.mashup.dojo.ImageEntity | ||
import com.mashup.dojo.ImageRepository | ||
import com.mashup.dojo.domain.Image | ||
import com.mashup.dojo.domain.ImageId | ||
import org.springframework.stereotype.Service | ||
import org.springframework.transaction.annotation.Transactional | ||
|
||
interface ImageService { | ||
fun load(imageId: ImageId): Image | ||
|
||
fun save( | ||
uuid: String, | ||
imageUrl: String, | ||
): ImageId | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
@Service | ||
class MockImageService() : ImageService { | ||
class DefaultImageService( | ||
private val imageRepository: ImageRepository, | ||
) : ImageService { | ||
@Transactional | ||
override fun save( | ||
uuid: String, | ||
imageUrl: String, | ||
): ImageId { | ||
val entity = ImageEntity(uuid = uuid, url = imageUrl) | ||
val saved = imageRepository.save(entity) | ||
return ImageId(saved.uuid) | ||
} | ||
|
||
override fun load(imageId: ImageId): Image { | ||
return Image.MOCK_USER_IMAGE | ||
TODO("Not yet implemented") | ||
} | ||
} |
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