From b15d7fa2aecf1ad7d78325074ad8b48e844f86df Mon Sep 17 00:00:00 2001 From: dungbik Date: Sun, 5 Apr 2026 15:09:37 +0900 Subject: [PATCH] =?UTF-8?q?Fix:=20=ED=86=A0=ED=81=B0=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=20=EC=A1=B0=ED=9A=8C=20GRPC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/application/AuthService.java | 2 - .../user/application/UserService.java | 11 +- .../grpc/GrpcExceptionHandlerImpl.java | 77 +++++----- .../interfaces/grpc/GrpcUserQueryService.java | 142 +++++++++--------- 4 files changed, 118 insertions(+), 114 deletions(-) diff --git a/src/main/java/flipnote/user/application/AuthService.java b/src/main/java/flipnote/user/application/AuthService.java index acfdd4e..e776d3c 100644 --- a/src/main/java/flipnote/user/application/AuthService.java +++ b/src/main/java/flipnote/user/application/AuthService.java @@ -151,8 +151,6 @@ public TokenValidateResult validateToken(String token) { } }); - findActiveUser(claims.userId()); - return new TokenValidateResult(claims.userId(), claims.email(), claims.role()); } diff --git a/src/main/java/flipnote/user/application/UserService.java b/src/main/java/flipnote/user/application/UserService.java index 6d33ab1..5b8c8e1 100644 --- a/src/main/java/flipnote/user/application/UserService.java +++ b/src/main/java/flipnote/user/application/UserService.java @@ -14,12 +14,11 @@ import flipnote.image.grpc.v1.Type; import flipnote.user.application.command.UpdateProfileCommand; import flipnote.user.application.result.MyInfoResult; +import flipnote.user.application.result.TokenValidateResult; import flipnote.user.application.result.UserInfoResult; import flipnote.user.application.result.UserResult; import flipnote.user.application.result.UserUpdateResult; -import flipnote.user.domain.AuthErrorCode; import flipnote.user.domain.ImageErrorCode; -import flipnote.user.domain.TokenClaims; import flipnote.user.domain.UserErrorCode; import flipnote.user.domain.common.BizException; import flipnote.user.domain.entity.User; @@ -38,6 +37,7 @@ public class UserService { private final UserRepository userRepository; private final SessionInvalidationRepository sessionInvalidationRepository; private final JwtProvider jwtProvider; + private final AuthService authService; private final ImageCommandServiceGrpc.ImageCommandServiceBlockingStub imageCommandServiceStub; public MyInfoResult getMyInfo(Long userId) { @@ -108,11 +108,8 @@ public Optional findActiveUserByEmail(String email) { } public UserResult findUserByToken(String token) { - if (!jwtProvider.isTokenValid(token)) { - throw new BizException(AuthErrorCode.INVALID_TOKEN); - } - TokenClaims claims = jwtProvider.extractClaims(token); - return UserResult.from(findActiveUser(claims.userId())); + TokenValidateResult tokenResult = authService.validateToken(token); + return UserResult.from(findActiveUser(tokenResult.userId())); } private User findActiveUser(Long userId) { diff --git a/src/main/java/flipnote/user/interfaces/grpc/GrpcExceptionHandlerImpl.java b/src/main/java/flipnote/user/interfaces/grpc/GrpcExceptionHandlerImpl.java index fc6c241..6771457 100644 --- a/src/main/java/flipnote/user/interfaces/grpc/GrpcExceptionHandlerImpl.java +++ b/src/main/java/flipnote/user/interfaces/grpc/GrpcExceptionHandlerImpl.java @@ -1,51 +1,56 @@ package flipnote.user.interfaces.grpc; +import org.springframework.grpc.server.exception.GrpcExceptionHandler; +import org.springframework.stereotype.Component; + import flipnote.user.domain.common.BizException; import flipnote.user.domain.common.ErrorCode; import io.grpc.Status; import io.grpc.StatusException; import io.grpc.StatusRuntimeException; import lombok.extern.slf4j.Slf4j; -import org.springframework.grpc.server.exception.GrpcExceptionHandler; -import org.springframework.stereotype.Component; @Slf4j @Component public class GrpcExceptionHandlerImpl implements GrpcExceptionHandler { - @Override - public StatusException handleException(Throwable t) { - if (t instanceof BizException e) { - ErrorCode errorCode = e.getErrorCode(); - log.warn("gRPC BizException: code={}, status={}, message={}", - errorCode.getCode(), errorCode.getStatus(), errorCode.getMessage()); - return toGrpcStatus(errorCode) - .withDescription(errorCode.getMessage()) - .asException(); - } - if (t instanceof StatusException e) { - log.warn("gRPC StatusException: status={}, description={}", - e.getStatus().getCode(), e.getStatus().getDescription()); - return e; - } - if (t instanceof StatusRuntimeException e) { - log.warn("gRPC StatusRuntimeException: status={}, description={}", - e.getStatus().getCode(), e.getStatus().getDescription()); - return e.getStatus().asException(e.getTrailers()); - } - log.error("gRPC Unhandled exception", t); - return Status.INTERNAL.withDescription("Internal server error").asException(); - } + @Override + public StatusException handleException(Throwable t) { + switch (t) { + case BizException e -> { + ErrorCode errorCode = e.getErrorCode(); + log.warn("gRPC BizException: code={}, status={}, message={}", + errorCode.getCode(), errorCode.getStatus(), errorCode.getMessage()); + return toGrpcStatus(errorCode) + .withDescription(errorCode.getMessage()) + .asException(); + } + case StatusException e -> { + log.warn("gRPC StatusException: status={}, description={}", + e.getStatus().getCode(), e.getStatus().getDescription()); + return e; + } + case StatusRuntimeException e -> { + log.warn("gRPC StatusRuntimeException: status={}, description={}", + e.getStatus().getCode(), e.getStatus().getDescription()); + return e.getStatus().asException(e.getTrailers()); + } + default -> { + } + } + log.error("gRPC Unhandled exception", t); + return Status.INTERNAL.withDescription("Internal server error").asException(); + } - private Status toGrpcStatus(ErrorCode errorCode) { - return switch (errorCode.getStatus()) { - case 400 -> Status.INVALID_ARGUMENT; - case 401 -> Status.UNAUTHENTICATED; - case 403 -> Status.PERMISSION_DENIED; - case 404 -> Status.NOT_FOUND; - case 409 -> Status.ALREADY_EXISTS; - case 429 -> Status.RESOURCE_EXHAUSTED; - default -> Status.INTERNAL; - }; - } + private Status toGrpcStatus(ErrorCode errorCode) { + return switch (errorCode.getStatus()) { + case 400 -> Status.INVALID_ARGUMENT; + case 401 -> Status.UNAUTHENTICATED; + case 403 -> Status.PERMISSION_DENIED; + case 404 -> Status.NOT_FOUND; + case 409 -> Status.ALREADY_EXISTS; + case 429 -> Status.RESOURCE_EXHAUSTED; + default -> Status.INTERNAL; + }; + } } diff --git a/src/main/java/flipnote/user/interfaces/grpc/GrpcUserQueryService.java b/src/main/java/flipnote/user/interfaces/grpc/GrpcUserQueryService.java index 20bfcf9..3fcad5e 100644 --- a/src/main/java/flipnote/user/interfaces/grpc/GrpcUserQueryService.java +++ b/src/main/java/flipnote/user/interfaces/grpc/GrpcUserQueryService.java @@ -2,7 +2,7 @@ import java.util.List; -import org.springframework.stereotype.Service; +import org.springframework.grpc.server.service.GrpcService; import flipnote.user.application.UserService; import flipnote.user.application.result.UserResult; @@ -18,76 +18,80 @@ import io.grpc.Status; import io.grpc.stub.StreamObserver; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; -@Service +@GrpcService @RequiredArgsConstructor +@Slf4j public class GrpcUserQueryService extends UserQueryServiceGrpc.UserQueryServiceImplBase { - private final UserService userService; - - @Override - public void getUser(GetUserRequest request, StreamObserver responseObserver) { - UserResult user = userService.findActiveUserById(request.getUserId()) - .orElseThrow(() -> Status.NOT_FOUND - .withDescription("사용자를 찾을 수 없습니다.") - .asRuntimeException()); - - responseObserver.onNext(toUserResponse(user)); - responseObserver.onCompleted(); - } - - @Override - public void getUsers(GetUsersRequest request, StreamObserver responseObserver) { - List userIds = request.getUserIdsList(); - List users = userService.findActiveUsersByIds(userIds); - - GetUsersResponse response = GetUsersResponse.newBuilder() - .addAllUsers(users.stream().map(this::toUserResponse).toList()) - .build(); - - responseObserver.onNext(response); - responseObserver.onCompleted(); - } - - @Override - public void getUserByEmail(GetUserByEmailRequest request, StreamObserver responseObserver) { - userService.findActiveUserByEmail(request.getEmail()) - .ifPresentOrElse( - user -> responseObserver.onNext( - GetUserByEmailResponse.newBuilder() - .setExists(true) - .setUser(toUserResponse(user)) - .build() - ), - () -> responseObserver.onNext( - GetUserByEmailResponse.newBuilder() - .setExists(false) - .build() - ) - ); - - responseObserver.onCompleted(); - } - - @Override - public void getUserByToken(GetUserByTokenRequest request, StreamObserver responseObserver) { - UserResult user = userService.findUserByToken(request.getAccessToken()); - - responseObserver.onNext( - GetUserByTokenResponse.newBuilder() - .setUserId(user.id()) - .setNickname(user.nickname()) - .build() - ); - responseObserver.onCompleted(); - } - - private GetUserResponse toUserResponse(UserResult user) { - return GetUserResponse.newBuilder() - .setId(user.id()) - .setEmail(user.email()) - .setNickname(user.nickname()) - .setProfileImageUrl(user.profileImageUrl()) - .build(); - } + private final UserService userService; + + @Override + public void getUser(GetUserRequest request, StreamObserver responseObserver) { + UserResult user = userService.findActiveUserById(request.getUserId()) + .orElseThrow(() -> Status.NOT_FOUND + .withDescription("사용자를 찾을 수 없습니다.") + .asRuntimeException()); + + responseObserver.onNext(toUserResponse(user)); + responseObserver.onCompleted(); + } + + @Override + public void getUsers(GetUsersRequest request, StreamObserver responseObserver) { + List userIds = request.getUserIdsList(); + List users = userService.findActiveUsersByIds(userIds); + + GetUsersResponse response = GetUsersResponse.newBuilder() + .addAllUsers(users.stream().map(this::toUserResponse).toList()) + .build(); + + responseObserver.onNext(response); + responseObserver.onCompleted(); + } + + @Override + public void getUserByEmail(GetUserByEmailRequest request, StreamObserver responseObserver) { + userService.findActiveUserByEmail(request.getEmail()) + .ifPresentOrElse( + user -> responseObserver.onNext( + GetUserByEmailResponse.newBuilder() + .setExists(true) + .setUser(toUserResponse(user)) + .build() + ), + () -> responseObserver.onNext( + GetUserByEmailResponse.newBuilder() + .setExists(false) + .build() + ) + ); + + responseObserver.onCompleted(); + } + + @Override + public void getUserByToken(GetUserByTokenRequest request, StreamObserver responseObserver) { + log.debug("getUserByToken accessToken [{}]", request.getAccessToken()); + + UserResult user = userService.findUserByToken(request.getAccessToken()); + + responseObserver.onNext( + GetUserByTokenResponse.newBuilder() + .setUserId(user.id()) + .setNickname(user.nickname()) + .build() + ); + responseObserver.onCompleted(); + } + + private GetUserResponse toUserResponse(UserResult user) { + return GetUserResponse.newBuilder() + .setId(user.id()) + .setEmail(user.email()) + .setNickname(user.nickname()) + .setProfileImageUrl(user.profileImageUrl()) + .build(); + } }