Skip to content

Commit

Permalink
Merge pull request #43 from TeamPINGLE/refac/34
Browse files Browse the repository at this point in the history
[refac] 코드리뷰 적용 및 패키지 구조 변경
  • Loading branch information
Parkjyun authored Jan 10, 2024
2 parents b73d591 + 0bc2361 commit 8d8edf6
Show file tree
Hide file tree
Showing 20 changed files with 76 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import org.pingle.pingleserver.dto.common.ApiResponse;
import org.pingle.pingleserver.dto.reponse.LocationResponse;
import org.pingle.pingleserver.dto.type.SuccessMessage;
import org.pingle.pingleserver.utils.naversearchutil.NaverUtil;
import org.pingle.pingleserver.utils.NaverUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import lombok.extern.slf4j.Slf4j;
import org.pingle.pingleserver.annotation.UserId;
import org.pingle.pingleserver.domain.User;
import org.pingle.pingleserver.domain.enums.URole;
import org.pingle.pingleserver.dto.response.JwtTokenResponse;
import org.pingle.pingleserver.exception.CustomException;
import org.pingle.pingleserver.dto.response.JwtTokenResponse;
import org.pingle.pingleserver.dto.type.ErrorMessage;
import org.pingle.pingleserver.exception.BusinessException;
import org.pingle.pingleserver.repository.UserRepository;
import org.pingle.pingleserver.utils.JwtUtil;
import org.springframework.http.ResponseEntity;
Expand All @@ -28,7 +28,7 @@ public class TestController {
@GetMapping("/token/{userId}")
public JwtTokenResponse testToken(@PathVariable Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new BusinessException(ErrorMessage.USER_NOT_FOUND));
.orElseThrow(() -> new CustomException(ErrorMessage.USER_NOT_FOUND));
JwtTokenResponse response = jwtUtil.generateTokens(user.getId(), user.getRole());
user.updateRefreshToken(response.refreshToken());
return response;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ public class ApiResponse<T>{

private final int code;
private final String message;
@JsonInclude(JsonInclude.Include.NON_NULL)
private T data;

public static <T> ApiResponse<T> success(SuccessMessage success) {
Expand Down
11 changes: 2 additions & 9 deletions src/main/java/org/pingle/pingleserver/dto/type/ErrorMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,20 @@ public enum ErrorMessage {
ALREADY_REGISTERED_USER(HttpStatus.BAD_REQUEST, "이미 가입된 사용자입니다."),
INVALID_GROUP_CODE(HttpStatus.BAD_REQUEST, "유효하지 않은 그룹 코드입니다."),
INVALID_HEADER_ERROR(HttpStatus.BAD_REQUEST, "유효하지 않은 헤더입니다."),
INVALID_PARAMETER_ERROR(HttpStatus.BAD_REQUEST, "유효하지 않은 파라미터입니다."),
INVALID_PROVIDER_ERROR(HttpStatus.BAD_REQUEST, "유효하지 않은 소셜 플랫폼입니다."),
MISSING_REQUIRED_HEADER(HttpStatus.BAD_REQUEST, "필수 헤더가 누락되었습니다."),
NO_SUCH_PIN(HttpStatus.BAD_REQUEST, "해당하는 핀이 없습니다."),
NO_SUCH_MEETING(HttpStatus.BAD_REQUEST, "해당하는 미팅이 없습니다." ),
// Authorization Error 401
TOKEN_MALFORMED_ERROR(HttpStatus.UNAUTHORIZED, "유효하지 않은 토큰입니다."),
UNAUTHORIZED_ERROR(HttpStatus.UNAUTHORIZED, "토큰이 제공되지 않았거나 유효하지 않습니다."),
NO_SUCH_USER(HttpStatus.UNAUTHORIZED, "존재하지 않는 사용자입니다."),
EMPTY_PRINCIPAL(HttpStatus.UNAUTHORIZED, "내부적으로 유저 정보를 받는데 실패했습니다"),
// Permission Denied 403
GROUP_PERMISSION_DENIED(HttpStatus.FORBIDDEN, "해당 사용자는 그룹에 속해 있지 않습니다."),
// Not Found Error 404
NOT_FOUND_RESOURCE(HttpStatus.NOT_FOUND, "해당 리소스가 존재하지 않습니다."),
RESOURCE_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 리소스가 존재하지 않습니다."),
USER_NOT_FOUND(HttpStatus.NOT_FOUND, "사용자를 찾을 수 없습니다."),
NOT_FOUND_END_POINT(HttpStatus.NOT_FOUND, "존재하지 않는 API입니다."),
// Method Not Allowed Error 405
METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, "지원하지 않는 HTTP 메소드입니다."),
// Conflict Error 409
RESOURCE_CONFLICT(HttpStatus.CONFLICT, "리소스 충돌이 일어났습니다."),
// OpenApi Server Error 500
NAVER_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "네이버 서버 오류입니다."),
// Internal Server Error 500
INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "서버 내부 오류입니다.");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import org.pingle.pingleserver.dto.type.ErrorMessage;

@Getter
public class BusinessException extends RuntimeException {
public class CustomException extends RuntimeException {
private final ErrorMessage errorMessage;

public BusinessException(ErrorMessage errorMessage) {
public CustomException(ErrorMessage errorMessage) {
super(errorMessage.getMessage());
this.errorMessage = errorMessage;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ public ResponseEntity<ApiResponse<?>> handlerMissingRequestHeaderException(Excep
.body(ApiResponse.fail(ErrorMessage.MISSING_REQUIRED_HEADER));
}

@ExceptionHandler(BusinessException.class)
public ResponseEntity<ApiResponse<?>> handleBusinessException(BusinessException e) {
@ExceptionHandler(CustomException.class)
public ResponseEntity<ApiResponse<?>> handleBusinessException(CustomException e) {
log.error("handleException() in GlobalExceptionHandler throw BusinessException : {}", e.getErrorMessage());
return ResponseEntity.status(e.getHttpStatusCode())
.body(ApiResponse.fail(e.getErrorMessage()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import lombok.RequiredArgsConstructor;
import org.pingle.pingleserver.annotation.GUserId;
import org.pingle.pingleserver.dto.type.ErrorMessage;
import org.pingle.pingleserver.exception.BusinessException;
import org.pingle.pingleserver.exception.CustomException;
import org.pingle.pingleserver.service.UserMeetingService;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -33,11 +33,11 @@ public Object resolveArgument(MethodParameter parameter,
WebDataBinderFactory binderFactory) {
final Principal principal = webRequest.getUserPrincipal();
if (principal == null) {
throw new BusinessException(ErrorMessage.NO_SUCH_USER);
throw new CustomException(ErrorMessage.EMPTY_PRINCIPAL);
}

if (webRequest.getHeader("Group-Id") == null)
throw new BusinessException(ErrorMessage.INVALID_HEADER_ERROR);
throw new CustomException(ErrorMessage.INVALID_HEADER_ERROR);
Long groupId = Long.valueOf(webRequest.getHeader("Group-Id"));

userMeetingService.verifyUser(getIdFromPrincipal(principal), groupId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import lombok.extern.slf4j.Slf4j;
import org.pingle.pingleserver.annotation.UserId;
import org.pingle.pingleserver.dto.type.ErrorMessage;
import org.pingle.pingleserver.exception.BusinessException;
import org.pingle.pingleserver.exception.CustomException;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
Expand All @@ -30,7 +30,7 @@ public Object resolveArgument(MethodParameter parameter,
WebDataBinderFactory binderFactory) {
final Principal principal = webRequest.getUserPrincipal();
if (principal == null) {
throw new BusinessException(ErrorMessage.INVALID_JWT_TOKEN);
throw new CustomException(ErrorMessage.EMPTY_PRINCIPAL);
}
return Long.valueOf(principal.getName());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.pingle.pingleserver.oauth.dto;

import org.pingle.pingleserver.dto.type.ErrorMessage;
import org.pingle.pingleserver.exception.BusinessException;
import org.pingle.pingleserver.exception.CustomException;

import java.util.List;

Expand All @@ -11,6 +11,6 @@ public ApplePublicKey getMatchesKey(String alg, String kid) {
.stream()
.filter(k -> k.alg().equals(alg) && k.kid().equals(kid))
.findFirst()
.orElseThrow(() -> new BusinessException(ErrorMessage.INVALID_APPLE_PUBLIC_KEY));
.orElseThrow(() -> new CustomException(ErrorMessage.INVALID_APPLE_PUBLIC_KEY));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.*;
import org.pingle.pingleserver.dto.type.ErrorMessage;
import org.pingle.pingleserver.exception.BusinessException;
import org.pingle.pingleserver.exception.CustomException;
import org.springframework.stereotype.Component;

import java.security.PublicKey;
Expand All @@ -26,7 +26,7 @@ public Map<String, String> parseHeaders(String identityToken) {
return OBJECT_MAPPER.readValue(decodedHeader, Map.class);

} catch (JsonProcessingException | ArrayIndexOutOfBoundsException e) {
throw new BusinessException(ErrorMessage.INVALID_APPLE_IDENTITY_TOKEN);
throw new CustomException(ErrorMessage.INVALID_APPLE_IDENTITY_TOKEN);
}
}

Expand All @@ -39,9 +39,9 @@ public Claims parsePublicKeyAndGetClaims(String idToken, PublicKey publicKey) {
.getBody();

} catch (ExpiredJwtException e) {
throw new BusinessException(ErrorMessage.EXPIRED_APPLE_IDENTITY_TOKEN);
throw new CustomException(ErrorMessage.EXPIRED_APPLE_IDENTITY_TOKEN);
} catch (UnsupportedJwtException | MalformedJwtException | IllegalArgumentException e) {
throw new BusinessException(ErrorMessage.INVALID_APPLE_IDENTITY_TOKEN);
throw new CustomException(ErrorMessage.INVALID_APPLE_IDENTITY_TOKEN);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.pingle.pingleserver.oauth.verify;

import org.pingle.pingleserver.dto.type.ErrorMessage;
import org.pingle.pingleserver.exception.BusinessException;
import org.pingle.pingleserver.exception.CustomException;
import org.pingle.pingleserver.oauth.dto.ApplePublicKey;
import org.pingle.pingleserver.oauth.dto.ApplePublicKeys;
import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -42,7 +42,7 @@ private PublicKey generatePublicKeyWithApplePublicKey(ApplePublicKey publicKey)
KeyFactory keyFactory = KeyFactory.getInstance(publicKey.kty());
return keyFactory.generatePublic(publicKeySpec);
} catch (NoSuchAlgorithmException | InvalidKeySpecException exception) {
throw new BusinessException(ErrorMessage.CREATE_PUBLIC_KEY_EXCEPTION);
throw new CustomException(ErrorMessage.CREATE_PUBLIC_KEY_EXCEPTION);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@

import org.pingle.pingleserver.domain.Team;
import org.pingle.pingleserver.dto.response.TeamDetailDto;
import org.pingle.pingleserver.dto.type.ErrorMessage;
import org.pingle.pingleserver.exception.CustomException;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;
import java.util.Optional;

public interface TeamRepository extends JpaRepository<Team, Long> {
default Team findByIdOrThrow(Long teamId) {
return findById(teamId)
.orElseThrow((() -> new CustomException(ErrorMessage.RESOURCE_NOT_FOUND)));
}
List<Team> findAllByNameIgnoreCaseContainingOrderByName(String name);

@Query("SELECT new org.pingle.pingleserver.dto.response.TeamDetailDto(t, COUNT(m), COUNT(ut)) " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,23 @@

import org.pingle.pingleserver.domain.User;
import org.pingle.pingleserver.domain.enums.Provider;
import org.pingle.pingleserver.dto.type.ErrorMessage;
import org.pingle.pingleserver.exception.CustomException;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Long> {
default User findByIdOrThrow(Long id) {
return findById(id).orElseThrow(() -> new CustomException(ErrorMessage.USER_NOT_FOUND));
}

default User findByIdAndIsDeletedOrThrow(Long id, Boolean deleted) {
return findByIdAndIsDeleted(id, false).orElseThrow(
() -> new CustomException(ErrorMessage.USER_NOT_FOUND));
}
Optional<User> findByIdAndIsDeleted(Long id, Boolean deleted);
boolean existsByProviderAndSerialIdAndIsDeleted(Provider provider, String serialId, Boolean deleted);
Optional<User> findByProviderAndSerialIdAndIsDeleted(Provider provider, String serialId, Boolean deleted);
Optional<User> findByIdAndIsDeleted(Long id, Boolean deleted);
Optional<User> findByRefreshTokenAndIsDeleted(String refreshToken, Boolean deleted);
}
11 changes: 5 additions & 6 deletions src/main/java/org/pingle/pingleserver/service/AuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
import org.pingle.pingleserver.domain.enums.Provider;
import org.pingle.pingleserver.domain.enums.URole;
import org.pingle.pingleserver.dto.request.ReissueRequest;
import org.pingle.pingleserver.exception.CustomException;
import org.pingle.pingleserver.oauth.dto.SocialInfoDto;
import org.pingle.pingleserver.dto.request.LoginRequest;
import org.pingle.pingleserver.dto.response.JwtTokenResponse;
import org.pingle.pingleserver.dto.type.ErrorMessage;
import org.pingle.pingleserver.exception.BusinessException;
import org.pingle.pingleserver.oauth.service.AppleLoginService;
import org.pingle.pingleserver.oauth.service.KakaoLoginService;
import org.pingle.pingleserver.repository.UserRepository;
Expand Down Expand Up @@ -38,14 +38,13 @@ public JwtTokenResponse login(String providerToken, LoginRequest request) {
public JwtTokenResponse reissue(ReissueRequest request) {
jwtUtil.getTokenBody(request.refreshToken());
User user = userRepository.findByRefreshTokenAndIsDeleted(request.refreshToken(), false)
.orElseThrow(() -> new BusinessException(ErrorMessage.USER_NOT_FOUND));
.orElseThrow(() -> new CustomException(ErrorMessage.USER_NOT_FOUND));
return generateTokensWithUpdateRefreshToken(user);
}

@Transactional
public void logout(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new BusinessException(ErrorMessage.USER_NOT_FOUND));
User user = userRepository.findByIdOrThrow(userId);
user.updateRefreshToken(null);
}

Expand All @@ -55,7 +54,7 @@ private SocialInfoDto getSocialInfo(LoginRequest request, String providerToken){
} else if (request.provider().toString().equals(Provider.KAKAO.toString())){
return kakaoLoginService.getInfo(providerToken);
} else {
throw new BusinessException(ErrorMessage.INVALID_PROVIDER_ERROR);
throw new CustomException(ErrorMessage.INVALID_PROVIDER_ERROR);
}
}

Expand All @@ -74,7 +73,7 @@ private User loadOrCreateUser(Provider provider, SocialInfoDto socialInfo){
}

return userRepository.findByProviderAndSerialIdAndIsDeleted(provider, socialInfo.serialId(), false)
.orElseThrow(() -> new BusinessException(ErrorMessage.USER_NOT_FOUND));
.orElseThrow(() -> new CustomException(ErrorMessage.USER_NOT_FOUND));
}

private JwtTokenResponse generateTokensWithUpdateRefreshToken(User user){
Expand Down
11 changes: 6 additions & 5 deletions src/main/java/org/pingle/pingleserver/service/PinService.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import org.pingle.pingleserver.domain.Point;
import org.pingle.pingleserver.dto.request.MeetingRequest;
import org.pingle.pingleserver.dto.type.ErrorMessage;
import org.pingle.pingleserver.exception.BusinessException;
import org.pingle.pingleserver.exception.CustomException;
import org.pingle.pingleserver.repository.PinRepository;
import org.pingle.pingleserver.repository.TeamRepository;
import org.pingle.pingleserver.repository.UserMeetingRepository;
Expand All @@ -38,14 +38,14 @@ public class PinService {
private final UserMeetingRepository userMeetingRepository;

public List<PinResponse> getPinListFilterByCategory(Long teamId, MCategory category) {
Team team = teamRepository.findById(teamId).orElseThrow(() -> new BusinessException(ErrorMessage.NOT_FOUND_RESOURCE));
Team team = teamRepository.findByIdOrThrow(teamId);
List<Pin> pinList = pinRepository.findAllByTeam(team);
if(category == null) return pinList.stream().map(PinResponse::of).toList();
return pinList.stream().filter(pin -> checkMeetingsCategoryOfPin(pin, category)).map(PinResponse::of).toList();
}

public List<MeetingResponse> getMeetingDetailList(Long userId, Long pinId) {
Pin pin = pinRepository.findById(pinId).orElseThrow(() -> new BusinessException(ErrorMessage.NOT_FOUND_RESOURCE));
Pin pin = pinRepository.findById(pinId).orElseThrow(() -> new CustomException(ErrorMessage.RESOURCE_NOT_FOUND));
Comparator<Meeting> comparator = Comparator.comparing(Meeting::getStartAt);
List<Meeting> meetingList = pin.getMeetingList();
meetingList.sort(comparator);
Expand All @@ -71,7 +71,7 @@ public List<MeetingResponse> getMeetingDetailList(Long userId, Long pinId) {

@Transactional
public Pin verifyAndReturnPin(MeetingRequest request, Long groupId) {
Team team = teamRepository.findById(groupId).orElseThrow(() -> new BusinessException(ErrorMessage.NOT_FOUND_RESOURCE));
Team team = teamRepository.findByIdOrThrow(groupId);
if(!exist(new Point(request.x(), request.y()))) {
return pinRepository.save(Pin.builder()
.address(new Address(request.roadAddress(), request.address()))
Expand All @@ -93,7 +93,8 @@ private boolean checkMeetingsCategoryOfPin(Pin pin, MCategory category) {
}

private String getOwnerName(Meeting meeting) {
UserMeeting userMeeting = userMeetingRepository.findByMeetingAndMeetingRole(meeting, MRole.OWNER).orElseThrow(() ->new BusinessException(ErrorMessage.NOT_FOUND_RESOURCE ));
UserMeeting userMeeting = userMeetingRepository.findByMeetingAndMeetingRole(meeting, MRole.OWNER)
.orElseThrow(() ->new CustomException(ErrorMessage.RESOURCE_NOT_FOUND));
return userMeeting.getUser().getName();
}

Expand Down
14 changes: 6 additions & 8 deletions src/main/java/org/pingle/pingleserver/service/TeamService.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import org.pingle.pingleserver.dto.response.TeamRegistResponse;
import org.pingle.pingleserver.dto.response.TeamSearchResultResponse;
import org.pingle.pingleserver.dto.type.ErrorMessage;
import org.pingle.pingleserver.exception.BusinessException;
import org.pingle.pingleserver.exception.CustomException;
import org.pingle.pingleserver.repository.TeamRepository;
import org.pingle.pingleserver.repository.UserRepository;
import org.pingle.pingleserver.repository.UserTeamRepository;
Expand Down Expand Up @@ -43,22 +43,20 @@ public List<TeamSearchResultResponse> searchTeams(String teamName) {

public SelectedTeamResponse getTeam(Long teamId) {
TeamDetailDto team = teamRepository.findTeamDetailsWithCounts(teamId)
.orElseThrow(() -> new BusinessException(ErrorMessage.NOT_FOUND_RESOURCE));
.orElseThrow(() -> new CustomException(ErrorMessage.RESOURCE_NOT_FOUND));
return SelectedTeamResponse.of(team.team(), team.meetingCount(), team.participantCount());
}

@Transactional
public TeamRegistResponse registTeam(Long userId, Long teamId, TeamRegisterRequest request) {
Team team = teamRepository.findById(teamId)
.orElseThrow(() -> new BusinessException(ErrorMessage.NOT_FOUND_RESOURCE));
Team team = teamRepository.findByIdOrThrow(teamId);
if (!team.getCode().equals(request.code())) {
throw new BusinessException(ErrorMessage.INVALID_GROUP_CODE);
throw new CustomException(ErrorMessage.INVALID_GROUP_CODE);
}
User user = userRepository.findById(userId)
.orElseThrow(() -> new BusinessException(ErrorMessage.NO_SUCH_USER));
User user = userRepository.findByIdOrThrow(userId);
boolean isRegistered = userTeamRepository.existsByUserAndTeam(user, team);
if (isRegistered) {
throw new BusinessException(ErrorMessage.ALREADY_REGISTERED_USER);
throw new CustomException(ErrorMessage.ALREADY_REGISTERED_USER);
}
UserTeam newUserTeam = UserTeam.builder()
.user(user)
Expand Down
Loading

0 comments on commit 8d8edf6

Please sign in to comment.