Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -75,3 +78,4 @@ dependencies {
tasks.named('test') {
useJUnitPlatform()
}

16 changes: 16 additions & 0 deletions src/main/java/com/sayup/SayUp/aop/Logging.java
Original file line number Diff line number Diff line change
Expand Up @@ -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์—์„œ ์˜ˆ์™ธ๋ฅผ ํ•ธ๋“ค๋งํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ ์ ˆํ•œ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ ๊ฐ€๋Šฅ)
}
}
}

21 changes: 4 additions & 17 deletions src/main/java/com/sayup/SayUp/controller/AuthController.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,13 @@
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.*;

@RestController
@RequestMapping("/api/auth")
public class AuthController {
private static final Logger logger = LoggerFactory.getLogger(AuthController.class);
private final AuthService authService;

public AuthController(AuthService authService) {
Expand All @@ -28,13 +25,8 @@ public AuthController(AuthService authService) {
*/
@PostMapping("/register")
public ResponseEntity<String> 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!");
}

/**
Expand All @@ -44,13 +36,8 @@ public ResponseEntity<String> register(@RequestBody @Valid UserDTO userDTO) {
*/
@PostMapping("/login")
public ResponseEntity<AuthResponseDTO> 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);
}

/**
Expand Down
51 changes: 9 additions & 42 deletions src/main/java/com/sayup/SayUp/controller/FriendshipController.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<List<User>> getFriendsList(
@AuthenticationPrincipal UserDetails userDetails) {
public ResponseEntity<List<User>> 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<List<PendingRequestDTO>> 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<PendingRequestDTO> pendingRequests = friendshipService.getPendingRequests(userDetails);
return ResponseEntity.ok(pendingRequests);
return ResponseEntity.ok(friendshipService.getPendingRequests(userDetails));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -14,30 +12,18 @@
@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) {
this.userVoiceService = userVoiceService;
}

@PostMapping(consumes = {"multipart/form-data"})
public ResponseEntity<String> uploadFile(
@RequestHeader("Authorization") String token,
@RequestParam("file")MultipartFile file){
logger.info("File upload request received.");

public ResponseEntity<String> 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<String> 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand All @@ -34,46 +29,32 @@ public UserTTSVectorController(JwtTokenProvider jwtTokenProvider,
@Async
public CompletableFuture<Void> 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<Map<String, String>> initiateVectorSave(
@RequestHeader("Authorization") String token,
@RequestBody Map<String, String> body) {
public ResponseEntity<Map<String, String>> initiateVectorSave(@RequestHeader("Authorization") String token, @RequestBody Map<String, String> 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"
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ public ResponseEntity<?> convertVoice(
@RequestHeader("Authorization") String token,
@RequestBody Map<String, String> requestBody) {

logger.info("Voice conversion request received.");

try {
// JWT ํ† ํฐ์—์„œ ์‚ฌ์šฉ์ž ์ด๋ฉ”์ผ ๊ฒ€์ฆ
String email = jwtTokenProvider.getUsernameFromToken(token.substring(7));
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/sayup/SayUp/service/AuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
springdoc.packages-to-scan=com.sayup.SayUp.controller