Skip to content

Commit

Permalink
chore: 비즈니스 예외 발생 시 슬랙 알림
Browse files Browse the repository at this point in the history
  • Loading branch information
jcw1031 committed Jan 14, 2024
1 parent 91e70d2 commit 97f4367
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 4 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'com.github.seratch:jslack:3.4.2'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testCompileOnly 'org.projectlombok:lombok'
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/ac/knu/likeknu/LikeKnuApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@EnableAsync
@SpringBootApplication
public class LikeKnuApplication {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector handlerMappingIntrospector)
throws Exception {
RequestMatcher requestMatcher = new MvcRequestMatcher(handlerMappingIntrospector, "/api/**");
return http.authorizeHttpRequests(registry -> registry.requestMatchers(requestMatcher).permitAll()
RequestMatcher apiRequestMatcher = new MvcRequestMatcher(handlerMappingIntrospector, "/api/**");
return http.authorizeHttpRequests(registry -> registry.requestMatchers(apiRequestMatcher).permitAll()
.anyRequest().authenticated())
.formLogin(security -> security.loginPage("/admin/login")
.defaultSuccessUrl("/admin/messages")
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/ac/knu/likeknu/domain/MainHeaderMessage.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ac.knu.likeknu.domain;

import ac.knu.likeknu.exception.BusinessException;
import ac.knu.likeknu.exception.ErrorMessage;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
Expand Down Expand Up @@ -31,7 +32,7 @@ protected MainHeaderMessage() {
public MainHeaderMessage(String message) {
this();
if (message.length() > 16) {
throw new BusinessException("메시지는 16자 이하이어야 합니다!");
throw new BusinessException(ErrorMessage.INVALID_MAIN_MESSAGE_SIZE);
}
this.message = message;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/ac/knu/likeknu/domain/value/RouteType.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static RouteType of(String type) {
return Arrays.stream(values())
.filter(routeType -> isSame(type, routeType))
.findAny()
.orElseThrow(() -> new BusinessException(ErrorMessage.INVALID_ROUTE_TYPE));
.orElseThrow(() -> new BusinessException(ErrorMessage.INVALID_MAIN_MESSAGE_SIZE));
}

private static boolean isSame(String type, RouteType routeType) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
package ac.knu.likeknu.exception;

import ac.knu.likeknu.service.SlackService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@Slf4j
@RestControllerAdvice
public class BusinessExceptionHandler {

private final SlackService slackService;

public BusinessExceptionHandler(SlackService slackService) {
this.slackService = slackService;
}

@ExceptionHandler(value = BusinessException.class)
protected ResponseEntity<String> businessExceptionHandler(BusinessException exception) {
String message = exception.getMessage();
log.info("sd", exception);
slackService.sendMessage(message);
return ResponseEntity.badRequest().body(message);
}
}
1 change: 1 addition & 0 deletions src/main/java/ac/knu/likeknu/exception/ErrorMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
public class ErrorMessage {

public static final String INVALID_ROUTE_TYPE = "Invalid city bus route type!";
public static final String INVALID_MAIN_MESSAGE_SIZE = "메시지는 16자 이하이어야 합니다!";
}
50 changes: 50 additions & 0 deletions src/main/java/ac/knu/likeknu/service/SlackService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package ac.knu.likeknu.service;

import com.github.seratch.jslack.Slack;
import com.github.seratch.jslack.api.model.Attachment;
import com.github.seratch.jslack.api.webhook.Payload;
import com.github.seratch.jslack.api.webhook.WebhookResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Collections;

@Slf4j
@Service
public class SlackService {

private static final String CHANNEL_NAME = "#서버-오류";

@Value("${slack.webhook}")
private String webhook;

@Async
public void sendMessage(String contents) {
String message = contents + System.lineSeparator();
Payload payload = buildPayload(message);

try {
WebhookResponse webhookResponse = Slack.getInstance()
.send(webhook, payload);
if (webhookResponse.getCode() == HttpStatus.OK.value()) {
log.info("Success send to slack!");
}
log.info(webhookResponse.getMessage());
} catch (IOException e) {
log.error("Unexpected Error! WebHook:" + webhook);
}
}

private Payload buildPayload(String message) {
return Payload.builder()
.attachments(Collections.singletonList(Attachment.builder()
.channelName(CHANNEL_NAME)
.build()))
.text(message)
.build();
}
}
2 changes: 2 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ spring.jpa.hibernate.ddl-auto=validate

admin.username=${ADMIN_USERNAME}
admin.password=${ADMIN_PASSWORD}

slack.webhook=${SLACK_WEBHOOK}

0 comments on commit 97f4367

Please sign in to comment.