diff --git a/build.gradle b/build.gradle index 73caae1..ccca72b 100644 --- a/build.gradle +++ b/build.gradle @@ -28,6 +28,9 @@ dependencies { runtimeOnly 'com.mysql:mysql-connector-j' testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.springframework.boot:spring-boot-testcontainers' + testImplementation 'org.testcontainers:junit-jupiter' + testImplementation 'org.testcontainers:mysql:1.20.0' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' implementation 'io.jsonwebtoken:jjwt-api:0.11.5' @@ -75,3 +78,4 @@ dependencies { tasks.named('test') { useJUnitPlatform() } + diff --git a/src/main/java/com/sayup/SayUp/aop/Logging.java b/src/main/java/com/sayup/SayUp/aop/Logging.java index bee6965..ccc2a0c 100644 --- a/src/main/java/com/sayup/SayUp/aop/Logging.java +++ b/src/main/java/com/sayup/SayUp/aop/Logging.java @@ -57,5 +57,21 @@ public Object logHttpRequests(ProceedingJoinPoint joinPoint) throws Throwable { return result; } + + // @RestController 또는 @Service 가 붙은 클래스만 AOP 적용 + @Around("within(@org.springframework.web.bind.annotation.RestController *) || within(@org.springframework.stereotype.Service *)") + public Object logExceptions(ProceedingJoinPoint joinPoint) throws Throwable { + try { + return joinPoint.proceed(); + } catch (Exception e) { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + String methodName = signature.getMethod().getName(); + String className = signature.getDeclaringType().getSimpleName(); + + logger.error("Exception in {}.{}() | Error: {}", className, methodName, e.getMessage()); + + throw e; // 예외 다시 던지기 -> Spring이 전역 예외 처리기로 전달 (@ControllerAdvice에서 예외를 핸들링하여 클라이언트에게 적절한 응답을 반환 가능) + } + } } diff --git a/src/main/java/com/sayup/SayUp/controller/AuthController.java b/src/main/java/com/sayup/SayUp/controller/AuthController.java index acf3879..f6fa9c7 100644 --- a/src/main/java/com/sayup/SayUp/controller/AuthController.java +++ b/src/main/java/com/sayup/SayUp/controller/AuthController.java @@ -5,8 +5,6 @@ import com.sayup.SayUp.dto.UserDTO; import com.sayup.SayUp.service.AuthService; import jakarta.validation.Valid; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -14,7 +12,6 @@ @RestController @RequestMapping("/api/auth") public class AuthController { - private static final Logger logger = LoggerFactory.getLogger(AuthController.class); private final AuthService authService; public AuthController(AuthService authService) { @@ -28,13 +25,8 @@ public AuthController(AuthService authService) { */ @PostMapping("/register") public ResponseEntity register(@RequestBody @Valid UserDTO userDTO) { - try { - authService.register(userDTO); - return ResponseEntity.ok("User registered successfully!"); - } catch (Exception ex) { - logger.error("Registration failed for email: {}", userDTO.getEmail(), ex); - return ResponseEntity.badRequest().body("Registration failed: " + ex.getMessage()); - } + authService.register(userDTO); + return ResponseEntity.ok("User registered successfully!"); } /** @@ -44,13 +36,8 @@ public ResponseEntity register(@RequestBody @Valid UserDTO userDTO) { */ @PostMapping("/login") public ResponseEntity login(@RequestBody @Valid AuthRequestDTO authRequestDTO) { - try { - AuthResponseDTO response = authService.login(authRequestDTO); - return ResponseEntity.ok(response); - } catch (Exception ex) { - logger.error("Login failed for email: {}", authRequestDTO.getEmail(), ex); - return ResponseEntity.badRequest().body(null); - } + AuthResponseDTO response = authService.login(authRequestDTO); + return ResponseEntity.ok(response); } /** diff --git a/src/main/java/com/sayup/SayUp/controller/FriendshipController.java b/src/main/java/com/sayup/SayUp/controller/FriendshipController.java index 4709b1d..fbe8eca 100644 --- a/src/main/java/com/sayup/SayUp/controller/FriendshipController.java +++ b/src/main/java/com/sayup/SayUp/controller/FriendshipController.java @@ -25,76 +25,43 @@ public class FriendshipController { private static final Logger logger = LoggerFactory.getLogger(FriendshipController.class); @PostMapping("/request/{addresseeId}") - public ResponseEntity sendFriendRequest( - @AuthenticationPrincipal UserDetails userDetails, - @PathVariable Integer addresseeId) { + public ResponseEntity sendFriendRequest(@AuthenticationPrincipal UserDetails userDetails, @PathVariable Integer addresseeId) { if (userDetails == null) { - logger.warn("Failed to send friend request: User not authenticated"); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("User not authenticated"); } else if (!(userDetails instanceof CustomUserDetails)) { logger.error("UserDetails is not an instance of CustomUserDetails"); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Internal Server Error"); } - CustomUserDetails customUserDetails = (CustomUserDetails) userDetails; - - try { - friendshipService.sendFriendRequest(customUserDetails, addresseeId); - return ResponseEntity.ok().build(); - } catch (Exception e) { - logger.error("Failed to send friend request: {}", e.getMessage()); - return ResponseEntity.badRequest().body(e.getMessage()); - } + friendshipService.sendFriendRequest((CustomUserDetails) userDetails, addresseeId); + return ResponseEntity.ok().build(); } @PostMapping("/accept/{relationshipId}") - public ResponseEntity acceptFriendRequest( - @AuthenticationPrincipal UserDetails userDetails, - @PathVariable Long relationshipId) { + public ResponseEntity acceptFriendRequest(@AuthenticationPrincipal UserDetails userDetails, @PathVariable Long relationshipId) { if (userDetails == null) { - logger.warn("Failed to accept friend request: User not authenticated"); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("User not authenticated"); - } else if (!(userDetails instanceof CustomUserDetails)) { - logger.error("UserDetails is not an instance of CustomUserDetails"); - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Internal Server Error"); } - CustomUserDetails customUserDetails = (CustomUserDetails) userDetails; - try { - friendshipService.acceptFriendRequest(customUserDetails, relationshipId); - return ResponseEntity.ok().build(); - } catch (Exception e) { - logger.error("Failed to accept friend request: {}", e.getMessage()); - return ResponseEntity.badRequest().body(e.getMessage()); - } + friendshipService.acceptFriendRequest((CustomUserDetails) userDetails, relationshipId); + return ResponseEntity.ok().build(); } @GetMapping("/list") - public ResponseEntity> getFriendsList( - @AuthenticationPrincipal UserDetails userDetails) { + public ResponseEntity> getFriendsList(@AuthenticationPrincipal UserDetails userDetails) { if (userDetails == null) { - logger.warn("Failed to get friends list: User not authenticated"); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); - } else if (!(userDetails instanceof CustomUserDetails)) { - logger.error("UserDetails is not an instance of CustomUserDetails"); - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } - CustomUserDetails customUserDetails = (CustomUserDetails) userDetails; - return ResponseEntity.ok(friendshipService.getFriendsList(customUserDetails)); + return ResponseEntity.ok(friendshipService.getFriendsList((CustomUserDetails) userDetails)); } @GetMapping("/pending") public ResponseEntity> getPendingRequests(@AuthenticationPrincipal CustomUserDetails userDetails) { if (userDetails == null) { - logger.warn("Failed to get pending requests: User not authenticated"); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); - } else if (!(userDetails instanceof CustomUserDetails)) { - logger.error("UserDetails is not an instance of CustomUserDetails"); - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } - List pendingRequests = friendshipService.getPendingRequests(userDetails); - return ResponseEntity.ok(pendingRequests); + return ResponseEntity.ok(friendshipService.getPendingRequests(userDetails)); } } diff --git a/src/main/java/com/sayup/SayUp/controller/UserAudioUploadController.java b/src/main/java/com/sayup/SayUp/controller/UserAudioUploadController.java index 1a2874e..cf582d5 100644 --- a/src/main/java/com/sayup/SayUp/controller/UserAudioUploadController.java +++ b/src/main/java/com/sayup/SayUp/controller/UserAudioUploadController.java @@ -2,8 +2,6 @@ import com.sayup.SayUp.repository.UserVoiceRepository; import com.sayup.SayUp.service.UserVoiceService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -14,7 +12,6 @@ @RestController @RequestMapping("/api/users/audio") public class UserAudioUploadController { - private static final Logger logger = LoggerFactory.getLogger(UserAudioUploadController.class); private final UserVoiceService userVoiceService; public UserAudioUploadController(UserVoiceService userVoiceService, UserVoiceRepository userVoiceRepository) { @@ -22,22 +19,11 @@ public UserAudioUploadController(UserVoiceService userVoiceService, UserVoiceRep } @PostMapping(consumes = {"multipart/form-data"}) - public ResponseEntity uploadFile( - @RequestHeader("Authorization") String token, - @RequestParam("file")MultipartFile file){ - logger.info("File upload request received."); - + public ResponseEntity uploadFile(@RequestHeader("Authorization") String token, @RequestParam("file")MultipartFile file){ if (file.isEmpty()) { - logger.warn("No file attached in the request."); return ResponseEntity.badRequest().body("File is required."); } - try { - ResponseEntity response = userVoiceService.uploadFile(token, file); - return response; - } catch (Exception e) { - logger.error("Error occurred while uploading file.", e); - return ResponseEntity.internalServerError().body("Error occurred while uploading file."); - } + return userVoiceService.uploadFile(token, file); } } diff --git a/src/main/java/com/sayup/SayUp/controller/UserTTSVectorController.java b/src/main/java/com/sayup/SayUp/controller/UserTTSVectorController.java index 2bd9edd..b7e011a 100644 --- a/src/main/java/com/sayup/SayUp/controller/UserTTSVectorController.java +++ b/src/main/java/com/sayup/SayUp/controller/UserTTSVectorController.java @@ -3,9 +3,6 @@ import com.sayup.SayUp.entity.User; import com.sayup.SayUp.repository.UserRepository; import com.sayup.SayUp.security.JwtTokenProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.scheduling.annotation.Async; import org.springframework.security.core.userdetails.UsernameNotFoundException; @@ -20,8 +17,6 @@ @RestController @RequestMapping("/api/users/tts") public class UserTTSVectorController { - private static final Logger logger = LoggerFactory.getLogger(UserTTSVectorController.class); - private final JwtTokenProvider jwtTokenProvider; private final UserRepository userRepository; @@ -34,46 +29,32 @@ public UserTTSVectorController(JwtTokenProvider jwtTokenProvider, @Async public CompletableFuture processAndSaveTTSVector(String email, String ttsVector) { return CompletableFuture.runAsync(() -> { - try { - User user = userRepository.findByEmail(email) - .orElseThrow(() -> new UsernameNotFoundException("User not found with email: " + email)); - - // TTS 벡터 저장 - user.setTtsVector(ttsVector); - userRepository.save(user); + User user = userRepository.findByEmail(email) + .orElseThrow(() -> new UsernameNotFoundException("User not found with email: " + email)); - } catch (Exception ex) { - logger.error("Error saving TTS Vector", ex); - } + // TTS 벡터 저장 + user.setTtsVector(ttsVector); + userRepository.save(user); }); } @PostMapping - public ResponseEntity> initiateVectorSave( - @RequestHeader("Authorization") String token, - @RequestBody Map body) { + public ResponseEntity> initiateVectorSave(@RequestHeader("Authorization") String token, @RequestBody Map body) { String ttsVector = body.get("ttsVector"); - try { - // JWT 토큰에서 사용자 이메일 추출 - String email = jwtTokenProvider.getUsernameFromToken(token.substring(7)); + // "Bearer " 제거 후 실제 JWT 토큰 추출 + String jwt = token.startsWith("Bearer ") ? token.substring(7) : token; - // 비동기 처리 시작 - processAndSaveTTSVector(email, ttsVector); + // JWT 토큰에서 사용자 이메일 추출 + String email = jwtTokenProvider.getUsernameFromToken(jwt); - return ResponseEntity.accepted().body(Map.of( - "status", "processing", - "message", "TTS Vector processing started" - )); + // 비동기 처리 시작 + processAndSaveTTSVector(email, ttsVector); - } catch (Exception ex) { - logger.error("Initial TTS Vector processing error", ex); - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body(Map.of( - "status", "error", - "message", "Failed to initiate TTS Vector processing" - )); - } + return ResponseEntity.accepted().body(Map.of( + "status", "processing", + "message", "TTS Vector processing started" + )); } } \ No newline at end of file diff --git a/src/main/java/com/sayup/SayUp/controller/UserVoiceConversionController.java b/src/main/java/com/sayup/SayUp/controller/UserVoiceConversionController.java index 9ed6952..438d322 100644 --- a/src/main/java/com/sayup/SayUp/controller/UserVoiceConversionController.java +++ b/src/main/java/com/sayup/SayUp/controller/UserVoiceConversionController.java @@ -44,8 +44,6 @@ public ResponseEntity convertVoice( @RequestHeader("Authorization") String token, @RequestBody Map requestBody) { - logger.info("Voice conversion request received."); - try { // JWT 토큰에서 사용자 이메일 검증 String email = jwtTokenProvider.getUsernameFromToken(token.substring(7)); diff --git a/src/main/java/com/sayup/SayUp/security/JwtAuthenticationFilter.java b/src/main/java/com/sayup/SayUp/security/JwtAuthenticationFilter.java index 61848b4..26f1854 100644 --- a/src/main/java/com/sayup/SayUp/security/JwtAuthenticationFilter.java +++ b/src/main/java/com/sayup/SayUp/security/JwtAuthenticationFilter.java @@ -1,6 +1,7 @@ package com.sayup.SayUp.security; import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; diff --git a/src/main/java/com/sayup/SayUp/service/AuthService.java b/src/main/java/com/sayup/SayUp/service/AuthService.java index 8a4160c..b1887ba 100644 --- a/src/main/java/com/sayup/SayUp/service/AuthService.java +++ b/src/main/java/com/sayup/SayUp/service/AuthService.java @@ -39,7 +39,6 @@ public class AuthService implements UserDetailsService { private static final Logger logger = LoggerFactory.getLogger(AuthController.class); - public AuthService(UserRepository userRepository, PasswordEncoder passwordEncoder, JwtTokenProvider jwtTokenProvider, diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a0b8098..ea20519 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -37,4 +37,4 @@ springdoc.swagger-ui.tags-sorter=alpha springdoc.swagger-ui.operations-sorter=alpha # API ?? ?? -springdoc.packages-to-scan=com.sayup.SayUp.controller \ No newline at end of file +springdoc.packages-to-scan=com.sayup.SayUp.controller