From 8a3865ab4501e76994f9f2f5cb41ba40383c12b8 Mon Sep 17 00:00:00 2001 From: amaran-th Date: Sun, 10 Dec 2023 03:23:27 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=20=EC=A4=91=20=EC=97=90=EB=9F=AC=20=EB=B0=9C?= =?UTF-8?q?=EC=83=9D=20=EC=8B=9C=20=EC=8B=A4=ED=96=89=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EB=A1=A4=EB=B0=B1=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #848 --- .../application/ImageCommandService.java | 10 +----- .../emmsale/image/application/S3Client.java | 17 +++------- .../application/MemberCommandService.java | 3 +- .../application/ImageCommandServiceTest.java | 32 ------------------- .../application/MemberCommandServiceTest.java | 8 ++--- 5 files changed, 9 insertions(+), 61 deletions(-) diff --git a/backend/emm-sale/src/main/java/com/emmsale/image/application/ImageCommandService.java b/backend/emm-sale/src/main/java/com/emmsale/image/application/ImageCommandService.java index 1adcbb1c9..29dc1a870 100644 --- a/backend/emm-sale/src/main/java/com/emmsale/image/application/ImageCommandService.java +++ b/backend/emm-sale/src/main/java/com/emmsale/image/application/ImageCommandService.java @@ -37,14 +37,7 @@ public List saveImages(final ImageType imageType, final Long contentId, validateImageCount(imageType, multipartFiles); final List imageNames = s3Client.uploadImages(multipartFiles); - - try { - return saveImagesToDb(imageType, contentId, imageNames); - } catch (Exception exception) { - s3Client.deleteImages(imageNames); - // TODO: 2023/09/15 이 동작이 실패했을 경우에 대한 처리(추후 고도화) - throw new ImageException(ImageExceptionType.FAIL_DB_UPLOAD_IMAGE); - } + return saveImagesToDb(imageType, contentId, imageNames); } private void validateContentExist(final ImageType imageType, final Long contentId) { @@ -96,6 +89,5 @@ public void deleteImages(final ImageType imageType, final Long contentId) { .collect(Collectors.toList()); imageRepository.deleteAllByIdInBatch(imageIds); s3Client.deleteImages(imageNames); - // TODO: 2023/09/15 S3의 이미지가 '일부만' 삭제되는 경우에 대한 처리(추후 고도화) } } diff --git a/backend/emm-sale/src/main/java/com/emmsale/image/application/S3Client.java b/backend/emm-sale/src/main/java/com/emmsale/image/application/S3Client.java index 84f747f77..c1f686507 100644 --- a/backend/emm-sale/src/main/java/com/emmsale/image/application/S3Client.java +++ b/backend/emm-sale/src/main/java/com/emmsale/image/application/S3Client.java @@ -12,7 +12,6 @@ import java.util.List; import java.util.Objects; import java.util.UUID; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -41,21 +40,14 @@ public S3Client( } public List uploadImages(final List multipartFiles) { - final AtomicBoolean catchException = new AtomicBoolean(false); - - final List uploadedImageNames = multipartFiles.stream() + return multipartFiles.stream() .parallel() - .map(file -> uploadImage(file, catchException)) + .map(this::uploadImage) .filter(Objects::nonNull) .collect(Collectors.toList()); - if (catchException.get()) { - deleteImages(uploadedImageNames); - throw new ImageException(ImageExceptionType.FAIL_S3_UPLOAD_IMAGE); - } - return uploadedImageNames; } - public String uploadImage(final MultipartFile file, final AtomicBoolean catchException) { + public String uploadImage(final MultipartFile file) { final String fileExtension = extractFileExtension(file); final String newFileName = UUID.randomUUID().toString().concat(fileExtension); final ObjectMetadata objectMetadata = configureObjectMetadata(file); @@ -64,8 +56,7 @@ public String uploadImage(final MultipartFile file, final AtomicBoolean catchExc amazonS3.putObject(new PutObjectRequest(bucket, newFileName, inputStream, objectMetadata)); return newFileName; } catch (final IOException | SdkClientException exception) { - catchException.set(true); - return null; + throw new ImageException(ImageExceptionType.FAIL_S3_UPLOAD_IMAGE); } } diff --git a/backend/emm-sale/src/main/java/com/emmsale/member/application/MemberCommandService.java b/backend/emm-sale/src/main/java/com/emmsale/member/application/MemberCommandService.java index 41888c4df..0c1efbc51 100644 --- a/backend/emm-sale/src/main/java/com/emmsale/member/application/MemberCommandService.java +++ b/backend/emm-sale/src/main/java/com/emmsale/member/application/MemberCommandService.java @@ -8,7 +8,6 @@ import com.emmsale.member.exception.MemberException; import com.emmsale.member.exception.MemberExceptionType; import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; import javax.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -52,7 +51,7 @@ public MemberImageResponse updateMemberProfile( s3Client.deleteImages(List.of(imageName)); } - final String imageName = s3Client.uploadImage(image, new AtomicBoolean(false)); + final String imageName = s3Client.uploadImage(image); final String imageUrl = s3Client.convertImageUrl(imageName); member.updateProfile(imageUrl); diff --git a/backend/emm-sale/src/test/java/com/emmsale/image/application/ImageCommandServiceTest.java b/backend/emm-sale/src/test/java/com/emmsale/image/application/ImageCommandServiceTest.java index 39f0e5d0a..fbd079691 100644 --- a/backend/emm-sale/src/test/java/com/emmsale/image/application/ImageCommandServiceTest.java +++ b/backend/emm-sale/src/test/java/com/emmsale/image/application/ImageCommandServiceTest.java @@ -164,38 +164,6 @@ void saveImages_fail_over_max_image_count() { assertThatThrownBy(actual).isInstanceOf(ImageException.class) .hasMessage(ImageExceptionType.OVER_MAX_IMAGE_COUNT.errorMessage()); } - - @Test - @DisplayName("이미지를 DB에 저장하는 작업이 실패하면 S3에 저장된 이미지를 삭제하고 예외를 던진다.") - void saveImages_fail_and_rollback() { - //givend - final Event event = eventRepository.save(인프콘_2023()); - final List imageNames = List.of("테스트테스트.png", "테스트테스트2.png"); - final List files = List.of( - new MockMultipartFile("test", "test.png", "", new byte[]{}), - new MockMultipartFile("test", "test.png", "", new byte[]{})); - - BDDMockito.given(s3Client.uploadImages(any())) - .willReturn(imageNames); - BDDMockito.willDoNothing().given(s3Client).deleteImages(any()); - BDDMockito.given(mockImageRepository.save(any(Image.class))) - .willThrow(new IllegalArgumentException()); - - //when - final ThrowingCallable actual = () -> imageCommandServiceWithMockImageRepository.saveImages( - ImageType.EVENT, event.getId(), files); - - //then - assertThatThrownBy(actual) - .isInstanceOf(ImageException.class) - .hasMessage(ImageExceptionType.FAIL_DB_UPLOAD_IMAGE.errorMessage()); - assertAll( - () -> verify(s3Client, times(1)) - .uploadImages(any()), - () -> verify(s3Client, times(1)) - .deleteImages(any()) - ); - } } @Nested diff --git a/backend/emm-sale/src/test/java/com/emmsale/member/application/MemberCommandServiceTest.java b/backend/emm-sale/src/test/java/com/emmsale/member/application/MemberCommandServiceTest.java index 9f2200083..d9a8495f4 100644 --- a/backend/emm-sale/src/test/java/com/emmsale/member/application/MemberCommandServiceTest.java +++ b/backend/emm-sale/src/test/java/com/emmsale/member/application/MemberCommandServiceTest.java @@ -5,10 +5,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertAll; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -148,7 +146,7 @@ class UpdateProfile { @BeforeEach void setUp() { ReflectionTestUtils.setField(s3Client, "bucket", bucket); - when(s3Client.uploadImage(eq(image), any())).thenReturn(imageName); + when(s3Client.uploadImage(image)).thenReturn(imageName); when(s3Client.convertImageUrl(anyString())).thenCallRealMethod(); when(s3Client.convertImageName(anyString())).thenCallRealMethod(); } @@ -168,7 +166,7 @@ void pastGithubUrl() { () -> assertThat(member.getImageUrl()) .isEqualTo(s3Client.convertImageUrl(imageName)), () -> verify(s3Client, times(1)) - .uploadImage(eq(image), any()) + .uploadImage(image) ); } @@ -188,7 +186,7 @@ void pastCustomImage() { () -> assertThat(member.getImageUrl()) .isEqualTo(s3Client.convertImageUrl(imageName)), () -> verify(s3Client, times(1)) - .uploadImage(eq(image), any()), + .uploadImage(image), () -> verify(s3Client, times(1)) .deleteImages(anyList()) );