Skip to content
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

[BE] 팀채팅시 이벤트 발행에 db조회 제거 #956

Merged
merged 2 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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