Skip to content

Commit 9dbefcd

Browse files
authored
Merge pull request #84 from Modagbul/fix/auth
Slack 알림 EventPublisher로 수정
2 parents be08efa + 27495f2 commit 9dbefcd

File tree

10 files changed

+114
-25
lines changed

10 files changed

+114
-25
lines changed

src/main/java/com/moing/backend/domain/team/application/service/CreateTeamUserCase.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
import com.moing.backend.domain.teamMember.domain.service.TeamMemberSaveService;
1111
import com.moing.backend.domain.teamScore.application.mapper.TeamScoreMapper;
1212
import com.moing.backend.domain.teamScore.domain.service.TeamScoreSaveService;
13-
import com.moing.backend.global.util.SlackService;
13+
import com.moing.backend.global.config.slack.team.dto.TeamCreateEvent;
1414
import lombok.RequiredArgsConstructor;
15+
import org.springframework.context.ApplicationEventPublisher;
1516
import org.springframework.stereotype.Service;
1617

1718
import javax.transaction.Transactional;
@@ -27,7 +28,7 @@ public class CreateTeamUserCase {
2728
private final TeamMapper teamMapper;
2829
private final TeamScoreSaveService teamScoreSaveService;
2930
private final TeamScoreMapper teamScoreMapper;
30-
private final SlackService slackService;
31+
private final ApplicationEventPublisher eventPublisher;
3132

3233
public CreateTeamResponse createTeam(CreateTeamRequest createTeamRequest, String socialId){
3334
Member member = memberGetService.getMemberBySocialId(socialId);
@@ -38,7 +39,7 @@ public CreateTeamResponse createTeam(CreateTeamRequest createTeamRequest, String
3839
team.approveTeam();
3940
//====지워야 함 (테스트 용)=====
4041
teamScoreSaveService.save(teamScoreMapper.mapToTeamScore(team)); // 팀스코어 엔티티 생성
41-
slackService.sendSlackTeamCreatedMessage(team.getName(), team.getLeaderId());
42+
eventPublisher.publishEvent(new TeamCreateEvent(team.getName(), team.getLeaderId()));
4243
return new CreateTeamResponse(team.getTeamId());
4344
}
4445
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.moing.backend.global.config.slack;
2+
3+
import com.slack.api.Slack;
4+
import org.springframework.context.annotation.Bean;
5+
import org.springframework.context.annotation.Configuration;
6+
7+
@Configuration
8+
public class SlackConfig {
9+
10+
@Bean
11+
public Slack slackClient() {
12+
return Slack.getInstance();
13+
}
14+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.moing.backend.global.config.slack.exception;
2+
3+
import com.moing.backend.global.config.slack.exception.dto.ExceptionEvent;
4+
import com.moing.backend.global.config.slack.util.WebhookUtil;
5+
import lombok.RequiredArgsConstructor;
6+
import org.springframework.context.event.EventListener;
7+
import org.springframework.scheduling.annotation.Async;
8+
import org.springframework.stereotype.Component;
9+
10+
@RequiredArgsConstructor
11+
@Component
12+
public class ExceptionEventHandler {
13+
14+
private final WebhookUtil webhookUtil;
15+
16+
@Async("asyncTaskExecutor")
17+
@EventListener
18+
public void onExceptionEvent(ExceptionEvent event) {
19+
webhookUtil.sendSlackAlertErrorLog(event.getRequest(), event.getException());
20+
}
21+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.moing.backend.global.config.slack.exception.dto;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Getter;
5+
6+
import javax.servlet.http.HttpServletRequest;
7+
8+
@Getter
9+
@AllArgsConstructor
10+
public class ExceptionEvent {
11+
12+
private final HttpServletRequest request;
13+
private final Exception exception;
14+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.moing.backend.global.config.slack.team;
2+
3+
import com.moing.backend.global.config.slack.team.dto.TeamCreateEvent;
4+
import com.moing.backend.global.config.slack.util.WebhookUtil;
5+
import lombok.RequiredArgsConstructor;
6+
import org.springframework.scheduling.annotation.Async;
7+
import org.springframework.stereotype.Component;
8+
import org.springframework.transaction.event.TransactionPhase;
9+
import org.springframework.transaction.event.TransactionalEventListener;
10+
11+
@RequiredArgsConstructor
12+
@Component
13+
public class TeamCreateHandler {
14+
15+
private final WebhookUtil webhookUtil;
16+
17+
@Async("asyncTaskExecutor")
18+
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
19+
public void onTeamCreateEvent(TeamCreateEvent event) {
20+
webhookUtil.sendSlackTeamCreatedMessage(event.getTeamName(), event.getLeaderId());
21+
}
22+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.moing.backend.global.config.slack.team.dto;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Getter;
5+
6+
@Getter
7+
@AllArgsConstructor
8+
public class TeamCreateEvent {
9+
10+
private final String teamName;
11+
private final Long leaderId;
12+
13+
}

src/main/java/com/moing/backend/global/util/SlackService.java renamed to src/main/java/com/moing/backend/global/config/slack/util/SlackAdapter.java

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
package com.moing.backend.global.util;
1+
package com.moing.backend.global.config.slack.util;
22

33
import com.slack.api.Slack;
44
import com.slack.api.model.Attachment;
55
import com.slack.api.model.Field;
6+
import lombok.RequiredArgsConstructor;
67
import lombok.extern.slf4j.Slf4j;
78
import org.springframework.beans.factory.annotation.Value;
8-
import org.springframework.scheduling.annotation.Async;
99
import org.springframework.stereotype.Component;
10-
import org.springframework.stereotype.Service;
1110

1211
import javax.servlet.http.HttpServletRequest;
1312
import java.io.IOException;
@@ -17,9 +16,10 @@
1716

1817
import static com.slack.api.webhook.WebhookPayloads.payload;
1918

20-
@Component
19+
@RequiredArgsConstructor
2120
@Slf4j
22-
public class SlackService {
21+
@Component
22+
public class SlackAdapter implements WebhookUtil {
2323

2424
@Value("${webhook.slack.error_url}")
2525
private String errorWebhookUrl;
@@ -29,8 +29,6 @@ public class SlackService {
2929

3030
private final Slack slackClient = Slack.getInstance();
3131

32-
// 공통 슬랙 메시지 전송 메서드
33-
@Async
3432
public void sendSlackMessage(String webhookUrl, String message, List<Attachment> attachments) {
3533
try {
3634
slackClient.send(webhookUrl, payload(p -> p
@@ -42,16 +40,16 @@ public void sendSlackMessage(String webhookUrl, String message, List<Attachment>
4240
}
4341
}
4442

45-
// 슬랙 에러 알림 메서드
46-
public void sendSlackAlertErrorLog(Exception e, HttpServletRequest request) {
43+
@Override
44+
public void sendSlackAlertErrorLog(HttpServletRequest request, Exception e) {
4745
String message = "[500 에러가 발생했습니다.]";
4846
List<Attachment> attachments = List.of(generateSlackErrorAttachment(e, request));
4947
sendSlackMessage(errorWebhookUrl, message, attachments);
5048
}
5149

52-
// 슬랙 소모임 생성 알림 메서드
50+
@Override
5351
public void sendSlackTeamCreatedMessage(String teamName, Long leaderId) {
54-
String message = String.format("새로운 소모임 '%s'이(가) 생성되었습니다!", teamName);
52+
String message = String.format("[새로운 소모임 '%s'이(가) 생성되었습니다.]", teamName);
5553
List<Attachment> attachments = List.of(generateSlackTeamAttachment(teamName, leaderId));
5654
sendSlackMessage(teamAlarmWebhookUrl, message, attachments);
5755
}
@@ -76,7 +74,7 @@ private Attachment generateSlackErrorAttachment(Exception e, HttpServletRequest
7674
.title(requestTime + " 발생 에러 로그")
7775
.fields(List.of(
7876
generateSlackField("Request IP", xffHeader == null ? request.getRemoteAddr() : xffHeader),
79-
generateSlackField("Request URL", request.getRequestURL() + " " + request.getMethod()),
77+
generateSlackField("Request URL", request.getMethod() + " " + request.getRequestURL()),
8078
generateSlackField("Error Message", e.getMessage())
8179
)
8280
)
@@ -90,5 +88,4 @@ private Field generateSlackField(String title, String value) {
9088
.valueShortEnough(false)
9189
.build();
9290
}
93-
94-
}
91+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.moing.backend.global.config.slack.util;
2+
3+
import javax.servlet.http.HttpServletRequest;
4+
5+
public interface WebhookUtil {
6+
7+
void sendSlackAlertErrorLog(HttpServletRequest request, Exception e);
8+
9+
void sendSlackTeamCreatedMessage(String teamName, Long leaderId);
10+
}

src/main/java/com/moing/backend/global/exception/GlobalExceptionHandler.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
package com.moing.backend.global.exception;
22

3+
import com.moing.backend.global.config.slack.exception.dto.ExceptionEvent;
34
import com.moing.backend.global.response.ErrorCode;
45
import com.moing.backend.global.response.ErrorResponse;
5-
import com.moing.backend.global.util.SlackService;
66
import lombok.RequiredArgsConstructor;
77
import lombok.extern.slf4j.Slf4j;
8+
import org.springframework.context.ApplicationEventPublisher;
9+
import org.springframework.context.support.DefaultMessageSourceResolvable;
810
import org.springframework.http.HttpStatus;
911
import org.springframework.http.ResponseEntity;
1012
import org.springframework.http.converter.HttpMessageNotReadableException;
1113
import org.springframework.web.HttpRequestMethodNotSupportedException;
1214
import org.springframework.web.bind.MethodArgumentNotValidException;
1315
import org.springframework.web.bind.annotation.ExceptionHandler;
1416
import org.springframework.web.bind.annotation.RestControllerAdvice;
15-
import org.springframework.context.support.DefaultMessageSourceResolvable;
1617

1718
import javax.servlet.http.HttpServletRequest;
1819
import java.util.function.Consumer;
@@ -25,7 +26,7 @@
2526
public class GlobalExceptionHandler {
2627

2728
private static final String LOG_FORMAT = "Class : {}, Code : {}, Message : {}";
28-
private final SlackService slackService;
29+
private final ApplicationEventPublisher eventPublisher;
2930

3031
@ExceptionHandler(ApplicationException.class)
3132
public ResponseEntity<ErrorResponse> handleApplicationException(ApplicationException ex) {
@@ -57,7 +58,7 @@ public ResponseEntity<ErrorResponse> httpRequestNotSupportedExceptionHandler(Htt
5758

5859
@ExceptionHandler(Exception.class)
5960
public ResponseEntity<ErrorResponse> internalServerErrorHandler(Exception ex, HttpServletRequest request) {
60-
slackService.sendSlackAlertErrorLog(ex, request);
61+
eventPublisher.publishEvent(new ExceptionEvent(request, ex));
6162
return handleException(ex, ErrorCode.INTERNAL_SERVER_ERROR, ErrorCode.INTERNAL_SERVER_ERROR.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR, log::error);
6263
}
6364

src/test/java/com/moing/backend/config/CommonControllerTest.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import com.moing.backend.global.config.security.filter.JwtAuthenticationEntryPoint;
99
import com.moing.backend.global.config.security.jwt.TokenUtil;
1010
import com.moing.backend.global.config.security.util.AuthenticationUtil;
11-
import com.moing.backend.global.util.SlackService;
1211
import org.junit.jupiter.api.BeforeEach;
1312
import org.junit.jupiter.api.extension.ExtendWith;
1413
import org.springframework.beans.factory.annotation.Autowired;
@@ -58,9 +57,6 @@ public class CommonControllerTest {
5857
@MockBean
5958
public MemberGetService memberQueryService;
6059

61-
@MockBean
62-
private SlackService slackService;
63-
6460
@BeforeEach
6561
public void setUp(final WebApplicationContext context, final RestDocumentationContextProvider provider) throws Exception {
6662

0 commit comments

Comments
 (0)