Skip to content

Commit

Permalink
[BE] 팀채팅시 이벤트 발행에 db조회 제거 (#956)
Browse files Browse the repository at this point in the history
* refactor: 피드 도메인 이벤트에 작성된 피드 내용 데이터 추가

FeedResponse, FeedImageResponse 사용

* refactor: SSE용 이벤트 변환시 db조회 제거
  • Loading branch information
pilyang authored Mar 12, 2024
1 parent 681f55e commit 9ec31a8
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,7 @@ private FeedResponse mapToResponse(final Feed feed, final MemberTeamPlace author

private List<FeedImageResponse> mapToFeedImageResponse(final FeedThread feedThread) {
final List<FeedThreadImage> images = feedThread.getImages();
return images.stream().map(feedThreadImage ->
new FeedImageResponse(
feedThreadImage.getId(),
feedThreadImage.isExpired(),
feedThreadImage.getImageName().getValue(),
feedThreadImage.getImageUrl().getValue()))
return images.stream().map(FeedImageResponse::from)
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import team.teamby.teambyteam.feed.application.dto.FeedImageResponse;
import team.teamby.teambyteam.feed.application.dto.FeedResponse;
import team.teamby.teambyteam.feed.application.dto.FeedThreadWritingRequest;
import team.teamby.teambyteam.feed.application.event.FeedEvent;
import team.teamby.teambyteam.feed.domain.FeedRepository;
Expand All @@ -22,9 +24,11 @@
import team.teamby.teambyteam.filesystem.util.FileUtil;
import team.teamby.teambyteam.member.configuration.dto.MemberEmailDto;
import team.teamby.teambyteam.member.domain.MemberRepository;
import team.teamby.teambyteam.member.domain.MemberTeamPlace;
import team.teamby.teambyteam.member.domain.MemberTeamPlaceRepository;
import team.teamby.teambyteam.member.domain.vo.Email;
import team.teamby.teambyteam.member.exception.MemberException;
import team.teamby.teambyteam.member.exception.MemberTeamPlaceException;

import java.util.List;
import java.util.Objects;
Expand All @@ -43,6 +47,7 @@ public class FeedWriteService {
private final FeedRepository feedRepository;
private final FeedThreadImageRepository feedThreadImageRepository;
private final MemberRepository memberRepository;
private final MemberTeamPlaceRepository memberTeamPlaceRepository;
private final FileStorageManager fileStorageManager;

@Value("${aws.s3.image-directory}")
Expand All @@ -61,14 +66,22 @@ public Long write(
final Long memberId = memberRepository.findIdByEmail(new Email(memberEmailDto.email()))
.orElseThrow(() -> new MemberException.MemberNotFoundException(memberEmailDto.email()))
.id();
final MemberTeamPlace author = memberTeamPlaceRepository.findByTeamPlaceIdAndMemberId(teamPlaceId, memberId)
.orElseThrow(() -> new MemberTeamPlaceException.NotFoundParticipatedTeamPlaceException(memberEmailDto.email(), teamPlaceId));

final FeedThread savedFeedThread = feedRepository.save(new FeedThread(teamPlaceId, new Content(content), memberId));
saveImages(images, savedFeedThread);
final List<FeedImageResponse> imageResponses = saveImages(images, savedFeedThread);

final Long threadId = savedFeedThread.getId();
log.info("스레드 생성 - 생성자 이메일 : {}, 스레드 아이디 : {}", memberEmailDto.email(), threadId);

sendFeedWritingEvent(savedFeedThread);
final FeedResponse responseForMe = FeedResponse.from(
savedFeedThread,
author,
imageResponses,
memberEmailDto.email()
);
sendFeedWritingEvent(responseForMe, teamPlaceId);

return threadId;
}
Expand Down Expand Up @@ -99,19 +112,21 @@ private void validateImage(final MultipartFile image) {
}
}

private void saveImages(final List<MultipartFile> images, final FeedThread savedFeedThread) {
images.forEach(image -> {
final String originalFilename = image.getOriginalFilename();
final String generatedImageUrl = fileStorageManager.upload(image, imageDirectory + "/" + UUID.randomUUID(), originalFilename);
final ImageUrl imageUrl = new ImageUrl(generatedImageUrl);
final ImageName imageName = new ImageName(originalFilename);
final FeedThreadImage feedThreadImage = new FeedThreadImage(imageUrl, imageName);
feedThreadImage.confirmFeedThread(savedFeedThread);
feedThreadImageRepository.save(feedThreadImage);
});
private List<FeedImageResponse> saveImages(final List<MultipartFile> images, final FeedThread savedFeedThread) {
return images.stream().map(image -> {
final String originalFilename = image.getOriginalFilename();
final String generatedImageUrl = fileStorageManager.upload(image, imageDirectory + "/" + UUID.randomUUID(), originalFilename);
final ImageUrl imageUrl = new ImageUrl(generatedImageUrl);
final ImageName imageName = new ImageName(originalFilename);
final FeedThreadImage feedThreadImage = new FeedThreadImage(imageUrl, imageName);
feedThreadImage.confirmFeedThread(savedFeedThread);
return feedThreadImageRepository.save(feedThreadImage);
})
.map(FeedImageResponse::from)
.toList();
}

private void sendFeedWritingEvent(final FeedThread savedFeedThread) {
applicationEventPublisher.publishEvent(new FeedEvent(savedFeedThread.getId()));
private void sendFeedWritingEvent(final FeedResponse response, final Long teamPlaceId) {
applicationEventPublisher.publishEvent(new FeedEvent(response, teamPlaceId));
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
package team.teamby.teambyteam.feed.application.dto;

import team.teamby.teambyteam.feed.domain.image.FeedThreadImage;

public record FeedImageResponse(
Long id,
Boolean isExpired,
String name,
String url
) {

public static FeedImageResponse from(final FeedThreadImage feedThreadImage) {
return new FeedImageResponse(
feedThreadImage.getId(),
feedThreadImage.isExpired(),
feedThreadImage.getImageName().getValue(),
feedThreadImage.getImageUrl().getValue()
);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
package team.teamby.teambyteam.feed.application.event;

import team.teamby.teambyteam.common.domain.DomainEvent;
import team.teamby.teambyteam.feed.application.dto.FeedResponse;

public class FeedEvent implements DomainEvent<Long> {
private final Long feedId;
private final Long teamPlaceId;
private final FeedResponse response;

public FeedEvent(final Long feedId) {
this.feedId = feedId;
public FeedEvent(final FeedResponse response, final Long teamPlaceId) {
this.feedId = response.id();
this.response = response;
this.teamPlaceId = teamPlaceId;
}

@Override
public Long getDomainId() {
return feedId;
}

public FeedResponse response() {
return response;
}

public Long getTeamPlaceId() {
return teamPlaceId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,23 @@
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import team.teamby.teambyteam.common.domain.DomainEvent;
import team.teamby.teambyteam.feed.application.dto.FeedImageResponse;
import team.teamby.teambyteam.feed.application.dto.FeedResponse;
import team.teamby.teambyteam.feed.application.event.FeedEvent;
import team.teamby.teambyteam.feed.domain.Feed;
import team.teamby.teambyteam.feed.domain.FeedRepository;
import team.teamby.teambyteam.feed.domain.FeedThread;
import team.teamby.teambyteam.feed.domain.image.FeedThreadImage;
import team.teamby.teambyteam.member.domain.MemberTeamPlace;
import team.teamby.teambyteam.member.domain.MemberTeamPlaceRepository;
import team.teamby.teambyteam.sse.domain.TeamPlaceSseEvent;
import team.teamby.teambyteam.sse.domain.emitter.TeamPlaceEmitterId;

import java.util.List;

@Slf4j
@Component
@RequiredArgsConstructor
public class FeedEventConverter implements TeamPlaceSseConverter<Long> {

private final FeedRepository feedRepository;
private final MemberTeamPlaceRepository memberTeamPlaceRepository;

@Override
@Transactional(readOnly = true)
public TeamPlaceSseEvent convert(final DomainEvent<Long> event) {
final Long feedId = event.getDomainId();
final Feed feed = feedRepository.findById(feedId)
.orElseThrow(() -> {
final String message = "No FeedFound ID : " + feedId;
log.error(message);
return new RuntimeException(message);
});
final MemberTeamPlace author = memberTeamPlaceRepository
.findByTeamPlaceIdAndMemberId(feed.getTeamPlaceId(), feed.getAuthorId())
.orElse(MemberTeamPlace.UNKNOWN_MEMBER_TEAM_PLACE);
return new FeedSse(feed, author);
final FeedEvent feedEvent = (FeedEvent) event;
final Long teamplaceId = feedEvent.getTeamPlaceId();

return new FeedSse(feedEvent.response(), teamplaceId);
}

@Override
Expand All @@ -53,32 +34,32 @@ private static class FeedSse implements TeamPlaceSseEvent {
private static final String EVENT_NAME = "new_thread";

private final Long teamPlaceId;
private final FeedResponse forMe;
private FeedResponse forMe;
private FeedResponse forOthers;

public FeedSse(final Feed feed, final MemberTeamPlace author) {
this.teamPlaceId = feed.getTeamPlaceId();
this.forMe = new FeedResponse(
feed.getId(),
feed.getType().name().toLowerCase(),
feed.getAuthorId(),
author.getDisplayMemberNameValue(),
author.findMemberProfileImageUrl(),
feed.getCreatedAt(),
feed.getContent().getValue(),
convertImageResponses(((FeedThread) feed).getImages()),
true
);
public FeedSse(final FeedResponse response, final Long teamPlaceId) {
this.teamPlaceId = teamPlaceId;
if (response.isMe()) {
forMe = response;
forOthers = reverseForMeField(response);
return;
}
forMe = reverseForMeField(response);
forOthers = response;
}

private static List<FeedImageResponse> convertImageResponses(final List<FeedThreadImage> images) {
return images.stream().map(feedThreadImage ->
new FeedImageResponse(
feedThreadImage.getId(),
feedThreadImage.isExpired(),
feedThreadImage.getImageName().getValue(),
feedThreadImage.getImageUrl().getValue()))
.toList();
private static FeedResponse reverseForMeField(final FeedResponse response) {
return new FeedResponse(
response.id(),
response.type(),
response.authorId(),
response.authorName(),
response.profileImageUrl(),
response.createdAt(),
response.content(),
response.images(),
!response.isMe()
);
}

@Override
Expand All @@ -96,19 +77,6 @@ public Object getEvent(final TeamPlaceEmitterId emitterId) {
if (emitterId.isMemberId(forMe.authorId())) {
return forMe;
}
if (forOthers == null) {
return new FeedResponse(
forMe.id(),
forMe.type(),
forMe.authorId(),
forMe.authorName(),
forMe.profileImageUrl(),
forMe.createdAt(),
forMe.content(),
forMe.images(),
false
);
}
return forOthers;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,14 @@ void convert() {

final Feed savedFeed = testFixtureBuilder.buildFeed(FeedThreadFixtures.CONTENT_ONLY_AND_IMAGE_EMPTY(savedTeamPlace.getId(), savedMember.getId()));

final FeedEvent testEvent = new FeedEvent(savedFeed.getId());
final FeedResponse response = FeedResponse.from(
savedFeed,
savedMemberTeamplcae,
null,
savedMember.getEmailValue()
);

final FeedEvent testEvent = new FeedEvent(response, savedTeamPlace.getId());

// when
final TeamPlaceSseEvent sseEvent = feedEventConverter.convert(testEvent);
Expand Down

0 comments on commit 9ec31a8

Please sign in to comment.