Skip to content

Commit

Permalink
Merge branch 'develop' into feature/57
Browse files Browse the repository at this point in the history
  • Loading branch information
jhsseonn authored Mar 2, 2024
2 parents 6760767 + 012048c commit 322e219
Show file tree
Hide file tree
Showing 60 changed files with 1,967 additions and 167 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
.idea/
build/
HELP.md
log/warn/
log/error/

# User-specific stuff
.idea/**/workspace.xml
Expand Down
7 changes: 7 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,19 @@ dependencies {
asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'

// logging
implementation 'net.logstash.logback:logstash-logback-encoder:6.1'

// fcm
implementation 'com.google.firebase:firebase-admin:6.8.1'

// thymeleaf
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

// monitoring
implementation 'org.springframework.boot:spring-boot-starter-actuator'
runtimeOnly 'io.micrometer:micrometer-registry-prometheus'

// etc
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
Expand Down
4 changes: 4 additions & 0 deletions src/docs/asciidoc/docs.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,7 @@ include::goal.adoc[]

== 스탬프
include::stamp.adoc[]

== 콕 찌르기
include::poke.adoc[]

5 changes: 5 additions & 0 deletions src/docs/asciidoc/poke.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
=== 콕 찌르기 요청
==== 요청
operation::poke-controller-test/특정_골의_사용자에게_콕_찌르기를_한다[snippets='http-request,request-headers,path-parameters']
==== 응답
operation::poke-controller-test/특정_골의_사용자에게_콕_찌르기를_한다[snippets='http-response']
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public enum ExceptionMessage {
INVALID_EMAIL_FORMAT("이메일 형식에 어긋났습니다."),
NULL_OR_EMPTY_NAME("이름은 비어있을 수 없습니다."),
LONGER_THAN_MAXIMUM_NAME("이름의 최대 길이를 초과했습니다."),
DUPLICATE_USER_NAME("이미 존재하는 사용자 이름입니다."),

// 테마 색상
UNSUPPORTED_THEME_COLOR("지원하지 않는 테마 색상입니다."),
Expand Down Expand Up @@ -55,7 +56,12 @@ public enum ExceptionMessage {
DELETE_GOAL_FORBIDDEN("골을 삭제할 권한이 없습니다."),
UPDATE_GOAL_FORBIDDEN("골을 수정할 권한이 없습니다."),
UPDATE_TEAMS_FORBIDDEN("골 참여자 목록은 비어있을 수 없습니다."),

NOT_FOUND_MANAGER("골의 관리자를 찾을 수 없습니다."),

// 콕 찌르기
SENDER_NOT_IN_GOAL_TEAM("콕 찌르기 요청자가 해당 골의 팀원이 아닙니다."),
RECEIVER_NOT_IN_GOAL_TEAM("콕 찌르기 수신자가 해당 골의 팀원이 아닙니다."),

// 스탬프
INVALID_STAMP_DAY("스탬프 날짜는 골 시작일 이전이거나 종료일 이후일 수 없습니다."),
INVALID_STAMP_DAY_FUTURE("오늘보다 이후의 스탬프는 추가할 수 없습니다."),
Expand Down
139 changes: 103 additions & 36 deletions src/main/java/com/backend/blooming/exception/GlobalExceptionHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,20 @@
import com.backend.blooming.friend.application.exception.FriendRequestNotAllowedException;
import com.backend.blooming.friend.application.exception.NotFoundFriendRequestException;
import com.backend.blooming.goal.application.exception.DeleteGoalForbiddenException;
import com.backend.blooming.goal.application.exception.ForbiddenGoalToPokeException;
import com.backend.blooming.goal.application.exception.InvalidGoalException;
import com.backend.blooming.goal.application.exception.NotFoundGoalException;
import com.backend.blooming.goal.application.exception.ReadGoalForbiddenException;
import com.backend.blooming.goal.application.exception.UpdateGoalForbiddenException;
import com.backend.blooming.notification.application.exception.NotFoundGoalManagerException;
import com.backend.blooming.stamp.application.exception.CreateStampForbiddenException;
import com.backend.blooming.stamp.application.exception.ReadStampForbiddenException;
import com.backend.blooming.stamp.domain.exception.InvalidStampException;
import com.backend.blooming.themecolor.domain.exception.UnsupportedThemeColorException;
import com.backend.blooming.user.application.exception.DuplicateUserNameException;
import com.backend.blooming.user.application.exception.NotFoundUserException;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.MDC;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
Expand All @@ -36,8 +41,11 @@ public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
private static final int METHOD_ARGUMENT_FIRST_ERROR_INDEX = 0;

@ExceptionHandler(Exception.class)
private ResponseEntity<ExceptionResponse> handleException(Exception exception) {
logger.error(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
private ResponseEntity<ExceptionResponse> handleException(
final Exception exception,
final HttpServletRequest request
) {
logError(exception, request);

return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ExceptionResponse("예상치 못한 문제가 발생했습니다."));
Expand All @@ -62,169 +70,199 @@ protected ResponseEntity<Object> handleMethodArgumentNotValid(

@ExceptionHandler(OAuthException.InvalidAuthorizationTokenException.class)
public ResponseEntity<ExceptionResponse> handleInvalidAuthorizationTokenExceptionException(
final OAuthException.InvalidAuthorizationTokenException exception
final OAuthException.InvalidAuthorizationTokenException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(OAuthException.KakaoServerUnavailableException.class)
public ResponseEntity<ExceptionResponse> handleKakaoServerExceptionException(
final OAuthException.KakaoServerUnavailableException exception
final OAuthException.KakaoServerUnavailableException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(InvalidTokenException.class)
public ResponseEntity<ExceptionResponse> handleInvalidTokenExceptionException(
final InvalidTokenException exception
final InvalidTokenException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(UnsupportedOAuthTypeException.class)
public ResponseEntity<ExceptionResponse> handleUnsupportedOAuthTypeException(
final UnsupportedOAuthTypeException exception
final UnsupportedOAuthTypeException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(UnsupportedThemeColorException.class)
public ResponseEntity<ExceptionResponse> handleUnsupportedThemeColorException(
final UnsupportedThemeColorException exception
final UnsupportedThemeColorException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(NotFoundUserException.class)
public ResponseEntity<ExceptionResponse> handleNotFoundUserException(
final NotFoundUserException exception
final NotFoundUserException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(InvalidGoalException.class)
public ResponseEntity<ExceptionResponse> handleInvalidGoalException(
final InvalidGoalException exception
final InvalidGoalException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(NotFoundGoalException.class)
public ResponseEntity<ExceptionResponse> handleNotFoundGoalException(
final NotFoundGoalException exception
final NotFoundGoalException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(FriendRequestNotAllowedException.class)
public ResponseEntity<ExceptionResponse> handleAlreadyRequestedFriendException(
final FriendRequestNotAllowedException exception
final FriendRequestNotAllowedException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(NotFoundFriendRequestException.class)
public ResponseEntity<ExceptionResponse> handleNotFoundFriendRequestException(
final NotFoundFriendRequestException exception
final NotFoundFriendRequestException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(FriendAcceptanceForbiddenException.class)
public ResponseEntity<ExceptionResponse> handleFriendAcceptanceForbiddenException(
final FriendAcceptanceForbiddenException exception
final FriendAcceptanceForbiddenException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(DeleteFriendForbiddenException.class)
public ResponseEntity<ExceptionResponse> handleDeleteFriendForbiddenException(
final DeleteFriendForbiddenException exception
final DeleteFriendForbiddenException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(DeleteGoalForbiddenException.class)
public ResponseEntity<ExceptionResponse> handleDeleteGoalForbiddenException(
final DeleteGoalForbiddenException exception
final DeleteGoalForbiddenException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(UpdateGoalForbiddenException.class)
public ResponseEntity<ExceptionResponse> handleUpdateGoalForbiddenException(
final UpdateGoalForbiddenException exception
final UpdateGoalForbiddenException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(AlreadyRegisterBlackListTokenException.class)
public ResponseEntity<ExceptionResponse> handleAlreadyRegisterBlackListTokenException(
final AlreadyRegisterBlackListTokenException exception
final AlreadyRegisterBlackListTokenException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(ForbiddenGoalToPokeException.class)
public ResponseEntity<ExceptionResponse> handleForbiddenGoalToPokeException(
final ForbiddenGoalToPokeException exception, final HttpServletRequest request
) {
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(NotFoundGoalManagerException.class)
public ResponseEntity<ExceptionResponse> handleNotFoundGoalManagerException(
final NotFoundGoalManagerException exception, final HttpServletRequest request
) {
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(DuplicateUserNameException.class)
public ResponseEntity<ExceptionResponse> handleDuplicateUserNameException(
final DuplicateUserNameException exception, final HttpServletRequest request
) {
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(InvalidStampException.class)
public ResponseEntity<ExceptionResponse> handleInvalidStampException(
final InvalidStampException exception
final InvalidStampException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new ExceptionResponse(exception.getMessage()));
}

@ExceptionHandler(CreateStampForbiddenException.class)
public ResponseEntity<ExceptionResponse> handleCreateStampForbiddenException(
final CreateStampForbiddenException exception
final CreateStampForbiddenException exception, final HttpServletRequest request
) {
logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
logWarn(exception, request);

return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(new ExceptionResponse(exception.getMessage()));
Expand All @@ -249,4 +287,33 @@ public ResponseEntity<ExceptionResponse> handleReadStampForbiddenException(
return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(new ExceptionResponse(exception.getMessage()));
}

private void logError(final Exception exception, final HttpServletRequest request) {
setMDC(request);

logger.error(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
}

private void logWarn(final Exception exception, final HttpServletRequest request) {
setMDC(request);

logger.warn(String.format(LOG_MESSAGE_FORMAT, exception.getClass().getSimpleName(), exception.getMessage()));
}

private void setMDC(final HttpServletRequest request) {
MDC.put("version", request.getHeader("X-API-VERSION"));
MDC.put("method", request.getMethod());
MDC.put("uri", getRequestURI(request));
}

private static String getRequestURI(final HttpServletRequest request) {
String requestURI = request.getRequestURI();
final String queryString = request.getQueryString();

if (queryString != null) {
requestURI = requestURI + "?" + queryString;
}

return requestURI;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public void accept(final Long userId, final Long requestId) {
validateRequestedUser(user, friend);

friend.acceptRequest();
notificationService.sendAcceptFriendNotification(friend);
}

private Friend getFriend(final Long requestId) {
Expand Down
Loading

0 comments on commit 322e219

Please sign in to comment.