diff --git a/src/main/java/umc/th/juinjang/JuinjangApplication.java b/src/main/java/umc/th/juinjang/JuinjangApplication.java index dbc1f8ae..e174c7c2 100644 --- a/src/main/java/umc/th/juinjang/JuinjangApplication.java +++ b/src/main/java/umc/th/juinjang/JuinjangApplication.java @@ -6,10 +6,12 @@ import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.FeignAutoConfiguration; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableJpaAuditing +@EnableAsync @ImportAutoConfiguration({FeignAutoConfiguration.class}) public class JuinjangApplication { diff --git a/src/main/java/umc/th/juinjang/event/SignUpEvent.java b/src/main/java/umc/th/juinjang/event/SignUpEvent.java new file mode 100644 index 00000000..83fb3707 --- /dev/null +++ b/src/main/java/umc/th/juinjang/event/SignUpEvent.java @@ -0,0 +1,13 @@ +package umc.th.juinjang.event; + +import umc.th.juinjang.model.entity.enums.MemberProvider; + +public record SignUpEvent( + MemberProvider memberProvider, + String name, + long count +) { + public static SignUpEvent of(MemberProvider memberProvider, String name, long count) { + return new SignUpEvent(memberProvider, name, count); + } +} diff --git a/src/main/java/umc/th/juinjang/event/publisher/ApplicationMemberEventPublisherAdapter.java b/src/main/java/umc/th/juinjang/event/publisher/ApplicationMemberEventPublisherAdapter.java new file mode 100644 index 00000000..661e4385 --- /dev/null +++ b/src/main/java/umc/th/juinjang/event/publisher/ApplicationMemberEventPublisherAdapter.java @@ -0,0 +1,19 @@ +package umc.th.juinjang.event.publisher; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Component; +import umc.th.juinjang.event.SignUpEvent; +import umc.th.juinjang.model.entity.Member; + +@RequiredArgsConstructor +@Component +public class ApplicationMemberEventPublisherAdapter implements MemberEventPublisher { + + private final ApplicationEventPublisher applicationEventPublisher; + + @Override + public void publishSignUpEvent(Member member) { + applicationEventPublisher.publishEvent(SignUpEvent.of(member.getProvider(), member.getNickname(), member.getMemberId())); + } +} diff --git a/src/main/java/umc/th/juinjang/event/publisher/MemberEventPublisher.java b/src/main/java/umc/th/juinjang/event/publisher/MemberEventPublisher.java new file mode 100644 index 00000000..cb570379 --- /dev/null +++ b/src/main/java/umc/th/juinjang/event/publisher/MemberEventPublisher.java @@ -0,0 +1,7 @@ +package umc.th.juinjang.event.publisher; + +import umc.th.juinjang.model.entity.Member; + +public interface MemberEventPublisher { + void publishSignUpEvent(Member member); +} diff --git a/src/main/java/umc/th/juinjang/event/subscriber/DiscordEventListener.java b/src/main/java/umc/th/juinjang/event/subscriber/DiscordEventListener.java new file mode 100644 index 00000000..0e33efc6 --- /dev/null +++ b/src/main/java/umc/th/juinjang/event/subscriber/DiscordEventListener.java @@ -0,0 +1,31 @@ +package umc.th.juinjang.event.subscriber; + +import lombok.RequiredArgsConstructor; +import org.springframework.core.env.Environment; +import org.springframework.core.env.Profiles; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.transaction.event.TransactionPhase; +import org.springframework.transaction.event.TransactionalEventListener; +import umc.th.juinjang.event.SignUpEvent; +import umc.th.juinjang.external.discord.DiscordAlertProvider; + +@Component +@RequiredArgsConstructor +public class DiscordEventListener { + + private final DiscordAlertProvider discordAlertProvider; + private final Environment environment; + + @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) + @Async + public void handleSignUpEvent (SignUpEvent event){ + if (isProdEnv()) { + discordAlertProvider.sendAlertToDiscord(String.format(EventMessage.SIGN_UP_MESSAGE.getMessage(), event.memberProvider(), event.count(), event.name())); + } + } + + private boolean isProdEnv() { + return environment.acceptsProfiles(Profiles.of("prod")); + } +} diff --git a/src/main/java/umc/th/juinjang/event/subscriber/EventMessage.java b/src/main/java/umc/th/juinjang/event/subscriber/EventMessage.java new file mode 100644 index 00000000..ebc8e988 --- /dev/null +++ b/src/main/java/umc/th/juinjang/event/subscriber/EventMessage.java @@ -0,0 +1,13 @@ +package umc.th.juinjang.event.subscriber; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +@Getter +public enum EventMessage { + SIGN_UP_MESSAGE("주인장에 %s %d번째 유저 < %s >님이 생겼어요!"); + + private final String message; +} diff --git a/src/main/java/umc/th/juinjang/external/discord/DiscordAlertProvider.java b/src/main/java/umc/th/juinjang/external/discord/DiscordAlertProvider.java index c2cc2531..5e8c455b 100644 --- a/src/main/java/umc/th/juinjang/external/discord/DiscordAlertProvider.java +++ b/src/main/java/umc/th/juinjang/external/discord/DiscordAlertProvider.java @@ -1,14 +1,10 @@ package umc.th.juinjang.external.discord; import feign.FeignException; -import java.util.Arrays; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; -import umc.th.juinjang.apiPayload.code.status.ErrorStatus; import umc.th.juinjang.external.discord.dto.DiscordAlert; -import umc.th.juinjang.model.entity.Member; @RequiredArgsConstructor @Component @@ -16,19 +12,12 @@ public class DiscordAlertProvider { private final DiscordFeignClient discordFeignClient; - private final Environment environment; - public void sendAlert(Member member) { - if (Arrays.asList(environment.getActiveProfiles()).contains("prod")) { - sendAlertToDiscord(DiscordAlert.createAlert(member.getMemberId(), member.getProvider(), member.getNickname())); - } - } - - private void sendAlertToDiscord(DiscordAlert discordAlert) { + public void sendAlertToDiscord(String content) { try { - discordFeignClient.sendAlert(discordAlert); + discordFeignClient.sendAlert(DiscordAlert.createAlert(content)); } catch (FeignException e) { - log.info(ErrorStatus.DISCORD_ALERT_ERROR.getMessage()+ " " +e.getMessage()); + log.info(StatusMessage.DISCORD_ALERT_ERROR.getMessage()+ " " +e.getMessage()); } } } \ No newline at end of file diff --git a/src/main/java/umc/th/juinjang/external/discord/StatusMessage.java b/src/main/java/umc/th/juinjang/external/discord/StatusMessage.java new file mode 100644 index 00000000..26f98c86 --- /dev/null +++ b/src/main/java/umc/th/juinjang/external/discord/StatusMessage.java @@ -0,0 +1,14 @@ +package umc.th.juinjang.external.discord; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public enum StatusMessage { + DISCORD_ALERT_ERROR("discord 알림 수신 중 오류가 발생했습니다."), + DISCORD_ALERT_SUCCESS("discord 알림 수신 성공했습니다."); + + private final String message; +} diff --git a/src/main/java/umc/th/juinjang/external/discord/dto/DiscordAlert.java b/src/main/java/umc/th/juinjang/external/discord/dto/DiscordAlert.java index d7d80a73..842aa6d4 100644 --- a/src/main/java/umc/th/juinjang/external/discord/dto/DiscordAlert.java +++ b/src/main/java/umc/th/juinjang/external/discord/dto/DiscordAlert.java @@ -1,9 +1,7 @@ package umc.th.juinjang.external.discord.dto; -import umc.th.juinjang.model.entity.enums.MemberProvider; - public record DiscordAlert(String content) { - public static DiscordAlert createAlert(Long id, MemberProvider memberProvider, String nickname) { - return new DiscordAlert("주인장에 " +memberProvider+" "+id+"번째 유저 < "+nickname+" >님이 생겼어요!"); + public static DiscordAlert createAlert(String content) { + return new DiscordAlert(content); } } \ No newline at end of file diff --git a/src/main/java/umc/th/juinjang/service/auth/OAuthService.java b/src/main/java/umc/th/juinjang/service/auth/OAuthService.java index 72c5dcf3..8dba7165 100644 --- a/src/main/java/umc/th/juinjang/service/auth/OAuthService.java +++ b/src/main/java/umc/th/juinjang/service/auth/OAuthService.java @@ -10,7 +10,7 @@ import umc.th.juinjang.apiPayload.ExceptionHandler; import umc.th.juinjang.apiPayload.exception.handler.MemberHandler; import umc.th.juinjang.controller.KakaoUnlinkClient; -import umc.th.juinjang.external.discord.DiscordAlertProvider; +import umc.th.juinjang.event.publisher.MemberEventPublisher; import umc.th.juinjang.model.dto.auth.LoginResponseDto; import umc.th.juinjang.model.dto.auth.TokenDto; import umc.th.juinjang.model.dto.auth.apple.*; @@ -50,7 +50,6 @@ public class OAuthService { private final JwtService jwtService; private final AppleClientSecretGenerator appleClientSecretGenerator; private final AppleOAuthProvider appleOAuthProvider; - private final DiscordAlertProvider discordAlertProvider; private final ScrapRepository scrapRepository; private final LimjangRepository limjangRepository; private final ChecklistAnswerRepository checklistAnswerRepository; @@ -59,6 +58,7 @@ public class OAuthService { private final ReportRepository reportRepository; private final S3Service s3Service; private final LimjangPriceRepository limjangPriceRepository; + private final MemberEventPublisher memberEventPublisher; @Autowired private KakaoUnlinkClient kakaoUnlinkClient; @@ -151,10 +151,14 @@ public LoginResponseDto kakaoSignUp (Long targetId, KakaoSignUpRequestDto kakaoS } // accessToken, refreshToken 발급 후 반환 - discordAlertProvider.sendAlert(member); + publishDiscordAlert(member); return createToken(member); } + private void publishDiscordAlert(Member member) { + memberEventPublisher.publishSignUpEvent(member); + } + // accessToken, refreshToken 발급 @Transactional public LoginResponseDto createToken(Member member) { @@ -300,7 +304,7 @@ public LoginResponseDto appleSignUp(AppleSignUpRequestDto appleSignUpRequestDto) if(member == null) throw new MemberHandler(FAILED_TO_LOGIN); - discordAlertProvider.sendAlert(member); + publishDiscordAlert(member); return createToken(member); }