From f4ccffba0592d7cbc3f12735e01118a1c442235c Mon Sep 17 00:00:00 2001 From: sohyundoh Date: Wed, 13 Nov 2024 21:53:27 +0900 Subject: [PATCH 01/11] =?UTF-8?q?#575=20[feat]=20=EB=B6=84=EC=82=B0?= =?UTF-8?q?=EB=9D=BD=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lock/AopForTransaction.java | 2 +- .../service/lock/AtomicMoimPopulerInfo.java | 12 ----- .../service/lock/MoimPopularInfoAspect.java | 49 ------------------- 3 files changed, 1 insertion(+), 62 deletions(-) rename module-domain/src/main/java/com/mile/{moim/service => common}/lock/AopForTransaction.java (92%) delete mode 100644 module-domain/src/main/java/com/mile/moim/service/lock/AtomicMoimPopulerInfo.java delete mode 100644 module-domain/src/main/java/com/mile/moim/service/lock/MoimPopularInfoAspect.java diff --git a/module-domain/src/main/java/com/mile/moim/service/lock/AopForTransaction.java b/module-domain/src/main/java/com/mile/common/lock/AopForTransaction.java similarity index 92% rename from module-domain/src/main/java/com/mile/moim/service/lock/AopForTransaction.java rename to module-domain/src/main/java/com/mile/common/lock/AopForTransaction.java index 545d1a34..12a1ad12 100644 --- a/module-domain/src/main/java/com/mile/moim/service/lock/AopForTransaction.java +++ b/module-domain/src/main/java/com/mile/common/lock/AopForTransaction.java @@ -1,4 +1,4 @@ -package com.mile.moim.service.lock; +package com.mile.common.lock; import org.aspectj.lang.ProceedingJoinPoint; import org.springframework.stereotype.Component; diff --git a/module-domain/src/main/java/com/mile/moim/service/lock/AtomicMoimPopulerInfo.java b/module-domain/src/main/java/com/mile/moim/service/lock/AtomicMoimPopulerInfo.java deleted file mode 100644 index 1b158e4f..00000000 --- a/module-domain/src/main/java/com/mile/moim/service/lock/AtomicMoimPopulerInfo.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.mile.moim.service.lock; - - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target({ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -public @interface AtomicMoimPopulerInfo { -} diff --git a/module-domain/src/main/java/com/mile/moim/service/lock/MoimPopularInfoAspect.java b/module-domain/src/main/java/com/mile/moim/service/lock/MoimPopularInfoAspect.java deleted file mode 100644 index 5cb88fa7..00000000 --- a/module-domain/src/main/java/com/mile/moim/service/lock/MoimPopularInfoAspect.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.mile.moim.service.lock; - -import com.mile.exception.message.ErrorMessage; -import com.mile.exception.model.MileException; -import com.mile.moim.domain.Moim; -import lombok.RequiredArgsConstructor; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Pointcut; -import org.redisson.api.RLock; -import org.redisson.api.RedissonClient; -import org.springframework.stereotype.Component; - -import java.util.concurrent.TimeUnit; - -@Aspect -@RequiredArgsConstructor -@Component -public class MoimPopularInfoAspect { - - private final RedissonClient redissonClient; - private final static String MOIM_POPULAR_LOCK = "MOIM_POPULAR_LOCK : "; - private final AopForTransaction aopForTransaction; - - @Pointcut("@annotation(com.mile.moim.service.lock.AtomicMoimPopulerInfo)") - public void setMoimPoplarInfoCut() { - } - - @Around("setMoimPoplarInfoCut()") - public Object getLockForPopularInfoTransaction(final ProceedingJoinPoint joinPoint) throws Throwable { - final Moim moim = (Moim) joinPoint.getArgs()[0]; - - final RLock lock = redissonClient.getLock(MOIM_POPULAR_LOCK + moim.getId().toString()); - - try { - checkAvailability(lock.tryLock(3, 4, TimeUnit.SECONDS)); - return aopForTransaction.proceed(joinPoint); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } finally { - lock.unlock(); - } - } - - public void checkAvailability(final Boolean available) { - if (!available) throw new MileException(ErrorMessage.TIME_OUT_EXCEPTION); - } -} From 66a222410ccbbee040bb686511549b26bc29f3f3 Mon Sep 17 00:00:00 2001 From: sohyundoh Date: Wed, 13 Nov 2024 21:54:21 +0900 Subject: [PATCH 02/11] =?UTF-8?q?#575=20[feat]=20=EB=B6=84=EC=82=B0?= =?UTF-8?q?=EB=9D=BD=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service => common}/lock/AtomicValidateUniqueMoimName.java | 2 +- .../src/main/java/com/mile/moim/service/MoimService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename module-domain/src/main/java/com/mile/{moim/service => common}/lock/AtomicValidateUniqueMoimName.java (88%) diff --git a/module-domain/src/main/java/com/mile/moim/service/lock/AtomicValidateUniqueMoimName.java b/module-domain/src/main/java/com/mile/common/lock/AtomicValidateUniqueMoimName.java similarity index 88% rename from module-domain/src/main/java/com/mile/moim/service/lock/AtomicValidateUniqueMoimName.java rename to module-domain/src/main/java/com/mile/common/lock/AtomicValidateUniqueMoimName.java index 3b0579f1..a93d5b68 100644 --- a/module-domain/src/main/java/com/mile/moim/service/lock/AtomicValidateUniqueMoimName.java +++ b/module-domain/src/main/java/com/mile/common/lock/AtomicValidateUniqueMoimName.java @@ -1,4 +1,4 @@ -package com.mile.moim.service.lock; +package com.mile.common.lock; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/module-domain/src/main/java/com/mile/moim/service/MoimService.java b/module-domain/src/main/java/com/mile/moim/service/MoimService.java index 64f4adaf..630cfdb4 100644 --- a/module-domain/src/main/java/com/mile/moim/service/MoimService.java +++ b/module-domain/src/main/java/com/mile/moim/service/MoimService.java @@ -33,7 +33,7 @@ import com.mile.moim.service.dto.response.TemporaryPostExistResponse; import com.mile.moim.service.dto.response.TopicListResponse; import com.mile.moim.service.dto.response.WriterNameConflictCheckResponse; -import com.mile.moim.service.lock.AtomicValidateUniqueMoimName; +import com.mile.common.lock.AtomicValidateUniqueMoimName; import com.mile.moim.service.popular.MoimPopularInfoService; import com.mile.post.domain.Post; import com.mile.post.service.PostRetriever; From 9d7f3a87818faaddc8257e2464959ebc7f08aafd Mon Sep 17 00:00:00 2001 From: sohyundoh Date: Wed, 13 Nov 2024 21:54:44 +0900 Subject: [PATCH 03/11] =?UTF-8?q?#575=20[feat]=20DistributedLock=20?= =?UTF-8?q?=ED=85=9C=ED=94=8C=EB=A6=BF=20=EA=B5=AC=ED=98=84=20=EB=B0=8F=20?= =?UTF-8?q?=ED=99=9C=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mile/common/lock/DistributedLock.java | 36 +++++++++++++++++++ .../lock/MoimNameRequestAspect.java | 23 ++++-------- .../com/mile/moim/service/MoimRetriever.java | 2 +- .../popular/MoimPopularInfoRegister.java | 11 ++++-- .../popular/MoimPopularInfoService.java | 2 -- 5 files changed, 52 insertions(+), 22 deletions(-) create mode 100644 module-domain/src/main/java/com/mile/common/lock/DistributedLock.java rename module-domain/src/main/java/com/mile/{moim/service => common}/lock/MoimNameRequestAspect.java (54%) diff --git a/module-domain/src/main/java/com/mile/common/lock/DistributedLock.java b/module-domain/src/main/java/com/mile/common/lock/DistributedLock.java new file mode 100644 index 00000000..5415b3f8 --- /dev/null +++ b/module-domain/src/main/java/com/mile/common/lock/DistributedLock.java @@ -0,0 +1,36 @@ +package com.mile.common.lock; + +import com.mile.exception.message.ErrorMessage; +import com.mile.exception.model.MileException; +import lombok.RequiredArgsConstructor; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; + +@RequiredArgsConstructor +@Component +public class DistributedLock { + + private final RedissonClient redissonClient; + + public void getLock(final String key) { + final RLock lock = redissonClient.getLock(key); + try { + checkAvailability(lock.tryLock(3, 4, TimeUnit.SECONDS)); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + public void afterLock(final String key) { + final RLock lock = redissonClient.getLock(key); + lock.unlock(); + } + + public void checkAvailability(final Boolean available) { + if (!available) throw new MileException(ErrorMessage.TIME_OUT_EXCEPTION); + } + +} diff --git a/module-domain/src/main/java/com/mile/moim/service/lock/MoimNameRequestAspect.java b/module-domain/src/main/java/com/mile/common/lock/MoimNameRequestAspect.java similarity index 54% rename from module-domain/src/main/java/com/mile/moim/service/lock/MoimNameRequestAspect.java rename to module-domain/src/main/java/com/mile/common/lock/MoimNameRequestAspect.java index 719b6ed6..7c45c128 100644 --- a/module-domain/src/main/java/com/mile/moim/service/lock/MoimNameRequestAspect.java +++ b/module-domain/src/main/java/com/mile/common/lock/MoimNameRequestAspect.java @@ -1,46 +1,35 @@ -package com.mile.moim.service.lock; +package com.mile.common.lock; -import com.mile.exception.message.ErrorMessage; -import com.mile.exception.model.MileException; import lombok.RequiredArgsConstructor; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; -import org.redisson.api.RLock; -import org.redisson.api.RedissonClient; import org.springframework.stereotype.Component; -import java.util.concurrent.TimeUnit; - @Aspect @RequiredArgsConstructor @Component public class MoimNameRequestAspect { - private final RedissonClient redissonClient; - private final static String MOIM_NAME_LOCK = "MOIM_NAME_LOCK : "; + private final DistributedLock distributedLock; + private final static String MOIM_NAME_LOCK = "MOIM_NAME_LOCK"; private final AopForTransaction aopForTransaction; - @Pointcut("@annotation(com.mile.moim.service.lock.AtomicValidateUniqueMoimName)") + @Pointcut("@annotation(com.mile.common.lock.AtomicValidateUniqueMoimName)") public void uniqueMoimNameCut() { } @Around("uniqueMoimNameCut()") public Object validateUniqueName(final ProceedingJoinPoint joinPoint) throws Throwable { - final RLock lock = redissonClient.getLock(MOIM_NAME_LOCK); try { - checkAvailability(lock.tryLock(3, 4, TimeUnit.SECONDS)); + distributedLock.getLock(MOIM_NAME_LOCK); return aopForTransaction.proceed(joinPoint); } catch (InterruptedException e) { throw new RuntimeException(e); } finally { - lock.unlock(); + distributedLock.afterLock(MOIM_NAME_LOCK); } } - public void checkAvailability(final Boolean available) { - if (!available) throw new MileException(ErrorMessage.TIME_OUT_EXCEPTION); - } - } diff --git a/module-domain/src/main/java/com/mile/moim/service/MoimRetriever.java b/module-domain/src/main/java/com/mile/moim/service/MoimRetriever.java index f5b3be0f..f3da8cd1 100644 --- a/module-domain/src/main/java/com/mile/moim/service/MoimRetriever.java +++ b/module-domain/src/main/java/com/mile/moim/service/MoimRetriever.java @@ -6,7 +6,7 @@ import com.mile.moim.domain.Moim; import com.mile.moim.repository.MoimRepository; import com.mile.moim.service.dto.response.MoimInfoResponse; -import com.mile.moim.service.lock.AtomicValidateUniqueMoimName; +import com.mile.common.lock.AtomicValidateUniqueMoimName; import com.mile.user.domain.User; import com.mile.common.utils.DateUtil; import com.mile.writername.domain.WriterName; diff --git a/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoRegister.java b/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoRegister.java index c2a18ac0..93f447ad 100644 --- a/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoRegister.java +++ b/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoRegister.java @@ -1,5 +1,6 @@ package com.mile.moim.service.popular; +import com.mile.common.lock.DistributedLock; import com.mile.curious.repository.dto.PostAndCuriousCountInLastWeek; import com.mile.curious.service.CuriousRetriever; import com.mile.moim.domain.Moim; @@ -7,7 +8,6 @@ import com.mile.moim.domain.popular.MoimCuriousWriter; import com.mile.moim.domain.popular.MoimPopularInfo; import com.mile.moim.repository.MoimPopularInfoRepository; -import com.mile.moim.service.lock.AtomicMoimPopulerInfo; import com.mile.writername.domain.WriterName; import lombok.RequiredArgsConstructor; import org.springframework.cache.annotation.CachePut; @@ -25,6 +25,7 @@ public class MoimPopularInfoRegister { private final MoimPopularInfoRepository moimPopularInfoRepository; private final CuriousRetriever curiousRetriever; + private final DistributedLock distributedLock; private Set getMoimCuriousPost(final List mostCuriousPostsInLastWeek) { @@ -46,6 +47,8 @@ private Set getMoimCuriousWriter(final List mostCuriousPostsInLastWeek = curiousRetriever.findMostCuriousPostsInLastWeek(moim); Set moimCuriousPosts = getMoimCuriousPost(mostCuriousPostsInLastWeek); @@ -54,7 +57,11 @@ public MoimPopularInfo setMostPopularInfoOfMoim(final Moim moim) { MoimPopularInfo moimPopularInfo = MoimPopularInfo.of(moim.getId(), moimCuriousPosts, moimCuriousWriters); - return moimPopularInfoRepository.saveAndFlush(moimPopularInfo); + moimPopularInfoRepository.saveAndFlush(moimPopularInfo); + + distributedLock.afterLock("MOIM_POPULAR_LOCK"); + + return moimPopularInfo; } } diff --git a/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoService.java b/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoService.java index 90943c76..648775ea 100644 --- a/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoService.java +++ b/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoService.java @@ -4,7 +4,6 @@ import com.mile.moim.domain.Moim; import com.mile.moim.domain.popular.MoimPopularInfo; import com.mile.moim.repository.MoimPopularInfoRepository; -import com.mile.moim.service.lock.AtomicMoimPopulerInfo; import com.mile.slack.module.SendMessageModule; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; @@ -22,7 +21,6 @@ public class MoimPopularInfoService { @Cacheable(value = "moimPopularInfo", key = "#moim.id") - @AtomicMoimPopulerInfo public MoimPopularInfo getMoimPopularInfo(final Moim moim) { return moimPopularInfoRepository.findByMoimId(moim.getId()).orElseGet( () -> moimPopularInfoRegister.setMostPopularInfoOfMoim(moim) From d4fdb5548e31ab7b2756ade857d70ca3820c6cfc Mon Sep 17 00:00:00 2001 From: sohyundoh Date: Sun, 17 Nov 2024 14:41:58 +0900 Subject: [PATCH 04/11] =?UTF-8?q?#578=20[feat]=20=EC=8A=AC=EB=9E=99=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=EC=A0=84=EC=86=A1=20=EB=AA=A8=EB=93=88=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mile/slack/module/SendErrorModule.java | 55 +++++++++++++++++++ .../mile/slack/module/SendMessageModule.java | 2 +- .../mile/slack/module/SendWebhookMessage.java | 12 ++-- 3 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 module-external/src/main/java/com/mile/slack/module/SendErrorModule.java diff --git a/module-external/src/main/java/com/mile/slack/module/SendErrorModule.java b/module-external/src/main/java/com/mile/slack/module/SendErrorModule.java new file mode 100644 index 00000000..162fffca --- /dev/null +++ b/module-external/src/main/java/com/mile/slack/module/SendErrorModule.java @@ -0,0 +1,55 @@ +package com.mile.slack.module; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.MDC; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; +import org.springframework.lang.NonNull; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.client.WebClient; + +@Slf4j +@Component +public class SendErrorModule extends SendWebhookMessage { + private final StringBuilder sb = new StringBuilder(); + + @Value("${webhook.url-for-error}") + private String webHookUri; + + @Override + public void sendError(@NonNull final Exception exception) { + WebClient webClient = WebClient.builder() + .baseUrl(webHookUri).build(); + + + webClient.post() + .contentType(MediaType.APPLICATION_JSON) + .bodyValue(generateMessage(exception)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(String.class) + .doOnError(e -> log.error("WEB HOOK 전송 중 에러 발생 -> {}", e.getMessage())) + .subscribe(); + } + + + private String readRootStackTrace(Exception error) { + return error.getStackTrace()[0].toString(); + } + + private SendErrorModule.SlackMessage generateMessage(final Exception exception) { + sb.append("🚨 ERROR").append("\n").append("\n").append(exception.toString()).append("\n"); + sb.append("REQUEST ID").append("\n").append("\n").append(MDC.get("request_id")).append("\n"); + sb.append("DETAILS").append("\n").append("\n").append(readRootStackTrace(exception)).append("\n"); + + return new SendErrorModule.SlackMessage(sb.toString()); + } + + @Getter + @AllArgsConstructor + private class SlackMessage { + private String text; + } +} diff --git a/module-external/src/main/java/com/mile/slack/module/SendMessageModule.java b/module-external/src/main/java/com/mile/slack/module/SendMessageModule.java index 6b8b2e4d..7f2f4f8f 100644 --- a/module-external/src/main/java/com/mile/slack/module/SendMessageModule.java +++ b/module-external/src/main/java/com/mile/slack/module/SendMessageModule.java @@ -16,7 +16,7 @@ @Component @Slf4j -public class SendMessageModule implements SendWebhookMessage { +public class SendMessageModule extends SendWebhookMessage { private final StringBuilder sb = new StringBuilder(); @Value("${webhook.url-for-event}") diff --git a/module-external/src/main/java/com/mile/slack/module/SendWebhookMessage.java b/module-external/src/main/java/com/mile/slack/module/SendWebhookMessage.java index ae4f1e2e..f227c1dd 100644 --- a/module-external/src/main/java/com/mile/slack/module/SendWebhookMessage.java +++ b/module-external/src/main/java/com/mile/slack/module/SendWebhookMessage.java @@ -1,8 +1,10 @@ package com.mile.slack.module; -import org.springframework.lang.NonNull; - -public interface SendWebhookMessage { - void sendMessage(@NonNull final String message); - +public abstract class SendWebhookMessage { + void sendMessage(String message) { + // TODO() - 상속받아 구현하기 + } + void sendError(Exception exception){ + // TODO() - 상속받아 구현하기 + } } From 824ccb3eb7fac46f3004d4f6dd445e50a3fc5ab5 Mon Sep 17 00:00:00 2001 From: sohyundoh Date: Sun, 17 Nov 2024 14:47:19 +0900 Subject: [PATCH 05/11] =?UTF-8?q?#578=20[feat]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=A0=84=EC=86=A1=20=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/mile/slack/module/SendErrorModule.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/module-external/src/main/java/com/mile/slack/module/SendErrorModule.java b/module-external/src/main/java/com/mile/slack/module/SendErrorModule.java index 162fffca..3f1fa6e9 100644 --- a/module-external/src/main/java/com/mile/slack/module/SendErrorModule.java +++ b/module-external/src/main/java/com/mile/slack/module/SendErrorModule.java @@ -5,6 +5,7 @@ import lombok.extern.slf4j.Slf4j; import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; import org.springframework.http.MediaType; import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; @@ -18,6 +19,9 @@ public class SendErrorModule extends SendWebhookMessage { @Value("${webhook.url-for-error}") private String webHookUri; + @Value("${spring.profiles.active}") + private String profile; + @Override public void sendError(@NonNull final Exception exception) { WebClient webClient = WebClient.builder() @@ -41,6 +45,7 @@ private String readRootStackTrace(Exception error) { private SendErrorModule.SlackMessage generateMessage(final Exception exception) { sb.append("🚨 ERROR").append("\n").append("\n").append(exception.toString()).append("\n"); + sb.append("PROFILE").append("\n").append("\n").append(profile).append("\n"); sb.append("REQUEST ID").append("\n").append("\n").append(MDC.get("request_id")).append("\n"); sb.append("DETAILS").append("\n").append("\n").append(readRootStackTrace(exception)).append("\n"); From 65b20cda1554c470e6d77b4e39513babc2a1cc5c Mon Sep 17 00:00:00 2001 From: sohyundoh Date: Sun, 17 Nov 2024 14:54:29 +0900 Subject: [PATCH 06/11] =?UTF-8?q?#578=20[feat]=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=EC=8B=9C=20=EC=A0=84=EC=86=A1=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handler/GlobalExceptionHandler.java | 19 +++++++++---------- .../mile/slack/module/SendErrorModule.java | 15 +++++++-------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/module-api/src/main/java/com/mile/exception/handler/GlobalExceptionHandler.java b/module-api/src/main/java/com/mile/exception/handler/GlobalExceptionHandler.java index 5ac7ab7c..cedb19f4 100644 --- a/module-api/src/main/java/com/mile/exception/handler/GlobalExceptionHandler.java +++ b/module-api/src/main/java/com/mile/exception/handler/GlobalExceptionHandler.java @@ -9,6 +9,7 @@ import com.mile.exception.model.NotFoundException; import com.mile.exception.model.TooManyRequestException; import com.mile.exception.model.UnauthorizedException; +import com.mile.slack.module.SendErrorModule; import io.sentry.Sentry; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; @@ -31,22 +32,25 @@ public class GlobalExceptionHandler { private static final int INDEX_ZERO = 0; + private final SendErrorModule sendErrorModule; + + public GlobalExceptionHandler(SendErrorModule sendErrorModule) { + this.sendErrorModule = sendErrorModule; + } @ExceptionHandler(HttpMessageNotReadableException.class) public ResponseEntity handleHttpMessageNotReadableException(final HttpMessageNotReadableException e) { - Sentry.captureException(e); + ; return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorResponse.of(ErrorMessage.ENUM_VALUE_BAD_REQUEST)); } @ExceptionHandler(HandlerMethodValidationException.class) public ResponseEntity handleHandlerMethodValidationException(final HandlerMethodValidationException e) { - Sentry.captureException(e); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorResponse.of(HttpStatus.BAD_REQUEST.value(), Objects.requireNonNull(e.getAllValidationResults().get(INDEX_ZERO).getResolvableErrors().get(INDEX_ZERO).getDefaultMessage()))); } @ExceptionHandler(MethodArgumentTypeMismatchException.class) public ResponseEntity handleMethodArgumentTypeMismatchException(final MethodArgumentTypeMismatchException e) { - Sentry.captureException(e); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorResponse.of(ErrorMessage.REQUEST_URL_WRONG_ERROR)); } @@ -58,13 +62,11 @@ public ResponseEntity handleBadRequestException(final BadRequestE @ExceptionHandler(UnauthorizedException.class) public ResponseEntity handleUnauthorizedException(final UnauthorizedException e) { - Sentry.captureException(e); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(ErrorResponse.of(e.getErrorMessage())); } @ExceptionHandler(JwtValidationException.class) public ResponseEntity handleJwtValidationException(final JwtValidationException e) { - Sentry.captureException(e); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(ErrorResponse.of(e.getErrorMessage())); } @@ -92,25 +94,21 @@ protected ResponseEntity handleMethodArgumentNotValidException(fi @ExceptionHandler(ForbiddenException.class) public ResponseEntity handleForbiddenException(final ForbiddenException e) { - Sentry.captureException(e); return ResponseEntity.status(HttpStatus.FORBIDDEN).body(ErrorResponse.of(e.getErrorMessage())); } @ExceptionHandler(NotFoundException.class) public ResponseEntity handleNotFoundException(final NotFoundException e) { - Sentry.captureException(e); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ErrorResponse.of(e.getErrorMessage())); } @ExceptionHandler(ConflictException.class) public ResponseEntity handleConflictException(final ConflictException e) { - Sentry.captureException(e); return ResponseEntity.status(HttpStatus.CONFLICT).body(ErrorResponse.of(e.getErrorMessage())); } @ExceptionHandler(TooManyRequestException.class) public ResponseEntity handleTooManyRequestException(final TooManyRequestException e) { - Sentry.captureException(e); return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).body(ErrorResponse.of(e.getErrorMessage())); } @@ -121,7 +119,8 @@ public ResponseEntity handleNoHandlerFoundException(final NoHandl @ExceptionHandler(Exception.class) protected ResponseEntity handleException(final Exception error, final HttpServletRequest request) { - Sentry.captureException(error); + sendErrorModule.sendError(error); + log.error("================================================NEW==============================================="); log.error(error.getMessage(), error); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ErrorResponse.of(ErrorMessage.INTERNAL_SERVER_ERROR)); diff --git a/module-external/src/main/java/com/mile/slack/module/SendErrorModule.java b/module-external/src/main/java/com/mile/slack/module/SendErrorModule.java index 3f1fa6e9..4af0269c 100644 --- a/module-external/src/main/java/com/mile/slack/module/SendErrorModule.java +++ b/module-external/src/main/java/com/mile/slack/module/SendErrorModule.java @@ -5,7 +5,6 @@ import lombok.extern.slf4j.Slf4j; import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.env.Environment; import org.springframework.http.MediaType; import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; @@ -43,18 +42,18 @@ private String readRootStackTrace(Exception error) { return error.getStackTrace()[0].toString(); } - private SendErrorModule.SlackMessage generateMessage(final Exception exception) { - sb.append("🚨 ERROR").append("\n").append("\n").append(exception.toString()).append("\n"); - sb.append("PROFILE").append("\n").append("\n").append(profile).append("\n"); - sb.append("REQUEST ID").append("\n").append("\n").append(MDC.get("request_id")).append("\n"); - sb.append("DETAILS").append("\n").append("\n").append(readRootStackTrace(exception)).append("\n"); + private Message generateMessage(final Exception exception) { + sb.append("🚨 ERROR🚨").append("\n").append(exception.toString()).append("\n").append("\n"); + sb.append("🏃🏻PROFILE🏃🏻").append("\n").append(profile).append("\n").append("\n"); + sb.append("🆔REQUEST ID🆔").append("\n").append(MDC.get("request_id")).append("\n").append("\n"); + sb.append("️✏️DETAILS✏️").append("\n").append(readRootStackTrace(exception)).append("\n"); - return new SendErrorModule.SlackMessage(sb.toString()); + return new Message(sb.toString()); } @Getter @AllArgsConstructor - private class SlackMessage { + private class Message { private String text; } } From c0820beacb9157c7e80440d3073f23ee555f693a Mon Sep 17 00:00:00 2001 From: sohyundoh Date: Sun, 17 Nov 2024 14:59:37 +0900 Subject: [PATCH 07/11] =?UTF-8?q?#578=20[feat]=20=EC=BA=90=EC=8B=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=EC=8B=9C=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=ED=8F=AC=EB=A7=B7=20=EB=8B=A8=EC=88=9C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module-domain/src/main/java/com/mile/common/CacheService.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/module-domain/src/main/java/com/mile/common/CacheService.java b/module-domain/src/main/java/com/mile/common/CacheService.java index 7bce197e..5f6463e6 100644 --- a/module-domain/src/main/java/com/mile/common/CacheService.java +++ b/module-domain/src/main/java/com/mile/common/CacheService.java @@ -1,6 +1,5 @@ package com.mile.common; -import com.mile.slack.module.SendMessageModule; import lombok.RequiredArgsConstructor; import org.springframework.cache.CacheManager; import org.springframework.stereotype.Service; @@ -11,10 +10,8 @@ public class CacheService { private final String MOIM_CACHE_NAME = "moimPopularInfo"; private final CacheManager cacheManager; - private final SendMessageModule sendMessageModule; public void deleteMoimCache() { - sendMessageModule.sendMessage("INTERNAL API 호출) 글모임 별 인기 글/ 작가에 대한 캐시 삭제 완료"); if (cacheManager.getCache(MOIM_CACHE_NAME) != null) { cacheManager.getCache(MOIM_CACHE_NAME).clear(); } From d39385a71fb4ddba901d2fb1c28c964241a27e8c Mon Sep 17 00:00:00 2001 From: sohyundoh Date: Sat, 30 Nov 2024 16:45:14 +0900 Subject: [PATCH 08/11] =?UTF-8?q?#580=20[feat]=20=EB=A6=AC=ED=94=84?= =?UTF-8?q?=EB=A0=88=EC=8B=9C=20=ED=86=A0=ED=81=B0=20=EB=A7=8C=EB=A3=8C?= =?UTF-8?q?=EC=8B=9C=20500=20=EC=97=90=EB=9F=AC=20=EC=95=84=EB=8B=8C=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=ED=83=80=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/mile/common/auth/JwtTokenProvider.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/module-api/src/main/java/com/mile/common/auth/JwtTokenProvider.java b/module-api/src/main/java/com/mile/common/auth/JwtTokenProvider.java index bc43a43b..535ee64f 100644 --- a/module-api/src/main/java/com/mile/common/auth/JwtTokenProvider.java +++ b/module-api/src/main/java/com/mile/common/auth/JwtTokenProvider.java @@ -123,6 +123,10 @@ public HashMap getJoinedRoleFromHeader(final String token) } public HashMap getJoinedRoleFromJwt(final String token) { + + if(!validateToken(token).equals(JwtValidationType.VALID_JWT)) { + throw new UnauthorizedException(ErrorMessage.TOKEN_INCORRECT_ERROR); + } Claims claims = getBody(token); Object joinedRole = claims.get(JOINED_ROLE); HashMap roleMap = objectMapper.convertValue(joinedRole, new TypeReference>() {}); From 9cd12fe1dcc5443e4aa75f3ed071280e94c216f7 Mon Sep 17 00:00:00 2001 From: sohyundoh Date: Sat, 30 Nov 2024 16:55:40 +0900 Subject: [PATCH 09/11] =?UTF-8?q?#580=20[feat]=20AuthFacade=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/mile/common/auth/JwtTokenProvider.java | 4 ---- .../java/com/mile/controller/user/facade/AuthFacade.java | 8 +++++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/module-api/src/main/java/com/mile/common/auth/JwtTokenProvider.java b/module-api/src/main/java/com/mile/common/auth/JwtTokenProvider.java index 535ee64f..bc43a43b 100644 --- a/module-api/src/main/java/com/mile/common/auth/JwtTokenProvider.java +++ b/module-api/src/main/java/com/mile/common/auth/JwtTokenProvider.java @@ -123,10 +123,6 @@ public HashMap getJoinedRoleFromHeader(final String token) } public HashMap getJoinedRoleFromJwt(final String token) { - - if(!validateToken(token).equals(JwtValidationType.VALID_JWT)) { - throw new UnauthorizedException(ErrorMessage.TOKEN_INCORRECT_ERROR); - } Claims claims = getBody(token); Object joinedRole = claims.get(JOINED_ROLE); HashMap roleMap = objectMapper.convertValue(joinedRole, new TypeReference>() {}); diff --git a/module-api/src/main/java/com/mile/controller/user/facade/AuthFacade.java b/module-api/src/main/java/com/mile/controller/user/facade/AuthFacade.java index bcdfe959..f994710a 100644 --- a/module-api/src/main/java/com/mile/controller/user/facade/AuthFacade.java +++ b/module-api/src/main/java/com/mile/controller/user/facade/AuthFacade.java @@ -4,7 +4,9 @@ import com.mile.client.SocialType; import com.mile.client.dto.UserLoginRequest; import com.mile.common.auth.JwtTokenProvider; -import com.mile.writername.domain.MoimRole; +import com.mile.common.auth.JwtValidationType; +import com.mile.exception.message.ErrorMessage; +import com.mile.exception.model.UnauthorizedException; import com.mile.jwt.service.TokenService; import com.mile.moim.service.dto.response.MoimListOfUserResponse; import com.mile.strategy.LoginStrategyManager; @@ -34,6 +36,10 @@ public AccessTokenGetSuccess refreshToken( final String refreshToken ) { final Long userId = tokenService.findIdByRefreshToken(refreshToken); + + if(jwtTokenProvider.validateToken(refreshToken).equals(JwtValidationType.VALID_JWT)) { + throw new UnauthorizedException(ErrorMessage.TOKEN_INCORRECT_ERROR); + } final Map role = jwtTokenProvider.getJoinedRoleFromJwt(refreshToken); return AccessTokenGetSuccess.of( From b97c90e9dd46cfcc0d3b7b5c661b3ecb24896fd0 Mon Sep 17 00:00:00 2001 From: sohyundoh Date: Sat, 30 Nov 2024 17:10:14 +0900 Subject: [PATCH 10/11] =?UTF-8?q?#581=20[feat]=20=EA=B8=80=EB=AA=A8?= =?UTF-8?q?=EC=9E=84=20=EC=A0=95=EB=B3=B4=20=EB=B0=9B=EC=95=84=EC=98=AC=20?= =?UTF-8?q?=EC=8B=9C=20=EB=B6=84=EC=82=B0=EB=9D=BD=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mile/moim/service/popular/MoimPopularInfoRegister.java | 1 - .../mile/moim/service/popular/MoimPopularInfoService.java | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoRegister.java b/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoRegister.java index 93f447ad..c26dd010 100644 --- a/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoRegister.java +++ b/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoRegister.java @@ -47,7 +47,6 @@ private Set getMoimCuriousWriter(final List mostCuriousPostsInLastWeek = curiousRetriever.findMostCuriousPostsInLastWeek(moim); diff --git a/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoService.java b/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoService.java index 648775ea..694bb6a5 100644 --- a/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoService.java +++ b/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoService.java @@ -1,6 +1,7 @@ package com.mile.moim.service.popular; import com.mile.common.CacheService; +import com.mile.common.lock.DistributedLock; import com.mile.moim.domain.Moim; import com.mile.moim.domain.popular.MoimPopularInfo; import com.mile.moim.repository.MoimPopularInfoRepository; @@ -17,13 +18,17 @@ public class MoimPopularInfoService { private final MoimPopularInfoRepository moimPopularInfoRepository; private final MoimPopularInfoRegister moimPopularInfoRegister; private final SendMessageModule sendMessageModule; + private final DistributedLock distributedLock; private final CacheService cacheService; @Cacheable(value = "moimPopularInfo", key = "#moim.id") public MoimPopularInfo getMoimPopularInfo(final Moim moim) { return moimPopularInfoRepository.findByMoimId(moim.getId()).orElseGet( - () -> moimPopularInfoRegister.setMostPopularInfoOfMoim(moim) + () -> { + distributedLock.getLock("MOIM_POPULAR_LOCK"); + return moimPopularInfoRegister.setMostPopularInfoOfMoim(moim); + } ); } From 8a0da6b492e8e4a7be71201e52cc6ce35921f5f2 Mon Sep 17 00:00:00 2001 From: sohyundoh Date: Sat, 30 Nov 2024 17:12:54 +0900 Subject: [PATCH 11/11] =?UTF-8?q?#581=20[feat]=20=EB=9D=BD=20=ED=82=A4=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mile/moim/service/popular/MoimPopularInfoRegister.java | 2 +- .../com/mile/moim/service/popular/MoimPopularInfoService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoRegister.java b/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoRegister.java index c26dd010..880718bb 100644 --- a/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoRegister.java +++ b/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoRegister.java @@ -58,7 +58,7 @@ public MoimPopularInfo setMostPopularInfoOfMoim(final Moim moim) { moimPopularInfoRepository.saveAndFlush(moimPopularInfo); - distributedLock.afterLock("MOIM_POPULAR_LOCK"); + distributedLock.afterLock("MOIM_POPULAR_LOCK" + moim.getId()); return moimPopularInfo; } diff --git a/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoService.java b/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoService.java index 694bb6a5..4b4c517a 100644 --- a/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoService.java +++ b/module-domain/src/main/java/com/mile/moim/service/popular/MoimPopularInfoService.java @@ -26,7 +26,7 @@ public class MoimPopularInfoService { public MoimPopularInfo getMoimPopularInfo(final Moim moim) { return moimPopularInfoRepository.findByMoimId(moim.getId()).orElseGet( () -> { - distributedLock.getLock("MOIM_POPULAR_LOCK"); + distributedLock.getLock("MOIM_POPULAR_LOCK" + moim.getId()); return moimPopularInfoRegister.setMostPopularInfoOfMoim(moim); } );