Skip to content

Commit

Permalink
refactor: 코드 리팩터링
Browse files Browse the repository at this point in the history
  • Loading branch information
JJ503 committed Mar 10, 2024
1 parent edb0a63 commit 2ecc70d
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,34 +36,69 @@ public class MessageService {
@Transactional
public Long create(final CreateMessageDto dto, final String profileImageAbsoluteUrl) {
final ChatRoom chatRoom = chatRoomRepository.findById(dto.chatRoomId())
.orElseThrow(() -> new ChatRoomNotFoundException(
"지정한 아이디에 대한 채팅방을 찾을 수 없습니다."));
.orElseThrow(() -> new ChatRoomNotFoundException(
"지정한 아이디에 대한 채팅방을 찾을 수 없습니다."
));
final Message persistMessage = psersistMessage(dto, chatRoom);
messageNotificationEventPublisher.publishEvent(new MessageNotificationEvent(
persistMessage,
profileImageAbsoluteUrl
));

return persistMessage.getId();
}

@Transactional
public ReadMessageDto create(final CreateMessageDto dto) {
final ChatRoom chatRoom = chatRoomRepository.findById(dto.chatRoomId())
.orElseThrow(() -> new ChatRoomNotFoundException(
"지정한 아이디에 대한 채팅방을 찾을 수 없습니다."
));
final Message message = psersistMessage(dto, chatRoom);

return ReadMessageDto.of(message, chatRoom);
}

private Message psersistMessage(final CreateMessageDto dto, final ChatRoom chatRoom) {
final User writer = userRepository.findByIdWithProfileImage(dto.writerId())
.orElseThrow(() -> new UserNotFoundException(
"지정한 아이디에 대한 발신자를 찾을 수 없습니다."));
.orElseThrow(() -> new UserNotFoundException(
"지정한 아이디에 대한 발신자를 찾을 수 없습니다."
));
final User receiver = userRepository.findById(dto.receiverId())
.orElseThrow(() -> new UserNotFoundException(
"지정한 아이디에 대한 수신자를 찾을 수 없습니다."));
.orElseThrow(() -> new UserNotFoundException(
"지정한 아이디에 대한 수신자를 찾을 수 없습니다."
));
validateReceiver(chatRoom, receiver);

final Message message = dto.toEntity(chatRoom, writer, receiver);

return messageRepository.save(message);
}

private void validateReceiver(final ChatRoom chatRoom, final User receiver) {
if (!chatRoom.isChatAvailablePartner(receiver)) {
throw new UnableToChatException("탈퇴한 사용자에게는 메시지 전송이 불가능합니다.");
}
}

final Message message = dto.toEntity(chatRoom, writer, receiver);

final Message persistMessage = messageRepository.save(message);

messageNotificationEventPublisher.publishEvent(new MessageNotificationEvent(persistMessage, profileImageAbsoluteUrl));
@Transactional
public ReadMessageDto createWithNotification(final CreateMessageDto dto, final String profileImageAbsoluteUrl) {
final ChatRoom chatRoom = chatRoomRepository.findById(dto.chatRoomId())
.orElseThrow(() -> new ChatRoomNotFoundException(
"지정한 아이디에 대한 채팅방을 찾을 수 없습니다."
));
final Message message = psersistMessage(dto, chatRoom);
messageNotificationEventPublisher.publishEvent(new MessageNotificationEvent(message, profileImageAbsoluteUrl));

return persistMessage.getId();
return ReadMessageDto.of(message, chatRoom);
}

public List<ReadMessageDto> readAllByLastMessageId(final ReadMessageRequest request) {
final User reader = userRepository.findById(request.messageReaderId())
.orElseThrow(() -> new UserNotFoundException("지정한 아이디에 대한 사용자를 찾을 수 없습니다."));
.orElseThrow(() -> new UserNotFoundException("지정한 아이디에 대한 사용자를 찾을 수 없습니다."));
final ChatRoom chatRoom = chatRoomRepository.findById(request.chatRoomId())
.orElseThrow(() -> new ChatRoomNotFoundException(
"지정한 아이디에 대한 채팅방을 찾을 수 없습니다."));
.orElseThrow(() -> new ChatRoomNotFoundException(
"지정한 아이디에 대한 채팅방을 찾을 수 없습니다."));

if (request.lastMessageId() != null) {
validateLastMessageId(request.lastMessageId());
Expand All @@ -82,8 +117,8 @@ public List<ReadMessageDto> readAllByLastMessageId(final ReadMessageRequest requ
}

return readMessages.stream()
.map(message -> ReadMessageDto.from(message, chatRoom))
.toList();
.map(message -> ReadMessageDto.of(message, chatRoom))
.toList();
}

private void validateLastMessageId(final Long lastMessageId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public record ReadMessageDto(
String contents
) {

public static ReadMessageDto from(
public static ReadMessageDto of(
final Message message,
final ChatRoom chatRoom
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.springframework.web.socket.WebSocketSession;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Component
Expand All @@ -27,6 +28,18 @@ public void add(final WebSocketSession session, final Long chatRoomId) {
}
}

public Set<WebSocketSession> getSessionsByChatRoomId(final Long chatRoomId) {
final WebSocketSessions webSocketSessions = chatRoomSessions.get(chatRoomId);

return webSocketSessions.getSessions();
}

public boolean containsByUserId(final Long chatRoomId, final Long userId) {
final WebSocketSessions webSocketSessions = chatRoomSessions.get(chatRoomId);

return webSocketSessions.contains(userId);
}

public void remove(final WebSocketSession session) {
final long chatRoomId = Long.parseLong(String.valueOf(session.getAttributes().get(ATTRIBUTE_KEY)));
final WebSocketSessions webSocketSessions = chatRoomSessions.get(chatRoomId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,9 @@ public void remove(final WebSocketSession session) {
public boolean containsValue(final WebSocketSession session) {
return sessions.contains(session);
}

public boolean contains(final Long userId) {
return sessions.stream()
.anyMatch(session -> session.getAttributes().get("userId") == userId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@

import com.ddang.ddang.chat.application.MessageService;
import com.ddang.ddang.chat.application.dto.CreateMessageDto;
import com.ddang.ddang.chat.application.dto.ReadMessageDto;
import com.ddang.ddang.chat.domain.WebSocketChatSessions;
import com.ddang.ddang.chat.domain.WebSocketSessions;
import com.ddang.ddang.chat.handler.dto.ChatMessageDataDto;
import com.ddang.ddang.chat.presentation.dto.request.CreateMessageRequest;
import com.ddang.ddang.chat.presentation.dto.response.ReadMessageResponse;
import com.ddang.ddang.websocket.handler.WebSocketHandleTextMessageProvider;
import com.ddang.ddang.websocket.handler.dto.SendMessagesDto;
import com.ddang.ddang.websocket.handler.dto.SessionAttributeDto;
import com.ddang.ddang.websocket.handler.dto.TextMessageType;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
Expand All @@ -37,31 +37,30 @@ public TextMessageType supportTextMessageType() {
}

@Override
public List<SendMessagesDto> handle(final WebSocketSession session, final Map<String, String> data) throws Exception {
public List<SendMessagesDto> handle(
final WebSocketSession session,
final Map<String, String> data
) throws Exception {
final SessionAttributeDto sessionAttribute = getSessionAttributes(session);
final ChatMessageDataDto messageData = objectMapper.convertValue(data, ChatMessageDataDto.class);
sessions.add(session, messageData.chatRoomId());

final Long senderId = sessionAttribute.userId();
final CreateMessageDto createMessageDto = createMessageDto(messageData, senderId);
final ReadMessageDto messageDto = createMessageDto(createMessageDto, sessionAttribute);

final Long messageId = messageService.create(createMessageDto, sessionAttribute.baseUrl());
final Map<Long, WebSocketSessions> chatRoomSessions = sessions.getChatRoomSessions();
final WebSocketSessions webSocketSessions = chatRoomSessions.get(messageData.chatRoomId());
final Set<WebSocketSession> groupSessions = webSocketSessions.getSessions();
final List<SendMessagesDto> sendMessagesDtos = new ArrayList<>();
for (WebSocketSession currentSession : groupSessions) {
ReadMessageResponse response;
if (currentSession.getAttributes().get("userId") == senderId) {
response = new ReadMessageResponse(messageId, LocalDateTime.now(), true, messageData.contents());
} else {
response = new ReadMessageResponse(messageId, LocalDateTime.now(), false, messageData.contents());
}
final TextMessage textMessage = new TextMessage(objectMapper.writeValueAsString(response));
sendMessagesDtos.add(new SendMessagesDto(session, textMessage));
return createSendMessages(session, messageDto, senderId);
}

private ReadMessageDto createMessageDto(
final CreateMessageDto createMessageDto,
final SessionAttributeDto sessionAttribute
) {
if (sessions.containsByUserId(createMessageDto.chatRoomId(), createMessageDto.receiverId())) {
return messageService.create(createMessageDto);
}

return sendMessagesDtos;
return messageService.createWithNotification(createMessageDto, sessionAttribute.baseUrl());
}

private SessionAttributeDto getSessionAttributes(final WebSocketSession session) {
Expand All @@ -79,6 +78,41 @@ private CreateMessageDto createMessageDto(final ChatMessageDataDto messageData,
return CreateMessageDto.of(userId, messageData.chatRoomId(), request);
}

private List<SendMessagesDto> createSendMessages(
final WebSocketSession session,
final ReadMessageDto messageDto,
final Long senderId
) throws JsonProcessingException {
final Set<WebSocketSession> groupSessions = sessions.getSessionsByChatRoomId(messageDto.chatRoomId());

final List<SendMessagesDto> sendMessagesDtos = new ArrayList<>();
for (WebSocketSession currentSession : groupSessions) {
final TextMessage textMessage = createTextMessage(messageDto, senderId, currentSession);
sendMessagesDtos.add(new SendMessagesDto(session, textMessage));
}

return sendMessagesDtos;
}

private TextMessage createTextMessage(
final ReadMessageDto messageDto,
final Long senderId,
final WebSocketSession session
) throws JsonProcessingException {
final ReadMessageResponse response = ReadMessageResponse.of(
messageDto,
isMyMessage(session, senderId)
);

return new TextMessage(objectMapper.writeValueAsString(response));
}

private boolean isMyMessage(final WebSocketSession session, final Long senderId) {
final long userId = Long.parseLong(String.valueOf(session.getAttributes().get("userId")));

return senderId.equals(userId);
}

@Override
public void remove(final WebSocketSession session) {
sessions.remove(session);
Expand Down

0 comments on commit 2ecc70d

Please sign in to comment.