File tree Expand file tree Collapse file tree 5 files changed +51
-1
lines changed
src/main/kotlin/dsm/pick2024
infrastructure/util/redis Expand file tree Collapse file tree 5 files changed +51
-1
lines changed Original file line number Diff line number Diff line change @@ -4,6 +4,7 @@ import dsm.pick2024.domain.mail.port.`in`.SendMailUseCase
44import dsm.pick2024.domain.mail.presentation.dto.request.SendMailRequest
55import dsm.pick2024.global.security.jwt.exception.InternalServerErrorException
66import dsm.pick2024.infrastructure.mail.MailProperties
7+ import dsm.pick2024.infrastructure.util.redis.port.RateLimiterPort
78import dsm.pick2024.infrastructure.util.redis.port.RedisUtilPort
89import org.springframework.beans.factory.annotation.Value
910import org.springframework.core.io.ClassPathResource
@@ -20,14 +21,15 @@ class SendMailService(
2021 private val mailSender : JavaMailSender ,
2122 private val redisUtilPort : RedisUtilPort ,
2223 private val mailProperties : MailProperties ,
24+ private val rateLimiterPort : RateLimiterPort ,
2325 @Value(" \$ {server.url}" )
2426 private val SERVER_URL : String
2527) : SendMailUseCase {
2628
2729 private val CODE_LENGTH = 6
2830
2931 override fun execute (request : SendMailRequest ) {
30- println ( " SERVER_URL = $SERVER_URL " )
32+ rateLimiterPort.isAllowed(request.mail )
3133
3234 val email = request.mail + mailProperties.dsmPostFix
3335 val authCode = generateAuthCode()
Original file line number Diff line number Diff line change @@ -49,6 +49,8 @@ enum class ErrorCode(
4949
5050 NOT_EXTENSION_XSL (415 , " XSL 확장자가 아닙니다" ),
5151
52+ TOO_MANY_REQUEST (429 , " 너무 많은 요청입니다." ),
53+
5254 // Internal Server Error
5355 INTERNAL_SERVER_ERROR (500 , " 내부 서버 오류" ),
5456 FEIGN_SERVER_ERROR (500 , " Feign 서버 오류" ),
Original file line number Diff line number Diff line change 1+ package dsm.pick2024.infrastructure.util.redis
2+
3+ import dsm.pick2024.infrastructure.util.redis.exception.TooManyRequestException
4+ import dsm.pick2024.infrastructure.util.redis.port.RateLimiterPort
5+ import org.springframework.data.redis.core.StringRedisTemplate
6+ import org.springframework.stereotype.Component
7+ import java.time.Duration
8+
9+ @Component
10+ class RateLimiter (
11+ private val redisTemplate : StringRedisTemplate
12+ ) : RateLimiterPort {
13+ private val RATE_LIMIT_PREFIX = " RATE_LIMIT"
14+
15+ private val REQUEST_LIMIT = 5L
16+
17+ private val TIME_WINDOW = Duration .ofMinutes(10 )
18+
19+ override fun isAllowed (key : String ) {
20+ val valueOperations = redisTemplate.opsForValue()
21+ val redisKey = " $RATE_LIMIT_PREFIX :$key "
22+
23+ val requestCount = valueOperations.increment(redisKey) ? : 0L
24+
25+ if (requestCount == 1L ) {
26+ redisTemplate.expire(redisKey, TIME_WINDOW )
27+ }
28+
29+ if (requestCount > REQUEST_LIMIT ) {
30+ throw TooManyRequestException
31+ }
32+ }
33+ }
Original file line number Diff line number Diff line change 1+ package dsm.pick2024.infrastructure.util.redis.exception
2+
3+ import dsm.pick2024.global.error.exception.ErrorCode
4+ import dsm.pick2024.global.error.exception.PickException
5+
6+ object TooManyRequestException : PickException(
7+ ErrorCode .TOO_MANY_REQUEST
8+ )
Original file line number Diff line number Diff line change 1+ package dsm.pick2024.infrastructure.util.redis.port
2+
3+ interface RateLimiterPort {
4+ fun isAllowed (key : String )
5+ }
You can’t perform that action at this time.
0 commit comments