Skip to content

Commit

Permalink
[Refactor] 사진 도메인을 리팩토링하고 테스트를 작성한다 (#89)
Browse files Browse the repository at this point in the history
* refactor: Image를 도메인 패키지로 변경한다

* refactor: Images의 upload 메서드가 Image 도메인 객체를 반환하도록 리팩토링한다

* refactor: ImageIdentifierGenerator를 인터페이스로 추상화하여 분리한다

* refactor: Image의 imageIdentifier 네이밍을 identifier로 변경한다

* feature: Image에 검증 로직을 추가한다

* fix: ImageIdentifier 수정으로 인한 버그를 수정한다

* test: Image 테스트를 작성한다
  • Loading branch information
vectorch9 authored Nov 4, 2023
1 parent cbef9dc commit 3f7f042
Show file tree
Hide file tree
Showing 42 changed files with 216 additions and 140 deletions.
12 changes: 6 additions & 6 deletions src/main/java/daybyquest/badge/application/SaveBadgeService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import daybyquest.badge.domain.Badge;
import daybyquest.badge.domain.Badges;
import daybyquest.global.utils.MultipartFileUtils;
import daybyquest.image.vo.Image;
import daybyquest.image.vo.ImageIdentifierGenerator;
import daybyquest.image.vo.Images;
import daybyquest.image.domain.Image;
import daybyquest.image.domain.ImageIdentifierGenerator;
import daybyquest.image.domain.Images;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
Expand All @@ -30,9 +30,9 @@ public SaveBadgeService(final Badges badges, final Images images,

@Transactional
public void invoke(final String name, final MultipartFile file) {
final String identifier = generator.generateIdentifier(CATEGORY, file.getOriginalFilename());
images.upload(identifier, MultipartFileUtils.getInputStream(file));
final Badge badge = new Badge(name, new Image(identifier));
final String identifier = generator.generate(CATEGORY, file.getOriginalFilename());
final Image image = images.upload(identifier, MultipartFileUtils.getInputStream(file));
final Badge badge = new Badge(name, image);
badges.save(badge);
}
}
2 changes: 1 addition & 1 deletion src/main/java/daybyquest/badge/domain/Badge.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import static jakarta.persistence.GenerationType.IDENTITY;

import daybyquest.global.error.exception.InvalidDomainException;
import daybyquest.image.vo.Image;
import daybyquest.image.domain.Image;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/daybyquest/badge/query/BadgeData.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package daybyquest.badge.query;

import daybyquest.image.vo.Image;
import daybyquest.image.domain.Image;
import java.time.LocalDateTime;
import lombok.Getter;

Expand All @@ -23,6 +23,6 @@ public BadgeData(final Long id, final String name, final Image image, final Loca
}

public String getImageIdentifier() {
return image.getImageIdentifier();
return image.getIdentifier();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package daybyquest.global.config;

import daybyquest.image.vo.BaseImageProperties;
import daybyquest.image.domain.BaseImageProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

Expand Down
16 changes: 8 additions & 8 deletions src/main/java/daybyquest/group/application/SaveGroupService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import daybyquest.group.domain.Group;
import daybyquest.group.domain.Groups;
import daybyquest.group.dto.request.SaveGroupRequest;
import daybyquest.image.vo.Image;
import daybyquest.image.vo.ImageIdentifierGenerator;
import daybyquest.image.vo.Images;
import daybyquest.image.domain.Image;
import daybyquest.image.domain.ImageIdentifierGenerator;
import daybyquest.image.domain.Images;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
Expand All @@ -31,14 +31,14 @@ public SaveGroupService(final Groups groups, final Images images,

@Transactional
public Long invoke(final Long loginId, final SaveGroupRequest request, final MultipartFile file) {
final String identifier = generator.generateIdentifier(CATEGORY, file.getOriginalFilename());
images.upload(identifier, MultipartFileUtils.getInputStream(file));
final Group group = toEntity(request, identifier);
final String identifier = generator.generate(CATEGORY, file.getOriginalFilename());
final Image image = images.upload(identifier, MultipartFileUtils.getInputStream(file));
final Group group = toEntity(request, image);
return groups.save(loginId, group);
}

public Group toEntity(final SaveGroupRequest request, final String imageIdentifier) {
public Group toEntity(final SaveGroupRequest request, final Image image) {
return new Group(request.getInterest(), request.getName(), request.getDescription(),
new Image(imageIdentifier));
image);
}
}
2 changes: 1 addition & 1 deletion src/main/java/daybyquest/group/domain/Group.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import static lombok.AccessLevel.PROTECTED;

import daybyquest.global.error.exception.InvalidDomainException;
import daybyquest.image.vo.Image;
import daybyquest.image.domain.Image;
import jakarta.persistence.AttributeOverride;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/daybyquest/group/query/GroupData.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package daybyquest.group.query;

import daybyquest.image.vo.Image;
import daybyquest.image.domain.Image;
import lombok.Getter;

@Getter
Expand Down Expand Up @@ -32,6 +32,6 @@ public GroupData(final Long id, final String name, final String description, fin
}

public String getImageIdentifier() {
return image.getImageIdentifier();
return image.getIdentifier();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package daybyquest.image.vo;
package daybyquest.image.domain;

import lombok.Getter;
import org.springframework.boot.context.properties.ConfigurationProperties;
Expand Down
45 changes: 45 additions & 0 deletions src/main/java/daybyquest/image/domain/Image.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package daybyquest.image.domain;

import static lombok.AccessLevel.PROTECTED;

import daybyquest.global.error.exception.InvalidDomainException;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import java.util.Objects;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Embeddable
@NoArgsConstructor(access = PROTECTED)
public class Image {

private static final int MAX_IDENTIFIER_LENGTH = 255;

@Column(nullable = false)
private String identifier;

public Image(String identifier) {
this.identifier = identifier;
validateIdentifier();
}

private void validateIdentifier() {
if (identifier == null || identifier.isEmpty() || identifier.length() > MAX_IDENTIFIER_LENGTH) {
throw new InvalidDomainException();
}
}

@Override
public boolean equals(Object o) {
if (!(o instanceof Image image)) {
return false;
}
return this.identifier.equals(image.identifier);
}

@Override
public int hashCode() {
return Objects.hashCode(identifier);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package daybyquest.image.domain;

public interface ImageIdentifierGenerator {

String generate(final String category, final String originalName);
}
10 changes: 10 additions & 0 deletions src/main/java/daybyquest/image/domain/Images.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package daybyquest.image.domain;

import java.io.InputStream;

public interface Images {

Image upload(final String identifier, final InputStream imageStream);

void remove(final String identifier);
}
6 changes: 4 additions & 2 deletions src/main/java/daybyquest/image/infra/S3Images.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import daybyquest.global.error.exception.InvalidFileException;
import daybyquest.image.vo.Images;
import daybyquest.image.domain.Image;
import daybyquest.image.domain.Images;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -24,14 +25,15 @@ public S3Images(final AmazonS3 amazonS3, @Value("${aws.bucket}") final String bu
}

@Override
public void upload(final String identifier, final InputStream imageStream) {
public Image upload(final String identifier, final InputStream imageStream) {
try {
final ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(imageStream.available());
final PutObjectRequest putObjectRequest = new PutObjectRequest(
bucket, identifier, imageStream, metadata
);
amazonS3.putObject(putObjectRequest);
return new Image(identifier);
} catch (IOException e) {
throw new InvalidFileException();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package daybyquest.image.infra;

import daybyquest.image.domain.ImageIdentifierGenerator;
import java.util.UUID;
import org.springframework.stereotype.Component;

@Component
public class UUIDImageIdentifierGenerator implements ImageIdentifierGenerator {

private static final String CATEGORY_DELIMITER = "/";

private static final String UUID_DELIMITER = "-";

@Override
public String generate(final String category, final String originalName) {
final String uuid = UUID.randomUUID().toString();
return category + CATEGORY_DELIMITER + uuid + UUID_DELIMITER + originalName;
}
}
36 changes: 0 additions & 36 deletions src/main/java/daybyquest/image/vo/Image.java

This file was deleted.

13 changes: 0 additions & 13 deletions src/main/java/daybyquest/image/vo/ImageIdentifierGenerator.java

This file was deleted.

10 changes: 0 additions & 10 deletions src/main/java/daybyquest/image/vo/Images.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package daybyquest.interest.application;

import daybyquest.global.utils.MultipartFileUtils;
import daybyquest.image.vo.Image;
import daybyquest.image.vo.ImageIdentifierGenerator;
import daybyquest.image.vo.Images;
import daybyquest.image.domain.Image;
import daybyquest.image.domain.ImageIdentifierGenerator;
import daybyquest.image.domain.Images;
import daybyquest.interest.domain.Interest;
import daybyquest.interest.domain.Interests;
import daybyquest.interest.dto.request.SaveInterestRequest;
Expand Down Expand Up @@ -31,9 +31,9 @@ public SaveInterestService(final Interests interests, final Images images,

@Transactional
public void invoke(final SaveInterestRequest request, final MultipartFile file) {
final String identifier = generator.generateIdentifier(CATEGORY, file.getOriginalFilename());
images.upload(identifier, MultipartFileUtils.getInputStream(file));
final Interest interest = new Interest(request.getName(), new Image(identifier));
final String identifier = generator.generate(CATEGORY, file.getOriginalFilename());
final Image image = images.upload(identifier, MultipartFileUtils.getInputStream(file));
final Interest interest = new Interest(request.getName(), image);
interests.save(interest);
}
}
4 changes: 2 additions & 2 deletions src/main/java/daybyquest/interest/domain/Interest.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package daybyquest.interest.domain;

import daybyquest.global.error.exception.InvalidDomainException;
import daybyquest.image.vo.Image;
import daybyquest.image.domain.Image;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
Expand Down Expand Up @@ -31,7 +31,7 @@ public Interest(final String name, final Image image) {
}

public String getImageIdentifier() {
return image.getImageIdentifier();
return image.getIdentifier();
}

private void validateName() {
Expand Down
11 changes: 5 additions & 6 deletions src/main/java/daybyquest/post/application/SavePostService.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package daybyquest.post.application;

import daybyquest.global.utils.MultipartFileUtils;
import daybyquest.image.vo.Image;
import daybyquest.image.vo.ImageIdentifierGenerator;
import daybyquest.image.vo.Images;
import daybyquest.image.domain.Image;
import daybyquest.image.domain.ImageIdentifierGenerator;
import daybyquest.image.domain.Images;
import daybyquest.post.domain.Post;
import daybyquest.post.domain.Posts;
import daybyquest.post.dto.request.SavePostRequest;
Expand Down Expand Up @@ -39,9 +39,8 @@ public Long invoke(final Long loginId, final SavePostRequest request,

private List<Image> toImageList(final List<MultipartFile> files) {
return files.stream().map((file) -> {
final String identifier = generator.generateIdentifier(CATEGORY, file.getOriginalFilename());
images.upload(identifier, MultipartFileUtils.getInputStream(file));
return new Image(identifier);
final String identifier = generator.generate(CATEGORY, file.getOriginalFilename());
return images.upload(identifier, MultipartFileUtils.getInputStream(file));
}).toList();
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/daybyquest/post/domain/Post.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import static jakarta.persistence.GenerationType.IDENTITY;

import daybyquest.global.error.exception.InvalidDomainException;
import daybyquest.image.vo.Image;
import daybyquest.image.domain.Image;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/daybyquest/post/dto/response/PostResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonFormat.Shape;
import daybyquest.image.vo.Image;
import daybyquest.image.domain.Image;
import daybyquest.post.query.PostData;
import daybyquest.user.dto.response.ProfileResponse;
import daybyquest.user.query.Profile;
Expand Down Expand Up @@ -42,7 +42,7 @@ public PostResponse(final ProfileResponse author, final Long id, final String co
public static PostResponse of(final PostData postData, final Profile profile) {
return new PostResponse(ProfileResponse.of(profile), postData.getId(), postData.getContent(),
postData.getUpdatedAt(), postData.isLiked(),
postData.getImages().stream().map(Image::getImageIdentifier).toList()
postData.getImages().stream().map(Image::getIdentifier).toList()
);
}
}
Loading

0 comments on commit 3f7f042

Please sign in to comment.