-
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.
feat: 이미지 업로드를 위한 presigned url 생성 (#184)
* [#182] build: s3 의존성 추가 * [#182] feat: presigned url 생성 client 작성 * [#182] feat: presigned url 생성 api 작성 * [#182, #160] build: jacoco test coverage 검사 제거 * [#182] test: 인수테스트 로그 제거 * [#182] feat: 이미지 파일 이름 랜덤 생성 * [#160] build: sonarcloud test coverage 제거
- Loading branch information
1 parent
8deab81
commit e2b9589
Showing
11 changed files
with
186 additions
and
3 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
21 changes: 21 additions & 0 deletions
21
src/main/java/com/mallang/common/infra/s3/AwsS3Config.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,21 @@ | ||
package com.mallang.common.infra.s3; | ||
|
||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider; | ||
import software.amazon.awssdk.regions.Region; | ||
import software.amazon.awssdk.services.s3.presigner.S3Presigner; | ||
|
||
@Configuration | ||
public class AwsS3Config { | ||
|
||
/** | ||
* S3Presigner 사용 후 close()를 권장하므로, Builder 를 반환하여 필요 시 객체를 만들어 사용 후 close 되도록 구현. | ||
*/ | ||
@Bean | ||
public S3Presigner.Builder s3PresignerBuilder() { | ||
return S3Presigner.builder() | ||
.credentialsProvider(InstanceProfileCredentialsProvider.create()) | ||
.region(Region.AP_NORTHEAST_2); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
src/main/java/com/mallang/common/infra/s3/AwsS3Property.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,11 @@ | ||
package com.mallang.common.infra.s3; | ||
|
||
import org.springframework.boot.context.properties.ConfigurationProperties; | ||
|
||
@ConfigurationProperties(prefix = "aws.s3") | ||
public record AwsS3Property( | ||
String bucket, | ||
String imagePath, | ||
int presignedUrlExpiresMinutes | ||
) { | ||
} |
43 changes: 43 additions & 0 deletions
43
src/main/java/com/mallang/common/infra/s3/PresignedUrlService.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,43 @@ | ||
package com.mallang.common.infra.s3; | ||
|
||
import java.time.Duration; | ||
import java.util.UUID; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Component; | ||
import software.amazon.awssdk.services.s3.model.PutObjectRequest; | ||
import software.amazon.awssdk.services.s3.presigner.S3Presigner; | ||
import software.amazon.awssdk.services.s3.presigner.model.PresignedPutObjectRequest; | ||
import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest; | ||
|
||
@RequiredArgsConstructor | ||
@Component | ||
public class PresignedUrlService { | ||
|
||
private final S3Presigner.Builder presignerBuilder; | ||
private final AwsS3Property s3Property; | ||
|
||
public String create(String imageExtension) { | ||
String imageName = createImageName(imageExtension); | ||
return createPresignedUrl(imageName); | ||
} | ||
|
||
private String createImageName(String imageExtension) { | ||
String uuid = UUID.randomUUID().toString(); | ||
return uuid + "." + imageExtension; | ||
} | ||
|
||
private String createPresignedUrl(String imageName) { | ||
try (S3Presigner presigner = presignerBuilder.build()) { | ||
PutObjectRequest objectRequest = PutObjectRequest.builder() | ||
.bucket(s3Property.bucket()) | ||
.key(s3Property.imagePath() + imageName) | ||
.build(); | ||
PutObjectPresignRequest presignRequest = PutObjectPresignRequest.builder() | ||
.signatureDuration(Duration.ofMinutes(s3Property.presignedUrlExpiresMinutes())) | ||
.putObjectRequest(objectRequest) | ||
.build(); | ||
PresignedPutObjectRequest presignedRequest = presigner.presignPutObject(presignRequest); | ||
return presignedRequest.url().toExternalForm(); | ||
} | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
src/main/java/com/mallang/common/infra/s3/presentation/CreatePresignedUrlRequest.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,6 @@ | ||
package com.mallang.common.infra.s3.presentation; | ||
|
||
public record CreatePresignedUrlRequest( | ||
String imageExtension | ||
) { | ||
} |
6 changes: 6 additions & 0 deletions
6
src/main/java/com/mallang/common/infra/s3/presentation/CreatePresignedUrlResponse.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,6 @@ | ||
package com.mallang.common.infra.s3.presentation; | ||
|
||
public record CreatePresignedUrlResponse( | ||
String presignedUrl | ||
) { | ||
} |
24 changes: 24 additions & 0 deletions
24
src/main/java/com/mallang/common/infra/s3/presentation/PresignedUrlController.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 com.mallang.common.infra.s3.presentation; | ||
|
||
import com.mallang.common.infra.s3.PresignedUrlService; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RequiredArgsConstructor | ||
@RequestMapping("/infra/aws/s3/presigned-url") | ||
@RestController | ||
public class PresignedUrlController { | ||
|
||
private final PresignedUrlService presignedUrlService; | ||
|
||
@PostMapping | ||
public ResponseEntity<CreatePresignedUrlResponse> createPresignedUrl( | ||
CreatePresignedUrlRequest request | ||
) { | ||
String url = presignedUrlService.create(request.imageExtension()); | ||
return ResponseEntity.ok(new CreatePresignedUrlResponse(url)); | ||
} | ||
} |
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
26 changes: 26 additions & 0 deletions
26
src/test/java/com/mallang/acceptance/common/s3/MockPresignedUrlService.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 com.mallang.acceptance.common.s3; | ||
|
||
import com.mallang.common.infra.s3.AwsS3Property; | ||
import com.mallang.common.infra.s3.PresignedUrlService; | ||
import org.springframework.context.annotation.Primary; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.test.context.ActiveProfiles; | ||
import software.amazon.awssdk.services.s3.presigner.S3Presigner.Builder; | ||
|
||
@ActiveProfiles("test") | ||
@Primary | ||
@Component | ||
public class MockPresignedUrlService extends PresignedUrlService { | ||
|
||
public MockPresignedUrlService( | ||
Builder presignerBuilder, | ||
AwsS3Property s3Property | ||
) { | ||
super(presignerBuilder, s3Property); | ||
} | ||
|
||
@Override | ||
public String create(String imageExtension) { | ||
return "https://example/sample." + imageExtension; | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
src/test/java/com/mallang/acceptance/common/s3/PresignedUrlAcceptanceTest.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,37 @@ | ||
package com.mallang.acceptance.common.s3; | ||
|
||
|
||
import static io.restassured.RestAssured.given; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import com.mallang.acceptance.AcceptanceTest; | ||
import com.mallang.common.infra.s3.presentation.CreatePresignedUrlRequest; | ||
import com.mallang.common.infra.s3.presentation.CreatePresignedUrlResponse; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Nested; | ||
import org.junit.jupiter.api.Test; | ||
|
||
@DisplayName("S3 Presigned Url 인수테스트") | ||
@SuppressWarnings("NonAsciiCharacters") | ||
public class PresignedUrlAcceptanceTest extends AcceptanceTest { | ||
|
||
@Nested | ||
class PresignedUrl_생성_API { | ||
|
||
@Test | ||
void presignedUrl을_생성한다() { | ||
// when | ||
CreatePresignedUrlResponse response = given() | ||
.body(new CreatePresignedUrlRequest("fileName")) | ||
.post("/infra/aws/s3/presigned-url") | ||
.then() | ||
//.log().all() | ||
.extract() | ||
.as(CreatePresignedUrlResponse.class); | ||
|
||
// then | ||
String s = response.presignedUrl(); | ||
assertThat(s).isNotNull(); | ||
} | ||
} | ||
} |