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

[Feat]: 채팅방 메세지를 조회할 수 있다 #14

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from
2 changes: 1 addition & 1 deletion api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ dependencies {
implementation(project(":client"))
implementation(project(":in-message"))
implementation(project(":out-message"))
implementation(project(":client"))
implementation(project(":storage"))
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-websocket")
}
Expand Down
2 changes: 1 addition & 1 deletion api/src/main/kotlin/gloddy/GloddyChatApplication.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package gloddy.api
package gloddy

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
Expand Down
25 changes: 25 additions & 0 deletions api/src/main/kotlin/gloddy/controller/GroupChatQueryController.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package gloddy.controller

import gloddy.groupChat.GroupChatMessage
import gloddy.groupChat.service.GroupChatCommander
import gloddy.groupChat.service.GroupChatReader
import gloddy.util.CursorRequest
import gloddy.util.PageCursor
import org.springframework.web.bind.annotation.*

@RestController
class GroupChatQueryController(
private val groupChatReader: GroupChatReader,
private val groupChatCommander: GroupChatCommander
) {

@GetMapping("/group-chat-messages/{groupId}")
fun getGroupChatMessagesByCursor(
@PathVariable("groupId") groupId: Long,
userId: Long,
@RequestBody(required = false) cursorRequest: CursorRequest
): PageCursor<GroupChatMessage> {

return groupChatReader.getMessagesByCursor(groupId, userId, cursorRequest)
}
}
2 changes: 1 addition & 1 deletion api/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ spring:
- application-client.yml
- application-aws-credentials.yml
- application-in-message.yml
- application-out-message
- application-out-message.yml
4 changes: 4 additions & 0 deletions domain/src/main/kotlin/gloddy/core/ErrorCode.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,8 @@ enum class ErrorCode(

//GroupChatMessage
GROUP_CHAT_MESSAGE_NOT_FOUND(404, "GROUP_CHAT_003", "그룹 채팅 메시지를 찾을 수 없습니다."),

//GroupChatUser
GROUP_CHAT_USER_NOT_FOUND(404, "GROUP_CHAT_USER_005", "유저를 찾을 수 없습니다.")

}
6 changes: 6 additions & 0 deletions domain/src/main/kotlin/gloddy/groupChat/GroupChatException.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,10 @@ class GroupChatMessageNotFoundException : GloddyChatException(
statusCode = ErrorCode.GROUP_CHAT_MESSAGE_NOT_FOUND.statusCode,
errorCode = ErrorCode.GROUP_CHAT_MESSAGE_NOT_FOUND.errorCode,
message = ErrorCode.GROUP_CHAT_MESSAGE_NOT_FOUND.message
)

class GroupChatUserNotFoundException : GloddyChatException(
statusCode = ErrorCode.GROUP_CHAT_USER_NOT_FOUND.statusCode,
errorCode = ErrorCode.GROUP_CHAT_USER_NOT_FOUND.errorCode,
message = ErrorCode.GROUP_CHAT_USER_NOT_FOUND.message
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package gloddy.groupChat.dto.command

import gloddy.util.CursorRequest
import java.util.*

data class GroupChatGetMessageCommand(
val groupId: Long,
val cursorRequest: CursorRequest
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package gloddy.groupChat.repository

import gloddy.groupChat.GroupChatMessage
import gloddy.util.CursorRequest
import java.time.LocalDateTime

interface GroupChatQueryRepository {
fun findWithoutKey(groupId: Long, createdAt: LocalDateTime): List<GroupChatMessage>

fun findWithKey(groupId: Long, cursorRequest: CursorRequest): List<GroupChatMessage>
fun findUserCreatedAtById(userId: Long): LocalDateTime
}
29 changes: 29 additions & 0 deletions domain/src/main/kotlin/gloddy/groupChat/service/GroupChatReader.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package gloddy.groupChat.service

import gloddy.groupChat.GroupChatMessage
import gloddy.groupChat.repository.GroupChatQueryRepository
import gloddy.util.CursorRequest
import gloddy.util.PageCursor
import org.springframework.stereotype.Service

@Service
class GroupChatReader(private val groupChatQueryRepository: GroupChatQueryRepository) {

fun getMessagesByCursor(groupId: Long, userId: Long, cursorRequest: CursorRequest): PageCursor<GroupChatMessage> {
var messages = findAll(groupId, userId, cursorRequest)
var nextKey = messages.stream()
.mapToLong(GroupChatMessage::sequenceId)
.min()
.orElse(CursorRequest.NONE_KEY)
return PageCursor(cursorRequest.next(nextKey), messages.size, messages)
}

private fun findAll(groupId: Long, userId: Long, cursorRequest: CursorRequest): List<GroupChatMessage> {
return if (cursorRequest.hasKey()) {
groupChatQueryRepository.findWithKey(groupId, cursorRequest)
} else {
val createdAt = groupChatQueryRepository.findUserCreatedAtById(userId)
groupChatQueryRepository.findWithoutKey(groupId, createdAt)
}
}
}
18 changes: 18 additions & 0 deletions domain/src/main/kotlin/gloddy/util/CursorRequest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package gloddy.util


data class CursorRequest(
val key: Long?
) {
companion object {
const val NONE_KEY: Long = -1L
}

fun hasKey(): Boolean {
return key != null
}

fun next(key: Long?): CursorRequest {
return CursorRequest(key)
}
}
7 changes: 7 additions & 0 deletions domain/src/main/kotlin/gloddy/util/PageCursor.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package gloddy.util

data class PageCursor<T>(
val nextCursorRequest: CursorRequest,
val size: Int,
val body: List<T>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package gloddy.adapter

import gloddy.groupChat.GroupChatMessage
import gloddy.groupChat.GroupChatUserNotFoundException
import gloddy.groupChat.repository.GroupChatQueryRepository
import gloddy.persistence.repository.GroupChatMessageJpaRepository
import gloddy.persistence.repository.GroupChatUserJpaRepository
import gloddy.persistence.util.toDomain
import gloddy.util.CursorRequest
import org.springframework.stereotype.Component
import java.time.LocalDateTime

@Component
class GroupChatQueryAdapterRepository(
private val groupChatMessageJpaRepository: GroupChatMessageJpaRepository,
private val groupChatUserJpaRepository: GroupChatUserJpaRepository,
private val groupChatCommandAdapterRepository: GroupChatCommandAdapterRepository
) : GroupChatQueryRepository {

override fun findWithoutKey(groupId: Long, createdAt: LocalDateTime): List<GroupChatMessage> {
val groupChat = groupChatCommandAdapterRepository.findByGroupId(groupId)
return groupChatMessageJpaRepository.findAllByChatIdAndOrderByIdDesc(
createdAt,
groupChat.id
).map { it.toDomain() }
}

override fun findWithKey(groupId: Long, cursorRequest: CursorRequest): List<GroupChatMessage> {
val groupChat = groupChatCommandAdapterRepository.findByGroupId(groupId)
return groupChatMessageJpaRepository.findAllByLessThanIdAndChatIdAndOrderByIdDesc(
cursorRequest.key,
groupChat.id
).map { it.toDomain() }
}

override fun findUserCreatedAtById(userId: Long): LocalDateTime {
val found = groupChatUserJpaRepository.findByUserId(userId)
return found?.createdAt ?: throw GroupChatUserNotFoundException()
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,31 @@ package gloddy.persistence.repository

import gloddy.persistence.GroupChatMessageEntity
import org.springframework.data.jpa.repository.JpaRepository
import java.util.UUID
import org.springframework.data.jpa.repository.Query
import java.time.LocalDateTime
import java.util.*

interface GroupChatMessageJpaRepository : JpaRepository<GroupChatMessageEntity, Long> {
fun findById(id: UUID): GroupChatMessageEntity?
fun findFirstByOrderBySequenceIdDesc(): GroupChatMessageEntity

@Query(
value = "SELECT m.* " +
"FROM group_chat_message AS m " +
"inner JOIN group_chat_user u " +
" ON u.user_id = m.user_id " +
"WHERE m.chat_id = :chatId and :createdAt < m.created_at and not m.type in ('SYSTEM_JOIN') " +
"ORDER BY m.sequence_id desc",
nativeQuery = true
)
fun findAllByChatIdAndOrderByIdDesc(createdAt: LocalDateTime, chatId: UUID): List<GroupChatMessageEntity>

@Query(
value = "SELECT * " +
"FROM group_chat_message m " +
"WHERE chat_id = :chatId and sequence_id < :sequenceId and not m.type in ('SYSTEM_JOIN') " +
"ORDER BY sequence_id desc",
nativeQuery = true
)
fun findAllByLessThanIdAndChatIdAndOrderByIdDesc(sequenceId: Long?, chatId: UUID): List<GroupChatMessageEntity>
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package gloddy.persistence.repository

import gloddy.persistence.GroupChatUserEntity
import org.springframework.data.jpa.repository.JpaRepository
import java.util.UUID
import java.util.*

interface GroupChatUserJpaRepository : JpaRepository<GroupChatUserEntity, Long> {
fun findById(id: UUID): GroupChatUserEntity?
fun findFirstByOrderBySequenceIdDesc(): GroupChatUserEntity
fun findByUserId(userId: Long): GroupChatUserEntity?
}
Loading