-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[YS-330] refactor: 이메일 전송 기능 AWS SES로 마이그레이션 #121
Merged
Merged
Changes from 6 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
ea64db0
feat: add aws ses sdk dependency
chock-cho b6973bf
fix: pull from origin dev branch
chock-cho fd74d5f
feat: define SES configuration files in infrastructure layer
chock-cho a287f45
refactor: revise the send email implement code to meet the ses client
chock-cho 80ddc2e
fix: correct aws spring cloud dependency typo
chock-cho 4630a4b
test: add missing ses properties in test env
chock-cho 37f2bd6
fix: delete unused smtp config in test env
chock-cho d2d37ca
refactor: delete unused email properties file
chock-cho 0a6feba
refactor: replace SesClient with SesAsyncClient and refact to
chock-cho File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
29 changes: 29 additions & 0 deletions
29
src/main/kotlin/com/dobby/backend/infrastructure/config/SESClientConfig.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,29 @@ | ||
package com.dobby.backend.infrastructure.config | ||
|
||
import com.dobby.backend.infrastructure.config.properties.SESProperties | ||
import org.springframework.context.annotation.Bean | ||
import org.springframework.context.annotation.Configuration | ||
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials | ||
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider | ||
import software.amazon.awssdk.regions.Region | ||
import software.amazon.awssdk.services.ses.SesClient | ||
|
||
@Configuration | ||
class SESClientConfig( | ||
private val sesProperties: SESProperties | ||
) { | ||
@Bean | ||
fun sesClient(): SesClient { | ||
return SesClient.builder() | ||
.region(Region.of(sesProperties.region.static)) | ||
.credentialsProvider( | ||
StaticCredentialsProvider.create( | ||
AwsBasicCredentials.create( | ||
sesProperties.credentials.accessKey, | ||
sesProperties.credentials.secretKey | ||
) | ||
) | ||
) | ||
.build() | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
src/main/kotlin/com/dobby/backend/infrastructure/config/properties/SESProperties.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,23 @@ | ||
package com.dobby.backend.infrastructure.config.properties | ||
|
||
import org.springframework.boot.context.properties.ConfigurationProperties | ||
|
||
@ConfigurationProperties(prefix = "aws.ses") | ||
data class SESProperties ( | ||
val email: Email, | ||
val region: Region, | ||
val credentials: Credentials | ||
) { | ||
data class Email( | ||
val sender: String | ||
) | ||
|
||
data class Region( | ||
val static: String | ||
) | ||
|
||
data class Credentials( | ||
val accessKey: String, | ||
val secretKey: String | ||
) | ||
} |
36 changes: 23 additions & 13 deletions
36
src/main/kotlin/com/dobby/backend/infrastructure/gateway/email/EmailGatewayImpl.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,35 +1,45 @@ | ||
package com.dobby.backend.infrastructure.gateway.email | ||
|
||
import com.dobby.backend.domain.gateway.email.EmailGateway | ||
import com.dobby.backend.infrastructure.config.properties.EmailProperties | ||
import com.dobby.backend.infrastructure.config.properties.SESProperties | ||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.withContext | ||
import org.springframework.mail.SimpleMailMessage | ||
import org.springframework.mail.javamail.JavaMailSender | ||
import org.springframework.mail.javamail.MimeMessageHelper | ||
import org.springframework.stereotype.Component | ||
import software.amazon.awssdk.regions.Region | ||
import software.amazon.awssdk.services.ses.SesClient | ||
import software.amazon.awssdk.services.ses.model.* | ||
|
||
@Component | ||
class EmailGatewayImpl( | ||
private val emailProperties: EmailProperties, | ||
private val mailSender: JavaMailSender | ||
private val sesClient: SesClient, | ||
private val sesProperties: SESProperties | ||
) : EmailGateway { | ||
|
||
override suspend fun sendEmail(to: String, subject: String, content: String, isHtml: Boolean) { | ||
withContext(Dispatchers.IO) { | ||
try { | ||
val message = mailSender.createMimeMessage() | ||
val helper = MimeMessageHelper(message, false, "UTF-8") | ||
val body = if(isHtml) { | ||
Body.builder().html(Content.builder().data(content).build()).build() | ||
} else { | ||
Body.builder().text(Content.builder().data(content).build()).build() | ||
} | ||
|
||
helper.setTo(to) | ||
helper.setSubject(subject) | ||
helper.setText(content, isHtml) | ||
val request = SendEmailRequest.builder() | ||
.source(sesProperties.email.sender) | ||
.destination(Destination.builder().toAddresses(to).build()) | ||
.message( | ||
Message.builder() | ||
.subject(Content.builder().data(subject).build()) | ||
.body(body) | ||
.build() | ||
) | ||
.build() | ||
|
||
sesClient.sendEmail(request) | ||
|
||
mailSender.send(message) | ||
} catch (ex: Exception) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이제 AWS SES라는 서드파티 서비스를 사용하는 거니 예외를 아래와 같은 형식으로 두 번 잡는 건 어떨까요?
|
||
throw IllegalStateException("이메일 발송 실패: ${ex.message}") | ||
} | ||
} | ||
} | ||
} | ||
|
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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
현재
SesClient
는 동기 API를 제공하기 때문에withContext(Dispatchers.IO)
를 사용한 것이 적절해 보입니다.그런데 제가 찾아보니 AWS에서 비동기 클라이언트인
SesAsyncClient
를 제공해서, 이를 활용하면 코루틴 없이도 자연스럽게 비동기 처리가 가능할 거라 기대해요! 이렇게 되면 서비스 전체적으로 코루틴을 줄이고 AWS SDK의 비동기 기능을 최대한 활용할 수 있어 깔끔해진다고 생각하는데 어떻게 생각하시나요? 🤔There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 제가 AWS에서
SesAsyncClient
를 제공해준다는 점을 몰랐었습니다!관련하여 반영하기 위해 더 찾아보니,
SesAsyncClient
의whenComplete
을 사용하면, 코루틴의launch{}
함수와 같은 효과(비동기 스레드 풀로 관리) AWS SDK의 내부 비동기 실행 모델을 최대한 활용할 수 있다고 하네요!오히려 해당 경우에서 코루틴의☺️ )
launch{}
를 사용하면, SES SDK 내부 구조와 호환성이 맞지 않아 예외가 잡히지 않는다고 합니다 👀!(제가 코루틴의
launch{}
와whenComplete
방식으로 개선해보니 두 경우 모두 비슷하게 약 800-900ms 정도의 응답시간이 소요되더라구요지수님의 꼼꼼한 리뷰 덕에 고칠 수 있었어요! 감사합니다! ✨