Skip to content

Commit

Permalink
refactor: replace SesClient with SesAsyncClient and refact to
Browse files Browse the repository at this point in the history
whenComplete

- 기존 `SesClient`를 `SesAsyncClient`로 리팩터링하여 비동기 전송
  방식으로 개선
- `whenComplete`를 활용하여 AWS SDK의 `CompletableFeature` 최적화
- `SesException`과 일반 예외를 구분하여 서드 파티 예외처리를 명확하게
  개선
  • Loading branch information
chock-cho committed Feb 25, 2025
1 parent d2d37ca commit 0a6feba
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ 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.SesAsyncClient
import software.amazon.awssdk.services.ses.SesClient

@Configuration
class SESClientConfig(
private val sesProperties: SESProperties
) {
@Bean
fun sesClient(): SesClient {
return SesClient.builder()
fun sesAsyncClient(): SesAsyncClient {
return SesAsyncClient.builder()
.region(Region.of(sesProperties.region.static))
.credentialsProvider(
StaticCredentialsProvider.create(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,46 @@ package com.dobby.backend.infrastructure.gateway.email

import com.dobby.backend.domain.gateway.email.EmailGateway
import com.dobby.backend.infrastructure.config.properties.SESProperties
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.future.await
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.springframework.stereotype.Component
import software.amazon.awssdk.regions.Region
import software.amazon.awssdk.services.ses.SesAsyncClient
import software.amazon.awssdk.services.ses.SesClient
import software.amazon.awssdk.services.ses.model.*

@Component
class EmailGatewayImpl(
private val sesClient: SesClient,
private val sesAsyncClient: SesAsyncClient,
private val sesProperties: SESProperties
) : EmailGateway {

override suspend fun sendEmail(to: String, subject: String, content: String, isHtml: Boolean) {
withContext(Dispatchers.IO) {
try {
val body = if(isHtml) {
Body.builder().html(Content.builder().data(content).build()).build()
} else {
Body.builder().text(Content.builder().data(content).build()).build()
}
val body = if(isHtml) {
Body.builder().html(Content.builder().data(content).build()).build()
} else {
Body.builder().text(Content.builder().data(content).build()).build()
}

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()
)
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)

} catch (ex: Exception) {
throw IllegalStateException("이메일 발송 실패: ${ex.message}")
sesAsyncClient.sendEmail(request)
.whenComplete { _, ex ->
when(ex){
is SesException -> throw IllegalStateException("AWS SES 오류 발생: ${ex.awsErrorDetails()?.errorMessage()}")
is Exception -> throw IllegalStateException("이메일 전송 실패: ${ex.message}") }
}
}
}
}

0 comments on commit 0a6feba

Please sign in to comment.