-
Notifications
You must be signed in to change notification settings - Fork 8
refactor: s3 버전 업그레이드 및 로직 수정 #608
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from 2 commits
8bc53a7
6210cac
4a020d6
e799840
18b9039
a709bdf
1bd38ee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,7 @@ | |
| import com.example.solidconnection.mentor.repository.MentorRepository; | ||
| import com.example.solidconnection.siteuser.domain.SiteUser; | ||
| import com.example.solidconnection.siteuser.repository.SiteUserRepository; | ||
| import java.util.Arrays; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
|
|
@@ -39,6 +40,7 @@ | |
| import org.springframework.messaging.simp.SimpMessageSendingOperations; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
| import org.springframework.util.StringUtils; | ||
|
|
||
| @Service | ||
| public class ChatService { | ||
|
|
@@ -240,16 +242,19 @@ public void sendChatImage(ChatImageSendRequest chatImageSendRequest, long siteUs | |
| ChatRoom chatRoom = chatRoomRepository.findById(roomId) | ||
| .orElseThrow(() -> new CustomException(INVALID_CHAT_ROOM_STATE)); | ||
|
|
||
| ChatMessage chatMessage = new ChatMessage( | ||
| "", | ||
| senderId, | ||
| chatRoom | ||
| ); | ||
| ChatMessage chatMessage = new ChatMessage("", senderId, chatRoom); | ||
|
|
||
| // 이미지 판별을 위한 확장자 리스트 | ||
| List<String> imageExtensions = Arrays.asList("jpg", "jpeg", "png", "webp"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분은 enum으로 관리하는 건 어떻게 생각하시나요? |
||
|
|
||
| for (String imageUrl : chatImageSendRequest.imageUrls()) { | ||
| String thumbnailUrl = generateThumbnailUrl(imageUrl); | ||
| String extension = StringUtils.getFilenameExtension(imageUrl); | ||
|
|
||
| ChatAttachment attachment = new ChatAttachment(true, imageUrl, thumbnailUrl, null); | ||
| boolean isImage = extension != null && imageExtensions.contains(extension.toLowerCase()); | ||
|
|
||
| String thumbnailUrl = isImage ? generateThumbnailUrl(imageUrl) : null; | ||
|
|
||
| ChatAttachment attachment = new ChatAttachment(isImage, imageUrl, thumbnailUrl, null); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thumbnailUrl이 null인 경우에 대해 방어 로직이 존재하나요?? 이번 pr 상에서는 안보여서... (개인적으로 gif나 avif 이미지 파일 확장자도 잘 쓰인다고 생각해서 확인 한 번 해주시면 감사드리겠습니다!) |
||
| chatMessage.addAttachment(attachment); | ||
| } | ||
|
|
||
|
|
@@ -268,11 +273,9 @@ private String generateThumbnailUrl(String originalUrl) { | |
|
|
||
| String thumbnailFileName = nameWithoutExt + "_thumb" + extension; | ||
|
|
||
| String thumbnailUrl = originalUrl.replace("chat/images/", "chat/thumbnails/") | ||
| return originalUrl.replace("chat/files/", "chat/thumbnails/") | ||
| .replace(fileName, thumbnailFileName); | ||
|
|
||
| return thumbnailUrl; | ||
|
|
||
| } catch (Exception e) { | ||
| return originalUrl; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,19 +3,19 @@ | |
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| public enum ImgType { | ||
| public enum UploadType { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저에게는 UploadType이 직관적으로는 업로드한 파일이 어떤 타입인지, 즉 파일 확장자를 구별하는 걸로 느껴집니다..! (추신 : 제미나이가 추천한 이름은 |
||
| PROFILE("profile"), | ||
| GPA("gpa"), | ||
| LANGUAGE_TEST("language"), | ||
| COMMUNITY("community"), | ||
| NEWS("news"), | ||
| CHAT("chat"), | ||
| CHAT("chat/files"), | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이미 |
||
| MENTOR_PROOF("mentor-proof"), | ||
| ; | ||
|
|
||
| private final String type; | ||
|
|
||
| ImgType(String type) { | ||
| UploadType(String type) { | ||
| this.type = type; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,51 +1,49 @@ | ||
| package com.example.solidconnection.s3.service; | ||
| package com.example.solidconnection.s3.service; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| import static com.example.solidconnection.common.exception.ErrorCode.S3_CLIENT_EXCEPTION; | ||
| import static com.example.solidconnection.common.exception.ErrorCode.S3_SERVICE_EXCEPTION; | ||
| import static com.example.solidconnection.common.exception.ErrorCode.S3_CLIENT_EXCEPTION; | ||
| import static com.example.solidconnection.common.exception.ErrorCode.S3_SERVICE_EXCEPTION; | ||
|
|
||
| import com.amazonaws.AmazonServiceException; | ||
| import com.amazonaws.SdkClientException; | ||
| import com.amazonaws.services.s3.AmazonS3Client; | ||
| import com.amazonaws.services.s3.model.CannedAccessControlList; | ||
| import com.amazonaws.services.s3.model.ObjectMetadata; | ||
| import com.amazonaws.services.s3.model.PutObjectRequest; | ||
| import com.example.solidconnection.common.exception.CustomException; | ||
| import java.io.IOException; | ||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.springframework.scheduling.annotation.Async; | ||
| import org.springframework.scheduling.annotation.EnableAsync; | ||
| import org.springframework.stereotype.Component; | ||
| import org.springframework.web.multipart.MultipartFile; | ||
| import com.example.solidconnection.common.exception.CustomException; | ||
| import java.io.IOException; | ||
| import lombok.RequiredArgsConstructor; | ||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.springframework.scheduling.annotation.Async; | ||
| import org.springframework.stereotype.Component; | ||
| import org.springframework.web.multipart.MultipartFile; | ||
| import software.amazon.awssdk.core.exception.SdkException; | ||
| import software.amazon.awssdk.core.sync.RequestBody; | ||
| import software.amazon.awssdk.services.s3.S3Client; | ||
| import software.amazon.awssdk.services.s3.model.ObjectCannedACL; | ||
| import software.amazon.awssdk.services.s3.model.PutObjectRequest; | ||
| import software.amazon.awssdk.services.s3.model.S3Exception; | ||
|
|
||
| @Component | ||
| @EnableAsync | ||
| @Slf4j | ||
| public class FileUploadService { | ||
| @Component | ||
| @Slf4j | ||
| @RequiredArgsConstructor | ||
| public class FileUploadService { | ||
|
|
||
| private final AmazonS3Client amazonS3; | ||
| private final S3Client s3Client; | ||
|
|
||
| public FileUploadService(AmazonS3Client amazonS3) { | ||
| this.amazonS3 = amazonS3; | ||
| } | ||
| @Async | ||
| public void uploadFile(String bucket, String fileName, MultipartFile multipartFile) { | ||
|
Comment on lines
+27
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# `@EnableAsync` 설정 확인
rg -n "@EnableAsync" --type javaRepository: solid-connection/solid-connect-server Length of output: 287 🏁 Script executed: #!/bin/bash
# 두 파일의 내용 확인 - `@EnableAsync` 주변 컨텍스트
echo "=== UpdateViewCountScheduler.java ==="
sed -n '1,30p' src/main/java/com/example/solidconnection/scheduler/UpdateViewCountScheduler.java
echo -e "\n=== UpdateViewCountService.java ==="
sed -n '1,30p' src/main/java/com/example/solidconnection/community/post/service/UpdateViewCountService.javaRepository: solid-connection/solid-connect-server Length of output: 2450
다음과 같은 사항을 확인했습니다:
🤖 Prompt for AI Agents
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이건 나중에 한 번에 바꿔야 할 것 같네 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
필요하시다면 추적을 위한 GitHub 이슈를 생성해 드릴까요? 이슈에 현재 상황과 개선 방향을 정리해 두면 나중에 작업하실 때 도움이 될 것 같습니다. |
||
| try { | ||
| PutObjectRequest putObjectRequest = PutObjectRequest.builder() | ||
| .bucket(bucket) | ||
| .key(fileName) | ||
| .contentType(multipartFile.getContentType()) | ||
| .contentLength(multipartFile.getSize()) | ||
| .build(); | ||
|
|
||
| @Async | ||
| public void uploadFile(String bucket, String fileName, MultipartFile multipartFile) { | ||
| // 메타데이터 생성 | ||
| String contentType = multipartFile.getContentType(); | ||
| ObjectMetadata metadata = new ObjectMetadata(); | ||
| metadata.setContentType(contentType); | ||
| metadata.setContentLength(multipartFile.getSize()); | ||
| s3Client.putObject(putObjectRequest, | ||
| RequestBody.fromInputStream(multipartFile.getInputStream(), multipartFile.getSize())); | ||
|
|
||
| try { | ||
| amazonS3.putObject(new PutObjectRequest(bucket, fileName, multipartFile.getInputStream(), metadata) | ||
| .withCannedAcl(CannedAccessControlList.PublicRead)); | ||
| log.info("이미지 업로드 정상적 완료 thread: {}", Thread.currentThread().getName()); | ||
| } catch (AmazonServiceException e) { | ||
| log.error("이미지 업로드 중 s3 서비스 예외 발생 : {}", e.getMessage()); | ||
| throw new CustomException(S3_SERVICE_EXCEPTION); | ||
| } catch (SdkClientException | IOException e) { | ||
| log.error("이미지 업로드 중 s3 클라이언트 예외 발생 : {}", e.getMessage()); | ||
| throw new CustomException(S3_CLIENT_EXCEPTION); | ||
| log.info("파일 업로드 정상 완료 thread: {}", Thread.currentThread().getName()); | ||
| } catch (S3Exception e) { | ||
| log.error("S3 서비스 예외 발생 : {}", e.awsErrorDetails().errorMessage()); | ||
| throw new CustomException(S3_SERVICE_EXCEPTION); | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } catch (SdkException | IOException e) { | ||
| log.error("S3 클라이언트 또는 IO 예외 발생 : {}", e.getMessage()); | ||
| throw new CustomException(S3_CLIENT_EXCEPTION); | ||
| } | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이건 상수로 빼는 건 어떤가요 ?