diff --git a/gotcha-common/src/main/java/gotcha_common/s3/S3ClientService.java b/gotcha-common/src/main/java/gotcha_common/s3/S3ClientService.java deleted file mode 100644 index 3761ecda..00000000 --- a/gotcha-common/src/main/java/gotcha_common/s3/S3ClientService.java +++ /dev/null @@ -1,42 +0,0 @@ - - -package gotcha_common.s3; - - -import gotcha_common.exception.CustomException; -import gotcha_common.exception.exceptionCode.GlobalExceptionCode; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; -import software.amazon.awssdk.core.sync.RequestBody; -import software.amazon.awssdk.services.s3.S3Client; -import software.amazon.awssdk.services.s3.model.PutObjectRequest; -import software.amazon.awssdk.services.s3.model.S3Exception; - -import java.io.IOException; - - -@Service -@RequiredArgsConstructor -public class S3ClientService { - private final S3Client s3Client; - - @Value("${spring.cloud.aws.s3.bucket-name}") - private String bucketName; - - // MultipartFile 이미지를 그대로 S3에 업로드 - public void uploadFile(String filename, MultipartFile file){ - try { - PutObjectRequest request = PutObjectRequest.builder() - .bucket(bucketName) - .key(filename) - .contentType(file.getContentType()) - .build(); - s3Client.putObject(request, RequestBody.fromInputStream(file.getInputStream(), file.getSize())); - } catch(IOException e){ - throw new CustomException(GlobalExceptionCode.FILE_PROCESS_ERROR); - } - } - -} diff --git a/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIGuessImageReq.java b/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIGuessImageReq.java index 53735a60..949dc042 100644 --- a/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIGuessImageReq.java +++ b/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIGuessImageReq.java @@ -1,6 +1,6 @@ package socket_server.domain.game.dto; public record AIGuessImageReq( - String imageURL + String image_url ) { } diff --git a/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIGuessMessageReq.java b/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIGuessMessageReq.java index 5831a0bd..9360f48b 100644 --- a/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIGuessMessageReq.java +++ b/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIGuessMessageReq.java @@ -1,6 +1,6 @@ package socket_server.domain.game.dto; public record AIGuessMessageReq( - String imageDescription + String image_description ) { } diff --git a/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIGuessReactReq.java b/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIGuessReactReq.java index 5fd4d614..ead86a56 100644 --- a/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIGuessReactReq.java +++ b/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIGuessReactReq.java @@ -1,7 +1,7 @@ package socket_server.domain.game.dto; public record AIGuessReactReq( - boolean isCorrect, + boolean is_correct, String answer, String guesser ) { diff --git a/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIGuessStartReq.java b/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIGuessStartReq.java index b2a92719..27f91f95 100644 --- a/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIGuessStartReq.java +++ b/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIGuessStartReq.java @@ -4,8 +4,8 @@ * 추측 시작 시(GUESS_REQUEST) AI서버로 보낼 DTO */ public record AIGuessStartReq( - int roundNum, - int totalRounds, + int round_num, + int total_rounds, String drawer, String guesser ) { diff --git a/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIRoundStartReq.java b/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIRoundStartReq.java index 46e4cf8f..2c8658fa 100644 --- a/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIRoundStartReq.java +++ b/gotcha-socket/src/main/java/socket_server/domain/game/dto/AIRoundStartReq.java @@ -4,7 +4,7 @@ * 라운드 시작 시 AI 서버에 보낼 DTO */ public record AIRoundStartReq( - int roundNum, - int totalRounds + int round_num, + int total_rounds ) { } diff --git a/gotcha-socket/src/main/java/socket_server/domain/game/service/AIClientService.java b/gotcha-socket/src/main/java/socket_server/domain/game/service/AIClientService.java index 9d57180c..735c40d9 100644 --- a/gotcha-socket/src/main/java/socket_server/domain/game/service/AIClientService.java +++ b/gotcha-socket/src/main/java/socket_server/domain/game/service/AIClientService.java @@ -30,7 +30,7 @@ public class AIClientService { public String getGameStartMessage(String roomId, AIGameStartReq request){ try { return webClient.post() - .uri(AI_SERVER_BASE_URL + "chat/" + roomId + "/start") + .uri(AI_SERVER_BASE_URL + "myomyo/" + roomId + "/start") .bodyValue(request) .retrieve() .onStatus(httpStatusCode -> httpStatusCode.is4xxClientError() || httpStatusCode.is5xxServerError() @@ -48,7 +48,7 @@ public String getGameStartMessage(String roomId, AIGameStartReq request){ public String getRoundStartMessage(String roomId, AIRoundStartReq request){ try { return webClient.post() - .uri(AI_SERVER_BASE_URL + "chat/" + roomId + "/round/start") + .uri(AI_SERVER_BASE_URL + "myomyo/" + roomId + "/round/start") .bodyValue(request) .retrieve() .onStatus(httpStatusCode -> httpStatusCode.is4xxClientError() || httpStatusCode.is5xxServerError() @@ -66,7 +66,7 @@ public String getRoundStartMessage(String roomId, AIRoundStartReq request){ public String getGuessStartMessage(String roomId, AIGuessStartReq request){ try { return webClient.post() - .uri(AI_SERVER_BASE_URL + "chat/" + roomId + "/guess/start") + .uri(AI_SERVER_BASE_URL + "myomyo/" + roomId + "/guess/start") .bodyValue(request) .retrieve() .onStatus(httpStatusCode -> httpStatusCode.is4xxClientError() || httpStatusCode.is5xxServerError(), @@ -84,7 +84,7 @@ public String getGuessStartMessage(String roomId, AIGuessStartReq request){ public AIGuessImageRes getGuessImage(AIGuessImageReq request){ try { return webClient.post() - .uri(AI_SERVER_BASE_URL + "image/classify") + .uri(AI_SERVER_BASE_URL + "classify") .bodyValue(request) .retrieve() .onStatus(httpStatusCode -> httpStatusCode.is4xxClientError() || httpStatusCode.is5xxServerError() @@ -101,7 +101,7 @@ public AIGuessImageRes getGuessImage(AIGuessImageReq request){ public String getGuessMessage(String roomId, AIGuessMessageReq request){ try { return webClient.post() - .uri(AI_SERVER_BASE_URL + "chat/" + roomId + "/guess") + .uri(AI_SERVER_BASE_URL + "myomyo/" + roomId + "/guess") .bodyValue(request) .retrieve() .onStatus(httpStatusCode -> httpStatusCode.is4xxClientError() || httpStatusCode.is5xxServerError() @@ -119,7 +119,7 @@ public String getGuessMessage(String roomId, AIGuessMessageReq request){ public String getGuessReactMessage(String roomId, AIGuessReactReq request){ try { return webClient.post() - .uri(AI_SERVER_BASE_URL + "chat/" + roomId + "/guess/react") + .uri(AI_SERVER_BASE_URL + "myomyo/" + roomId + "/guess/react") .bodyValue(request) .retrieve() .onStatus(httpStatusCode -> httpStatusCode.is4xxClientError() || httpStatusCode.is5xxServerError() @@ -137,7 +137,7 @@ public String getGuessReactMessage(String roomId, AIGuessReactReq request){ public String getRoundEndMessage(String roomId, AIRoundEndReq request){ try { return webClient.post() - .uri(AI_SERVER_BASE_URL + "chat/" + roomId + "/round/end") + .uri(AI_SERVER_BASE_URL + "myomyo/" + roomId + "/round/end") .bodyValue(request) .retrieve() .onStatus(httpStatusCode -> httpStatusCode.is4xxClientError() || httpStatusCode.is5xxServerError() @@ -155,7 +155,7 @@ public String getRoundEndMessage(String roomId, AIRoundEndReq request){ public String getGameEndMessage(String roomId, AIGameEndReq request) { try { return webClient.post() - .uri(AI_SERVER_BASE_URL + "chat/" + roomId + "/end") + .uri(AI_SERVER_BASE_URL + "myomyo/" + roomId + "/end") .bodyValue(request) .retrieve() .onStatus(httpStatusCode -> httpStatusCode.is4xxClientError() || httpStatusCode.is5xxServerError() diff --git a/gotcha-socket/src/main/java/socket_server/domain/game/service/GameEndService.java b/gotcha-socket/src/main/java/socket_server/domain/game/service/GameEndService.java index 948ded4c..0dec9994 100644 --- a/gotcha-socket/src/main/java/socket_server/domain/game/service/GameEndService.java +++ b/gotcha-socket/src/main/java/socket_server/domain/game/service/GameEndService.java @@ -100,6 +100,7 @@ public void updateScore(Game game){ } public void flushGame(GameMeta gameMeta) { + log.info("Flushing game data for roomId: {}", gameMeta.getRoomId()); //1. roomId 기반 삭제 gameRepository.deleteGameMeta(gameMeta.getRoomId()); diff --git a/gotcha/src/main/java/Gotcha/domain/image/api/ImageApi.java b/gotcha/src/main/java/Gotcha/domain/image/api/ImageApi.java deleted file mode 100644 index 7b8c5a75..00000000 --- a/gotcha/src/main/java/Gotcha/domain/image/api/ImageApi.java +++ /dev/null @@ -1,45 +0,0 @@ -package Gotcha.domain.image.api; - - -import gotcha_domain.auth.SecurityUserDetails; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.ExampleObject; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.multipart.MultipartFile; - -@Tag(name = "[이미지 업로드 API]", description = "이미지 업로드 API") -public interface ImageApi { - - @Operation(summary = "이미지 업로드", description = "이미지 업로드 API, png, jpg, jpeg 파일만 허용합니다.") - @ApiResponses({ - @ApiResponse(responseCode = "200", description = "이미지 업로드 성공", - content = @Content(mediaType = "application/json", examples = { - @ExampleObject(value = """ - { - "status": "OK", - "message": "https://gotchaai-image-bucket.s3.ap-northeast-2.amazonaws.com/useruuid/6a0f9e3d-1b2c-4d5e-8f2a-8b02f60d92e4.jpg - " - } - """) - }) - ), - @ApiResponse(responseCode = "400", description = "유효하지 않은 파일 확장자(png, jpg, jpeg만 허용)", - content = @Content(mediaType = "application/json", examples = { - @ExampleObject(value = """ - { - "status": "BAD_REQUEST", - "code" : "IMAGE-400-001", - "message": "이미지 타입이 유효하지 않습니다.(png, jpg, jpeg만 허용)" - } - """) - }) - ), - }) - ResponseEntity uploadImage(@RequestParam("file") MultipartFile file, SecurityUserDetails userDetails); -} diff --git a/gotcha/src/main/java/Gotcha/domain/image/controller/ImageController.java b/gotcha/src/main/java/Gotcha/domain/image/controller/ImageController.java deleted file mode 100644 index 4a41df05..00000000 --- a/gotcha/src/main/java/Gotcha/domain/image/controller/ImageController.java +++ /dev/null @@ -1,32 +0,0 @@ -package Gotcha.domain.image.controller; - -import Gotcha.domain.image.api.ImageApi; -import Gotcha.domain.image.service.ImageService; -import gotcha_common.dto.SuccessRes; -import gotcha_domain.auth.SecurityUserDetails; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -@RestController -@RequestMapping("/api/v1/image") -@RequiredArgsConstructor -@Slf4j -public class ImageController implements ImageApi { - - private final ImageService imageService; - - - @PostMapping("/upload") - public ResponseEntity uploadImage(@RequestParam("file") MultipartFile file, @AuthenticationPrincipal SecurityUserDetails userDetails) { - String filename = imageService.uploadImage(userDetails.getUuid(), file); - return ResponseEntity.ok(SuccessRes.from(filename)); - } - -} diff --git a/gotcha/src/main/java/Gotcha/domain/image/exception/ImageExceptionCode.java b/gotcha/src/main/java/Gotcha/domain/image/exception/ImageExceptionCode.java deleted file mode 100644 index 06eaadcb..00000000 --- a/gotcha/src/main/java/Gotcha/domain/image/exception/ImageExceptionCode.java +++ /dev/null @@ -1,30 +0,0 @@ -package Gotcha.domain.image.exception; - -import gotcha_common.exception.exceptionCode.ExceptionCode; -import lombok.AllArgsConstructor; -import org.springframework.http.HttpStatus; - -@AllArgsConstructor -public enum ImageExceptionCode implements ExceptionCode { - INVALID_IMAGE_TYPE(HttpStatus.BAD_REQUEST, "IMAGE-400-001", "이미지 타입이 유효하지 않습니다.(png, jpg, jpeg만 허용)"); - - private final HttpStatus status; - private final String code; - private final String message; - - - @Override - public String getCode() { - return code; - } - - @Override - public HttpStatus getStatus() { - return status; - } - - @Override - public String getMessage() { - return message; - } -} diff --git a/gotcha/src/main/java/Gotcha/domain/image/service/ImageService.java b/gotcha/src/main/java/Gotcha/domain/image/service/ImageService.java deleted file mode 100644 index 5e87f462..00000000 --- a/gotcha/src/main/java/Gotcha/domain/image/service/ImageService.java +++ /dev/null @@ -1,46 +0,0 @@ -package Gotcha.domain.image.service; - -import Gotcha.domain.image.exception.ImageExceptionCode; -import gotcha_common.exception.CustomException; -import gotcha_common.s3.S3ClientService; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; - -import java.util.UUID; - -@Service -@RequiredArgsConstructor -public class ImageService { - - private final S3ClientService s3ClientService; - - @Value("${spring.cloud.aws.region.static}") - private String region; - @Value("${spring.cloud.aws.s3.bucket-name}") - private String bucketName; - - public String uploadImage(String userUuid, MultipartFile file) { - String filename = generateUserFileName(userUuid, file); - s3ClientService.uploadFile(filename, file); - return String.format("https://%s.s3.%s.amazonaws.com/%s", bucketName, region, filename); - } - - private String generateUserFileName(String userUuid, MultipartFile file) { - String originalFilename = file.getOriginalFilename(); - String extension = ""; - - if (originalFilename != null && originalFilename.contains(".")) { - extension = originalFilename.substring(originalFilename.lastIndexOf(".")); - } - - if(extension.isEmpty() || (!extension.equals(".jpg") && !extension.equals(".png") && !extension.equals(".jpeg"))){ - throw new CustomException(ImageExceptionCode.INVALID_IMAGE_TYPE); - } - - String uuid = UUID.randomUUID().toString(); - return userUuid + "/" + uuid + extension; - } - -} diff --git a/gotcha/src/main/java/Gotcha/domain/lulu/service/LuLuAIClientService.java b/gotcha/src/main/java/Gotcha/domain/lulu/service/LuLuAIClientService.java index f2a6d582..4a1495ee 100644 --- a/gotcha/src/main/java/Gotcha/domain/lulu/service/LuLuAIClientService.java +++ b/gotcha/src/main/java/Gotcha/domain/lulu/service/LuLuAIClientService.java @@ -116,7 +116,7 @@ private TaskEvalRes requestEvaluate(String gameId, String imageCaption){ public String getImageCaption(String imageUrl){ Map body = Map.of("imageURL", imageUrl); return webClient.post() - .uri(AI_SERVER_BASE_URL + "image/caption") + .uri(AI_SERVER_BASE_URL + "caption") .bodyValue(body) .retrieve() .onStatus(httpStatusCode -> httpStatusCode.is4xxClientError() || httpStatusCode.is5xxServerError( diff --git a/gotcha/src/main/resources/application.yml b/gotcha/src/main/resources/application.yml index 3ab8b25a..10322a2e 100644 --- a/gotcha/src/main/resources/application.yml +++ b/gotcha/src/main/resources/application.yml @@ -25,16 +25,7 @@ spring: timeout: 5000 starttls: enable: true - cloud: - aws: - credentials: - access-key: ${AWS_S3_ACCESS_KEY} - secret-key: ${AWS_S3_SECRET_KEY} - s3: - bucket-name: ${AWS_S3_BUCKET_NAME} - region: - static: ${AWS_S3_REGION} data: redis: host: ${REDIS_HOST:localhost} @@ -68,4 +59,4 @@ server: address: 0.0.0.0 ai-server: - url: ${AI_SERVER_API} \ No newline at end of file + url: ${AI_SERVER_API:http://localhost:8000/api/v1/} \ No newline at end of file