-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MATE-151 : [FEAT] 메이트 채팅 저장소를 MySQL에서 MongoDB로 마이그레이션 (#141)
* MATE-151 : [FEAT] 메이트 메세지 도큐먼트 생성 * MATE-151 : [FEAT] 메이트 메세지 클래스 삭제 * MATE-151 : [FEAT] 메이트 메세지의 MongoRepository 생성 * MATE-151 : [FEAT] 메이트 메세지의 응답 DTO의 보조 메서드 제거 * MATE-151 : [FEAT] 메이트 메세지의 응답 DTO 필드 변경 * MATE-151 : [FEAT] 메이트 채팅 메세지 서비스 코드 변경 - MongoDb 도큐먼트 사용으로 인한 반환값 변화에 따른 코드 수정 * MATE-151 : [FEAT] 메이트 채팅 메세지 조회 메서드 리팩토링 * MATE-151 : [FEAT] 불필요한 헬퍼 메서드 제거 * MATE-151 : [FEAT] 불필요한 html파일 제거 * MATE-151 : [FEAT] 메세지 리포지토리 메서드 이름 변경 * MATE-151 : [FEAT] 메세지 반환 DTO 수정으로 인한 테스트 환경 변경 * MATE-151 : [FEAT] 채팅방 멤버 조회 시 불필요한 검증 제거 * MATE-151 : [FEAT] 테스트 코드에 빈 오버라이딩 허용 설정 * MATE-151 : [FEAT] 테스트 코드에 빈 오버라이딩 허용 설정
- Loading branch information
Showing
13 changed files
with
149 additions
and
479 deletions.
There are no files selected for viewing
25 changes: 25 additions & 0 deletions
25
src/main/java/com/example/mate/domain/mateChat/document/MateChatMessage.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.example.mate.domain.mateChat.document; | ||
|
||
import com.example.mate.common.BaseTimeEntity; | ||
import com.example.mate.domain.mateChat.message.MessageType; | ||
import jakarta.persistence.Id; | ||
import lombok.*; | ||
import org.springframework.data.mongodb.core.mapping.Document; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
@Document(collection = "mate_chat_message") | ||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor(access = AccessLevel.PRIVATE) | ||
@Builder | ||
public class MateChatMessage extends BaseTimeEntity { | ||
@Id | ||
private String id; | ||
|
||
private Long roomId; | ||
private Long senderId; | ||
private MessageType type; | ||
private String content; | ||
private LocalDateTime sendTime; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 0 additions & 39 deletions
39
src/main/java/com/example/mate/domain/mateChat/entity/MateChatMessage.java
This file was deleted.
Oops, something went wrong.
14 changes: 0 additions & 14 deletions
14
src/main/java/com/example/mate/domain/mateChat/event/MateChatEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,10 @@ | ||
package com.example.mate.domain.mateChat.event; | ||
|
||
import com.example.mate.domain.mateChat.dto.request.MateChatMessageRequest; | ||
import com.example.mate.domain.mateChat.message.MessageType; | ||
import com.example.mate.domain.member.entity.Member; | ||
|
||
public record MateChatEvent(Long chatRoomId, Member member, MessageType type) { | ||
public static MateChatEvent from(Long chatRoomId, Member member, MessageType type) { | ||
return new MateChatEvent(chatRoomId, member, type); | ||
} | ||
|
||
public MateChatMessageRequest toMessageRequest() { | ||
String content = type == MessageType.ENTER ? | ||
member.getNickname() + "님이 들어왔습니다." : | ||
member.getNickname() + "님이 나갔습니다."; | ||
|
||
return MateChatMessageRequest.builder() | ||
.roomId(chatRoomId) | ||
.senderId(member.getId()) | ||
.type(type.name()) | ||
.message(content) | ||
.build(); | ||
} | ||
} |
24 changes: 11 additions & 13 deletions
24
src/main/java/com/example/mate/domain/mateChat/repository/MateChatMessageRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,19 @@ | ||
package com.example.mate.domain.mateChat.repository; | ||
|
||
import com.example.mate.domain.mateChat.entity.MateChatMessage; | ||
import com.example.mate.domain.mateChat.document.MateChatMessage; | ||
import org.springframework.data.domain.Page; | ||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.data.jpa.repository.Query; | ||
import org.springframework.data.repository.query.Param; | ||
import org.springframework.data.mongodb.repository.MongoRepository; | ||
import org.springframework.data.mongodb.repository.Query; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
public interface MateChatMessageRepository extends JpaRepository<MateChatMessage, Long> { | ||
|
||
@Query("SELECT m FROM MateChatMessage m " + | ||
"WHERE m.mateChatRoom.id = :roomId " + | ||
"AND m.createdAt >= :enterTime " + | ||
"ORDER BY m.createdAt DESC ") | ||
Page<MateChatMessage> findByChatRoomIdAndCreatedAtAfterOrderByCreatedAtDesc(@Param("roomId") Long roomId, | ||
@Param("enterTime") LocalDateTime enterTime, | ||
Pageable pageable); | ||
public interface MateChatMessageRepository extends MongoRepository<MateChatMessage, String> { | ||
// 채팅방의 특정 시간 이후 메시지 조회 (페이징) | ||
@Query("{ 'roomId': ?0, 'sendTime': { $gt: ?1 } }") | ||
Page<MateChatMessage> findByRoomIdAndSendTimeAfter( | ||
Long roomId, | ||
LocalDateTime enterTime, | ||
Pageable pageable | ||
); | ||
} |
85 changes: 59 additions & 26 deletions
85
src/main/java/com/example/mate/domain/mateChat/service/MateChatMessageService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,75 +1,108 @@ | ||
package com.example.mate.domain.mateChat.service; | ||
|
||
import com.example.mate.common.error.CustomException; | ||
import com.example.mate.common.error.ErrorCode; | ||
import com.example.mate.domain.mateChat.document.MateChatMessage; | ||
import com.example.mate.domain.mateChat.dto.request.MateChatMessageRequest; | ||
import com.example.mate.domain.mateChat.dto.response.MateChatMessageResponse; | ||
import com.example.mate.domain.mateChat.entity.MateChatMessage; | ||
import com.example.mate.domain.mateChat.entity.MateChatRoom; | ||
import com.example.mate.domain.mateChat.event.MateChatEvent; | ||
import com.example.mate.domain.mateChat.message.MessageType; | ||
import com.example.mate.domain.mateChat.repository.MateChatMessageRepository; | ||
import com.example.mate.domain.mateChat.repository.MateChatRoomRepository; | ||
import com.example.mate.domain.member.entity.Member; | ||
import com.example.mate.domain.member.repository.MemberRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.messaging.simp.SimpMessageSendingOperations; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
import static com.example.mate.common.error.ErrorCode.*; | ||
|
||
@Slf4j | ||
@Service | ||
@RequiredArgsConstructor | ||
public class MateChatMessageService { | ||
private final MateChatRoomRepository chatRoomRepository; | ||
private final MateChatMessageRepository chatMessageRepository; | ||
private final MateChatMessageRepository chatMessageRepository; // 새로운 MongoDB 레포지토리 | ||
private final MemberRepository memberRepository; | ||
private final SimpMessageSendingOperations messagingTemplate; | ||
|
||
@Transactional | ||
public void sendMessage(MateChatMessageRequest request) { | ||
MateChatRoom chatRoom = findChatRoomById(request.getRoomId()); | ||
|
||
// 메시지 전송 가능 여부 검증 | ||
MateChatRoom chatRoom = chatRoomRepository.findById(request.getRoomId()) | ||
.orElseThrow(() -> new CustomException(CHAT_ROOM_NOT_FOUND)); | ||
if (!chatRoom.getIsMessageable()) { | ||
throw new CustomException(ErrorCode.CHAT_ROOM_NOT_MESSAGEABLE); | ||
throw new CustomException(CHAT_ROOM_NOT_MESSAGEABLE); | ||
} | ||
|
||
Member sender = findMemberById(request.getSenderId()); | ||
MateChatMessage chatMessage = chatMessageRepository.save(MateChatMessageRequest.toEntity(chatRoom, request, sender)); | ||
Member sender = memberRepository.findById(request.getSenderId()) | ||
.orElseThrow(() -> new CustomException(MEMBER_NOT_FOUND_BY_ID)); | ||
|
||
// MongoDB에 메시지 저장 | ||
MateChatMessage message = MateChatMessage.builder() | ||
.roomId(chatRoom.getId()) | ||
.senderId(sender.getId()) | ||
.content(request.getMessage()) | ||
.type(MessageType.TALK) | ||
.sendTime(LocalDateTime.now()) | ||
.build(); | ||
|
||
MateChatMessage savedMessage = chatMessageRepository.save(message); | ||
|
||
// 마지막 메시지 정보 업데이트 | ||
chatRoom.updateLastChat(chatMessage.getContent()); | ||
chatRoom.updateLastChat(request.getMessage()); | ||
|
||
// 웹소켓으로 메시지 전송 | ||
messagingTemplate.convertAndSend( | ||
"/sub/chat/mate/" + request.getRoomId(), | ||
MateChatMessageResponse.of(chatMessage) | ||
createMessageResponse(savedMessage, sender) | ||
); | ||
} | ||
|
||
@Transactional | ||
public void sendChatEventMessage(MateChatEvent event) { | ||
MateChatRoom chatRoom = findChatRoomById(event.chatRoomId()); | ||
MateChatMessageRequest request = event.toMessageRequest(); | ||
MateChatRoom chatRoom = chatRoomRepository.findById(event.chatRoomId()) | ||
.orElseThrow(() -> new CustomException(CHAT_ROOM_NOT_FOUND)); | ||
|
||
MateChatMessage chatMessage = chatMessageRepository.save( | ||
MateChatMessageRequest.toEntity(chatRoom, request, event.member()) | ||
); | ||
Member sender = event.member(); | ||
|
||
chatRoom.updateLastChat(chatMessage.getContent()); | ||
String eventType = event.type() == MessageType.ENTER ? | ||
"님이 입장하셨습니다." : "님이 퇴장하셨습니다."; | ||
String eventMessage = sender.getNickname() + eventType; | ||
|
||
// 이벤트 메시지 저장 | ||
MateChatMessage message = MateChatMessage.builder() | ||
.roomId(chatRoom.getId()) | ||
.senderId(sender.getId()) | ||
.content(eventMessage) | ||
.type(event.type()) | ||
.sendTime(LocalDateTime.now()) | ||
.build(); | ||
|
||
MateChatMessage savedMessage = chatMessageRepository.save(message); | ||
|
||
// 채팅방 마지막 메시지 업데이트 | ||
chatRoom.updateLastChat(eventMessage); | ||
|
||
messagingTemplate.convertAndSend( | ||
"/sub/chat/mate/" + event.chatRoomId(), | ||
MateChatMessageResponse.of(chatMessage) | ||
createMessageResponse(savedMessage, sender) | ||
); | ||
} | ||
|
||
private MateChatRoom findChatRoomById(Long roomId) { | ||
return chatRoomRepository.findById(roomId) | ||
.orElseThrow(() -> new CustomException(ErrorCode.CHAT_ROOM_NOT_FOUND)); | ||
} | ||
|
||
private Member findMemberById(Long memberId) { | ||
return memberRepository.findById(memberId) | ||
.orElseThrow(() -> new CustomException(ErrorCode.MEMBER_NOT_FOUND_BY_ID)); | ||
private MateChatMessageResponse createMessageResponse(MateChatMessage message, Member sender) { | ||
return MateChatMessageResponse.builder() | ||
.messageId(message.getId()) | ||
.roomId(message.getRoomId()) | ||
.senderId(sender.getId()) | ||
.senderNickname(sender.getNickname()) | ||
.senderImageUrl(sender.getImageUrl()) | ||
.message(message.getContent()) | ||
.messageType(message.getType().getValue()) | ||
.sendTime(message.getSendTime()) | ||
.build(); | ||
} | ||
} |
Oops, something went wrong.