From fe1afd233180dc4a9d79cc078713bef9161f40ec Mon Sep 17 00:00:00 2001 From: k-kbk Date: Wed, 10 Jan 2024 15:38:37 +0900 Subject: [PATCH 01/12] =?UTF-8?q?s3=20presignedUrl=20=EB=B0=9C=EA=B8=89=20?= =?UTF-8?q?api=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + Dockerfile | 6 +++ build.gradle.kts | 3 ++ gradle.properties | 6 +-- .../mjucow/eatda/common/config/S3Config.kt | 27 ++++++++++++++ .../eatda/domain/s3/dto/PresignedUrlDto.kt | 12 ++++++ .../eatda/domain/s3/service/S3Service.kt | 37 +++++++++++++++++++ .../eatda/presentation/s3/S3Controller.kt | 24 ++++++++++++ src/main/resources/application.yml | 14 +++++++ 9 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/com/mjucow/eatda/common/config/S3Config.kt create mode 100644 src/main/kotlin/com/mjucow/eatda/domain/s3/dto/PresignedUrlDto.kt create mode 100644 src/main/kotlin/com/mjucow/eatda/domain/s3/service/S3Service.kt create mode 100644 src/main/kotlin/com/mjucow/eatda/presentation/s3/S3Controller.kt diff --git a/.gitignore b/.gitignore index c8089ad..28d3a3d 100644 --- a/.gitignore +++ b/.gitignore @@ -175,3 +175,5 @@ gradle-app.setting *.hprof redis/ + +.run diff --git a/Dockerfile b/Dockerfile index e5bf806..ceec6d1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,9 @@ ARG PROFILE=prod ARG DB_URL ARG DB_USERNAME ARG DB_PASSWORD +ARG S3_ACCESS_KEY +ARG S3_SECRET_KEY +ARG S3_BUCKET COPY ${JAR_FILE} app.jar @@ -15,5 +18,8 @@ ENV PROFILE=${PROFILE} ENV DB_URL=${DB_URL} ENV DB_USERNAME=${DB_USERNAME} ENV DB_PASSWORD=${DB_PASSWORD} +ENV S3_ACCESS_KEY=${S3_ACCESS_KEY} +ENV S3_SECRET_KEY=${S3_SECRET_KEY} +ENV S3_BUCKET=${S3_BUCKET} ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=${PROFILE}", "-Djava.security.egd=file:/dev/./urandom", "/app.jar"] diff --git a/build.gradle.kts b/build.gradle.kts index 27893df..6a1d8e1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -63,6 +63,9 @@ dependencies { jooqGenerator("org.jooq:jooq-meta-extensions-liquibase") jooqGenerator("org.liquibase:liquibase-core") + // aws + implementation("software.amazon.awssdk:s3:2.22.12") + // test testImplementation("org.testcontainers:postgresql") testImplementation("org.testcontainers:testcontainers:$testContainerVersion") diff --git a/gradle.properties b/gradle.properties index 232fd22..9ca4c36 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,11 +4,11 @@ applicationVersion=0.1.8-RELEASE ### Project configs ### projectGroup="com.mjucow" -### Project depdency versions ### +### Project dependency versions ### kotlinVersion=1.9.10 javaVersion=17 -### Plugin depdency versions ### +### Plugin dependency versions ### asciidoctorConvertVersion=3.3.2 ktlintVersion=11.6.0 jacocoVersion=0.8.9 @@ -17,7 +17,7 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyManagementVersion=1.1.3 -### DB depedency versions ### +### DB dependency versions ### jooqPluginVersion=8.2 jooqVersion="3.18.4" diff --git a/src/main/kotlin/com/mjucow/eatda/common/config/S3Config.kt b/src/main/kotlin/com/mjucow/eatda/common/config/S3Config.kt new file mode 100644 index 0000000..fb3f3cc --- /dev/null +++ b/src/main/kotlin/com/mjucow/eatda/common/config/S3Config.kt @@ -0,0 +1,27 @@ +package com.mjucow.eatda.common.config + +import org.springframework.beans.factory.annotation.Value +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials +import software.amazon.awssdk.regions.Region +import software.amazon.awssdk.services.s3.presigner.S3Presigner + +@Configuration +class S3Config( + @Value("\${aws.s3.credentials.access-key}") + private val accessKey: String, + @Value("\${aws.s3.credentials.secret-key}") + private val secretKey: String, +) { + + @Bean + fun s3Presigner(): S3Presigner { + val credential = AwsBasicCredentials.create(accessKey, secretKey) + + return S3Presigner.builder() + .region(Region.AP_NORTHEAST_2) + .credentialsProvider { credential } + .build() + } +} diff --git a/src/main/kotlin/com/mjucow/eatda/domain/s3/dto/PresignedUrlDto.kt b/src/main/kotlin/com/mjucow/eatda/domain/s3/dto/PresignedUrlDto.kt new file mode 100644 index 0000000..329a4d0 --- /dev/null +++ b/src/main/kotlin/com/mjucow/eatda/domain/s3/dto/PresignedUrlDto.kt @@ -0,0 +1,12 @@ +package com.mjucow.eatda.domain.s3.dto + +data class PresignedUrlDto( + val url: String, +) { + + companion object { + fun from(url: String): PresignedUrlDto { + return PresignedUrlDto(url) + } + } +} diff --git a/src/main/kotlin/com/mjucow/eatda/domain/s3/service/S3Service.kt b/src/main/kotlin/com/mjucow/eatda/domain/s3/service/S3Service.kt new file mode 100644 index 0000000..80b716a --- /dev/null +++ b/src/main/kotlin/com/mjucow/eatda/domain/s3/service/S3Service.kt @@ -0,0 +1,37 @@ +package com.mjucow.eatda.domain.s3.service + +import org.springframework.beans.factory.annotation.Value +import org.springframework.stereotype.Service +import software.amazon.awssdk.services.s3.model.PutObjectRequest +import software.amazon.awssdk.services.s3.presigner.S3Presigner +import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest +import java.time.Duration + +@Service +class S3Service( + private val s3Presigner: S3Presigner, + @Value("\${aws.s3.bucket}") + private val bucket: String, +) { + + fun createPresignedUrl(key: String, contentType: String): String { + val putObjectRequest = PutObjectRequest + .builder() + .bucket(bucket) + .key(key) + .contentType(contentType) + .build() + + val presignRequest = PutObjectPresignRequest + .builder() + .signatureDuration(Duration.ofMinutes(DURATION_MINUTES)) + .putObjectRequest(putObjectRequest) + .build() + + return s3Presigner.presignPutObject(presignRequest).url().toString() + } + + companion object { + const val DURATION_MINUTES = 3L + } +} diff --git a/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3Controller.kt b/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3Controller.kt new file mode 100644 index 0000000..b7c559c --- /dev/null +++ b/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3Controller.kt @@ -0,0 +1,24 @@ +package com.mjucow.eatda.presentation.s3 + +import com.mjucow.eatda.domain.s3.dto.PresignedUrlDto +import com.mjucow.eatda.domain.s3.service.S3Service +import com.mjucow.eatda.presentation.common.ApiResponse +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestParam +import org.springframework.web.bind.annotation.RestController + +@RequestMapping("/api/v1/s3") +@RestController +class S3Controller( + private val s3Service: S3Service, +) { + + @GetMapping("/presigned-url") + fun createPresignedUrl( + @RequestParam key: String, + @RequestParam contentType: String, + ): ApiResponse { + return ApiResponse.success(PresignedUrlDto(s3Service.createPresignedUrl(key, contentType))) + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 53076c2..d829cdc 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -65,6 +65,13 @@ spring: host: localhost port: 16379 +aws: + s3: + credentials: + access-key: ${S3_ACCESS_KEY} + secret-key: ${S3_SECRET_KEY} + bucket: ${S3_BUCKET} + --- spring: @@ -100,3 +107,10 @@ spring: jooq: sql-dialect: postgres + +aws: + s3: + credentials: + access-key: ${S3_ACCESS_KEY} + secret-key: ${S3_SECRET_KEY} + bucket: ${S3_BUCKET} From 99fb793d83cd672749aba01c26b15b0617058782 Mon Sep 17 00:00:00 2001 From: k-kbk Date: Wed, 10 Jan 2024 18:24:53 +0900 Subject: [PATCH 02/12] =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=9A=A9=20presignedUr?= =?UTF-8?q?l=20=EC=83=9D=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eatda/domain/s3/service/S3Service.kt | 25 ++++++++++++++++--- .../eatda/presentation/s3/S3Controller.kt | 11 ++++++-- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/mjucow/eatda/domain/s3/service/S3Service.kt b/src/main/kotlin/com/mjucow/eatda/domain/s3/service/S3Service.kt index 80b716a..78b9cda 100644 --- a/src/main/kotlin/com/mjucow/eatda/domain/s3/service/S3Service.kt +++ b/src/main/kotlin/com/mjucow/eatda/domain/s3/service/S3Service.kt @@ -2,8 +2,10 @@ package com.mjucow.eatda.domain.s3.service import org.springframework.beans.factory.annotation.Value import org.springframework.stereotype.Service +import software.amazon.awssdk.services.s3.model.GetObjectRequest import software.amazon.awssdk.services.s3.model.PutObjectRequest import software.amazon.awssdk.services.s3.presigner.S3Presigner +import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest import java.time.Duration @@ -14,7 +16,7 @@ class S3Service( private val bucket: String, ) { - fun createPresignedUrl(key: String, contentType: String): String { + fun createPutPresignedUrl(key: String, contentType: String): String { val putObjectRequest = PutObjectRequest .builder() .bucket(bucket) @@ -24,14 +26,31 @@ class S3Service( val presignRequest = PutObjectPresignRequest .builder() - .signatureDuration(Duration.ofMinutes(DURATION_MINUTES)) + .signatureDuration(Duration.ofMinutes(PUT_DURATION_MINUTES)) .putObjectRequest(putObjectRequest) .build() return s3Presigner.presignPutObject(presignRequest).url().toString() } + fun createGetPresignedUrl(key: String): String { + val getObjectRequest = GetObjectRequest + .builder() + .bucket(bucket) + .key(key) + .build() + + val presignRequest = GetObjectPresignRequest + .builder() + .signatureDuration(Duration.ofHours(GET_DURATION_HOURS)) + .getObjectRequest(getObjectRequest) + .build() + + return s3Presigner.presignGetObject(presignRequest).url().toString() + } + companion object { - const val DURATION_MINUTES = 3L + const val PUT_DURATION_MINUTES = 3L + const val GET_DURATION_HOURS = 24L } } diff --git a/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3Controller.kt b/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3Controller.kt index b7c559c..884cbe0 100644 --- a/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3Controller.kt +++ b/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3Controller.kt @@ -15,10 +15,17 @@ class S3Controller( ) { @GetMapping("/presigned-url") - fun createPresignedUrl( + fun getPutPresignedUrl( @RequestParam key: String, @RequestParam contentType: String, ): ApiResponse { - return ApiResponse.success(PresignedUrlDto(s3Service.createPresignedUrl(key, contentType))) + return ApiResponse.success( + PresignedUrlDto( + s3Service.createPutPresignedUrl( + key = key, + contentType = contentType + ) + ) + ) } } From 582e5e11f28c42b6d5ea57a0ed9cc0af186c8985 Mon Sep 17 00:00:00 2001 From: k-kbk Date: Wed, 10 Jan 2024 18:41:51 +0900 Subject: [PATCH 03/12] lint --- .../kotlin/com/mjucow/eatda/domain/s3/dto/PresignedUrlDto.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/com/mjucow/eatda/domain/s3/dto/PresignedUrlDto.kt b/src/main/kotlin/com/mjucow/eatda/domain/s3/dto/PresignedUrlDto.kt index 329a4d0..0c199fa 100644 --- a/src/main/kotlin/com/mjucow/eatda/domain/s3/dto/PresignedUrlDto.kt +++ b/src/main/kotlin/com/mjucow/eatda/domain/s3/dto/PresignedUrlDto.kt @@ -3,7 +3,7 @@ package com.mjucow.eatda.domain.s3.dto data class PresignedUrlDto( val url: String, ) { - + companion object { fun from(url: String): PresignedUrlDto { return PresignedUrlDto(url) From b644139a78fc7e03ca1e79b054c8054af9a7b87c Mon Sep 17 00:00:00 2001 From: k-kbk Date: Wed, 10 Jan 2024 18:56:30 +0900 Subject: [PATCH 04/12] =?UTF-8?q?test=20=EC=84=A4=EC=A0=95=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test.yml | 4 +++ src/test/resources/application.yml | 45 +++++++++++++++++------------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b489492..62bafe5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,6 +30,10 @@ jobs: # Gradle test를 실행 - name: Test with Gradle run: ./gradlew clean testCoverage --no-daemon + env: + S3_ACCESS_KEY: ${{ secrets.S3_ACCESS_KEY }} + S3_SECRET_KEY: ${{ secrets.S3_SECRET_KEY }} + S3_BUCKET: ${{ secrets.S3_TEST_BUCKET }} # Report upload - name: Upload coverage reports to Codecov diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 387c7c0..ec9d75e 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -1,24 +1,31 @@ spring: - jpa: - hibernate: - ddl-auto: validate - properties: - hibernate: - format_sql: true - show_sql: true - database-platform: org.hibernate.dialect.PostgreSQLDialect - database: postgresql - liquibase: - change-log: classpath:/db/changelog-master.yml - enabled: true + jpa: + hibernate: + ddl-auto: validate + properties: + hibernate: + format_sql: true + show_sql: true + database-platform: org.hibernate.dialect.PostgreSQLDialect + database: postgresql + liquibase: + change-log: classpath:/db/changelog-master.yml + enabled: true - datasource: - driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver - url: jdbc:tc:postgresql:15.4-alpine://test-database + datasource: + driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver + url: jdbc:tc:postgresql:15.4-alpine://test-database - data: - redis: - host: 127.0.0.1 - port: 6379 + data: + redis: + host: 127.0.0.1 + port: 6379 logging.config: classpath:logback-test.xml + +aws: + s3: + credentials: + access-key: ${S3_ACCESS_KEY} + secret-key: ${S3_SECRET_KEY} + bucket: ${S3_BUCKET} From 5eee1cbee8ce608d81034b9bee4643c6e2dbd0c6 Mon Sep 17 00:00:00 2001 From: k-kbk Date: Wed, 10 Jan 2024 19:06:54 +0900 Subject: [PATCH 05/12] =?UTF-8?q?s3=20jacoco=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EC=A0=9C=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 6a1d8e1..65d0236 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -196,7 +196,8 @@ tasks.jacocoTestCoverageVerification { "*.common.*", "*.dto.*", "com.mjucow.eatda.jooq.*", - "*.Companion" + "*.Companion", + "*.s3.*" ) } } From 397e0fc87f24c87123567a016992f6e7ef7f06d8 Mon Sep 17 00:00:00 2001 From: k-kbk Date: Tue, 30 Jan 2024 21:33:42 +0900 Subject: [PATCH 06/12] =?UTF-8?q?string=20=E2=86=92=20URL=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eatda/domain/s3/dto/PresignedUrlDto.kt | 6 ++++-- .../mjucow/eatda/domain/s3/service/S3Service.kt | 17 +++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/com/mjucow/eatda/domain/s3/dto/PresignedUrlDto.kt b/src/main/kotlin/com/mjucow/eatda/domain/s3/dto/PresignedUrlDto.kt index 0c199fa..867c897 100644 --- a/src/main/kotlin/com/mjucow/eatda/domain/s3/dto/PresignedUrlDto.kt +++ b/src/main/kotlin/com/mjucow/eatda/domain/s3/dto/PresignedUrlDto.kt @@ -1,11 +1,13 @@ package com.mjucow.eatda.domain.s3.dto +import java.net.URL + data class PresignedUrlDto( - val url: String, + val url: URL, ) { companion object { - fun from(url: String): PresignedUrlDto { + fun from(url: URL): PresignedUrlDto { return PresignedUrlDto(url) } } diff --git a/src/main/kotlin/com/mjucow/eatda/domain/s3/service/S3Service.kt b/src/main/kotlin/com/mjucow/eatda/domain/s3/service/S3Service.kt index 78b9cda..2bcd1ca 100644 --- a/src/main/kotlin/com/mjucow/eatda/domain/s3/service/S3Service.kt +++ b/src/main/kotlin/com/mjucow/eatda/domain/s3/service/S3Service.kt @@ -7,6 +7,7 @@ import software.amazon.awssdk.services.s3.model.PutObjectRequest import software.amazon.awssdk.services.s3.presigner.S3Presigner import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest +import java.net.URL import java.time.Duration @Service @@ -16,7 +17,7 @@ class S3Service( private val bucket: String, ) { - fun createPutPresignedUrl(key: String, contentType: String): String { + fun createPutPresignedUrl(key: String, contentType: String): URL { val putObjectRequest = PutObjectRequest .builder() .bucket(bucket) @@ -26,14 +27,14 @@ class S3Service( val presignRequest = PutObjectPresignRequest .builder() - .signatureDuration(Duration.ofMinutes(PUT_DURATION_MINUTES)) + .signatureDuration(Duration.ofMinutes(UPLOAD_DURATION_MINUTES)) .putObjectRequest(putObjectRequest) .build() - return s3Presigner.presignPutObject(presignRequest).url().toString() + return s3Presigner.presignPutObject(presignRequest).url() } - fun createGetPresignedUrl(key: String): String { + fun createGetPresignedUrl(key: String): URL { val getObjectRequest = GetObjectRequest .builder() .bucket(bucket) @@ -42,15 +43,15 @@ class S3Service( val presignRequest = GetObjectPresignRequest .builder() - .signatureDuration(Duration.ofHours(GET_DURATION_HOURS)) + .signatureDuration(Duration.ofHours(DOWNLOAD_DURATION_HOURS)) .getObjectRequest(getObjectRequest) .build() - return s3Presigner.presignGetObject(presignRequest).url().toString() + return s3Presigner.presignGetObject(presignRequest).url() } companion object { - const val PUT_DURATION_MINUTES = 3L - const val GET_DURATION_HOURS = 24L + const val UPLOAD_DURATION_MINUTES = 3L + const val DOWNLOAD_DURATION_HOURS = 24L } } From fe2999c5c5f959fd6c335dd860b6ca7a2bba0170 Mon Sep 17 00:00:00 2001 From: k-kbk Date: Tue, 30 Jan 2024 21:36:09 +0900 Subject: [PATCH 07/12] =?UTF-8?q?=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 8ab9939..2d9b395 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -198,7 +198,7 @@ tasks.jacocoTestCoverageVerification { "com.mjucow.eatda.jooq.*", "*.Companion", "*.s3.*", - "*.popularstore.*" // FIXME: redis 이슈 해결 후 제거'[ + "*.popularstore.*" // FIXME: redis 이슈 해결 후 제거 ) } } From 30cb945518642622227f6dd1a4b4230ccebcb9f1 Mon Sep 17 00:00:00 2001 From: k-kbk Date: Tue, 30 Jan 2024 21:43:03 +0900 Subject: [PATCH 08/12] =?UTF-8?q?=EB=AA=85=EC=84=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eatda/presentation/s3/S3ApiPresentation.kt | 16 ++++++++++++++++ .../mjucow/eatda/presentation/s3/S3Controller.kt | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/com/mjucow/eatda/presentation/s3/S3ApiPresentation.kt diff --git a/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3ApiPresentation.kt b/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3ApiPresentation.kt new file mode 100644 index 0000000..f38cee1 --- /dev/null +++ b/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3ApiPresentation.kt @@ -0,0 +1,16 @@ +package com.mjucow.eatda.presentation.s3 + +import com.mjucow.eatda.domain.s3.dto.PresignedUrlDto +import com.mjucow.eatda.presentation.common.ApiResponse +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag + +@Tag(name = "S3 API", description = "S3 관련 API") +interface S3ApiPresentation { + + @Operation( + summary = "이미지 업로드용 presigned URL 발급", + description = "*key: 버킷의 폴더 경로" + ) + fun getPutPresignedUrl(key: String, contentType: String): ApiResponse +} diff --git a/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3Controller.kt b/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3Controller.kt index 884cbe0..4a0fc06 100644 --- a/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3Controller.kt +++ b/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3Controller.kt @@ -12,10 +12,10 @@ import org.springframework.web.bind.annotation.RestController @RestController class S3Controller( private val s3Service: S3Service, -) { +) : S3ApiPresentation { @GetMapping("/presigned-url") - fun getPutPresignedUrl( + override fun getPutPresignedUrl( @RequestParam key: String, @RequestParam contentType: String, ): ApiResponse { From e36c50ddfc6348e7d1df8081cad08917b0ab5c13 Mon Sep 17 00:00:00 2001 From: k-kbk Date: Tue, 30 Jan 2024 21:55:07 +0900 Subject: [PATCH 09/12] =?UTF-8?q?codecov=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- codecov.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 codecov.yml diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..5f5a402 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,3 @@ +ignore: + - "*/s3/*" + - "*/s3/*" From e209189eebef4deb3f2e05af2c3f1a41cd9a4aac Mon Sep 17 00:00:00 2001 From: k-kbk Date: Tue, 30 Jan 2024 22:03:30 +0900 Subject: [PATCH 10/12] =?UTF-8?q?codecov=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test.yml | 2 ++ codecov.yml | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) delete mode 100644 codecov.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 62bafe5..af8bbcd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,6 +38,8 @@ jobs: # Report upload - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v3 + with: + flags: '!*/s3/*' env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} file: ./build/reports/jacoco/test/jacocoTestReport.xml diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index 5f5a402..0000000 --- a/codecov.yml +++ /dev/null @@ -1,3 +0,0 @@ -ignore: - - "*/s3/*" - - "*/s3/*" From 9dc39a68ce40c12535a90bc4209b666515d17170 Mon Sep 17 00:00:00 2001 From: k-kbk Date: Tue, 30 Jan 2024 22:05:39 +0900 Subject: [PATCH 11/12] =?UTF-8?q?codecov=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index af8bbcd..d474b53 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -39,7 +39,7 @@ jobs: - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v3 with: - flags: '!*/s3/*' + flags: '!**/s3/*' env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} file: ./build/reports/jacoco/test/jacocoTestReport.xml From 1a0a2ad3c5d529f2d1a9b84ee80bdfe3c4d64a31 Mon Sep 17 00:00:00 2001 From: k-kbk Date: Tue, 30 Jan 2024 23:55:25 +0900 Subject: [PATCH 12/12] =?UTF-8?q?s3=20prod=20=ED=94=84=EB=A1=9C=ED=95=84?= =?UTF-8?q?=20=ED=99=9C=EC=84=B1=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mjucow/eatda/common/config/S3Config.kt | 2 ++ .../eatda/domain/s3/service/S3Service.kt | 2 ++ .../eatda/presentation/s3/S3Controller.kt | 2 ++ src/main/resources/application.yml | 7 ------- src/test/resources/application.yml | 7 ------- src/test/resources/logback-test.xml | 18 +++++++++--------- 6 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/main/kotlin/com/mjucow/eatda/common/config/S3Config.kt b/src/main/kotlin/com/mjucow/eatda/common/config/S3Config.kt index fb3f3cc..9273db2 100644 --- a/src/main/kotlin/com/mjucow/eatda/common/config/S3Config.kt +++ b/src/main/kotlin/com/mjucow/eatda/common/config/S3Config.kt @@ -3,11 +3,13 @@ package com.mjucow.eatda.common.config import org.springframework.beans.factory.annotation.Value import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.Profile import software.amazon.awssdk.auth.credentials.AwsBasicCredentials import software.amazon.awssdk.regions.Region import software.amazon.awssdk.services.s3.presigner.S3Presigner @Configuration +@Profile("prod") class S3Config( @Value("\${aws.s3.credentials.access-key}") private val accessKey: String, diff --git a/src/main/kotlin/com/mjucow/eatda/domain/s3/service/S3Service.kt b/src/main/kotlin/com/mjucow/eatda/domain/s3/service/S3Service.kt index 2bcd1ca..9829835 100644 --- a/src/main/kotlin/com/mjucow/eatda/domain/s3/service/S3Service.kt +++ b/src/main/kotlin/com/mjucow/eatda/domain/s3/service/S3Service.kt @@ -1,6 +1,7 @@ package com.mjucow.eatda.domain.s3.service import org.springframework.beans.factory.annotation.Value +import org.springframework.context.annotation.Profile import org.springframework.stereotype.Service import software.amazon.awssdk.services.s3.model.GetObjectRequest import software.amazon.awssdk.services.s3.model.PutObjectRequest @@ -11,6 +12,7 @@ import java.net.URL import java.time.Duration @Service +@Profile("prod") class S3Service( private val s3Presigner: S3Presigner, @Value("\${aws.s3.bucket}") diff --git a/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3Controller.kt b/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3Controller.kt index 4a0fc06..3f2172d 100644 --- a/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3Controller.kt +++ b/src/main/kotlin/com/mjucow/eatda/presentation/s3/S3Controller.kt @@ -3,6 +3,7 @@ package com.mjucow.eatda.presentation.s3 import com.mjucow.eatda.domain.s3.dto.PresignedUrlDto import com.mjucow.eatda.domain.s3.service.S3Service import com.mjucow.eatda.presentation.common.ApiResponse +import org.springframework.context.annotation.Profile import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam @@ -10,6 +11,7 @@ import org.springframework.web.bind.annotation.RestController @RequestMapping("/api/v1/s3") @RestController +@Profile("prod") class S3Controller( private val s3Service: S3Service, ) : S3ApiPresentation { diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index d829cdc..1b116f7 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -65,13 +65,6 @@ spring: host: localhost port: 16379 -aws: - s3: - credentials: - access-key: ${S3_ACCESS_KEY} - secret-key: ${S3_SECRET_KEY} - bucket: ${S3_BUCKET} - --- spring: diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index ec9d75e..bd53901 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -22,10 +22,3 @@ spring: port: 6379 logging.config: classpath:logback-test.xml - -aws: - s3: - credentials: - access-key: ${S3_ACCESS_KEY} - secret-key: ${S3_SECRET_KEY} - bucket: ${S3_BUCKET} diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index e7983ea..e48abb6 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -1,20 +1,20 @@ - + + + + + + ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> %d{HH:mm:ss.SSS} %-5level %logger - %msg%n + + + - - - - - - -