Skip to content

Commit

Permalink
Merge pull request #359 from Team-Ampersand/develop
Browse files Browse the repository at this point in the history
변경사항 마스터 적용
  • Loading branch information
esperar committed Jul 5, 2024
2 parents fd63f6d + 35cfd28 commit 348dfb5
Show file tree
Hide file tree
Showing 35 changed files with 529 additions and 50 deletions.
2 changes: 1 addition & 1 deletion appspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ permissions:

hooks:
ApplicationStart:
- location: ./deploy-dev.sh
- location: ./deploy-execution.sh
timeout: 60
runas: ubuntu
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ dependencies {

// kotlin
implementation(Dependencies.KOTLIN_JACKSON)
implementation(Dependencies.KOTLIN_JACKSON_DATABIND)
implementation(Dependencies.KOTLIN_REFLECT)
implementation(Dependencies.KOTLIN_STDLIB)
runtimeOnly(Dependencies.H2_DATABASE)
Expand Down
1 change: 1 addition & 0 deletions buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ object Dependencies {

// kotlin
const val KOTLIN_JACKSON = "com.fasterxml.jackson.module:jackson-module-kotlin"
const val KOTLIN_JACKSON_DATABIND = "com.fasterxml.jackson.core:jackson-databind:${DependencyVersions.JACKSON_DATA_BIND}"
const val KOTLIN_REFLECT = "org.jetbrains.kotlin:kotlin-reflect"
const val KOTLIN_STDLIB = "org.jetbrains.kotlin:kotlin-stdlib-jdk8"

Expand Down
3 changes: 3 additions & 0 deletions buildSrc/src/main/kotlin/DependencyVersions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ object DependencyVersions {
const val KOTEST_ASSERTIONS_VERSION = "5.5.5"
const val KOTEST_JVM_VERSION = "5.5.5"

// jackson
const val JACKSON_DATA_BIND = "2.12.4"

// mockk
const val MOCKK_VERSION = "1.13.4"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,11 @@ data class BoardResDto(
createdDate = board.createdDate
)
}
constructor() : this(
id = 0L,
title = "",
content = "",
role = Role.ROLE_MEMBER,
createdDate = LocalDateTime.now()
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ package com.dotori.v2.domain.board.presentation.data.res

data class ListBoardResDto(
val boardList: List<BoardResDto>
)
) {
constructor() : this(listOf())
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.dotori.v2.domain.board.service

import com.dotori.v2.domain.board.domain.entity.Board
import com.dotori.v2.domain.board.presentation.data.req.ModifyBoardReqDto

interface ModifyBoardService {
fun execute(modifyBoardReqDto: ModifyBoardReqDto, boardId: Long): Board
fun execute(modifyBoardReqDto: ModifyBoardReqDto, boardId: Long)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import com.dotori.v2.domain.board.domain.entity.Board
import com.dotori.v2.domain.board.domain.entity.BoardImage
import com.dotori.v2.domain.board.presentation.data.dto.CreateBoardDto
import com.dotori.v2.domain.board.presentation.data.req.CreateBoardReqDto
import com.dotori.v2.domain.board.presentation.data.res.BoardResDto
import com.dotori.v2.domain.board.presentation.data.res.ListBoardResDto
import com.dotori.v2.domain.board.service.CreateBoardService
import com.dotori.v2.global.thirdparty.aws.s3.S3Service
import com.dotori.v2.domain.board.util.BoardSaveUtil
import com.dotori.v2.domain.member.domain.entity.Member
import com.dotori.v2.global.config.redis.service.RedisCacheService
import com.dotori.v2.global.util.UserUtil
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
Expand All @@ -19,24 +22,29 @@ import org.springframework.web.multipart.MultipartFile
class CreateBoardServiceImpl(
private val userUtil: UserUtil,
private val s3Service: S3Service,
private val boardSaveUtil: BoardSaveUtil
private val boardSaveUtil: BoardSaveUtil,
private val redisCacheService: RedisCacheService
) : CreateBoardService {

@Value("\${cloud.aws.s3.url}")
private val S3_ADDRESS: String? = null
val CACHE_KEY = "boardList"

override fun execute(createBoardReqDto: CreateBoardReqDto, multipartFiles: List<MultipartFile>?): Board {
val member: Member = userUtil.fetchCurrentUser()
val createBoardDto: CreateBoardDto = toDto(createBoardReqDto = createBoardReqDto)

if (multipartFiles == null) {
return toEntity(createBoardDto, member)
.let { boardSaveUtil.saveBoard(board = it) }
val saveBoard = toEntity(createBoardDto,member)
.let { boardSaveUtil.saveBoard(it) }
updateBoardCache(saveBoard)
return saveBoard
}

val uploadFile: List<String> = s3Service.uploadListFile(multipartFiles)
val board: Board = toEntity(createBoardDto, member)
.let { boardSaveUtil.saveBoard(board = it) }
updateBoardCache(board)

for (uploadFileUrl: String in uploadFile) {
toEntity(board = board, uploadFileUrl)
Expand All @@ -45,6 +53,22 @@ class CreateBoardServiceImpl(
return board
}

private fun updateBoardCache(board: Board) {
val cachedData = redisCacheService.getFromCache(CACHE_KEY) as? ListBoardResDto

if (cachedData != null) {
val updatedList = cachedData.boardList.toMutableList().apply {
add(BoardResDto.of(board))
}
updatedList.sortByDescending { it.id }

redisCacheService.putToCache(CACHE_KEY, ListBoardResDto(updatedList))
} else {
val newList = listOf(BoardResDto.of(board))
redisCacheService.putToCache(CACHE_KEY, ListBoardResDto(newList))
}
}

private fun toDto(createBoardReqDto: CreateBoardReqDto): CreateBoardDto =
CreateBoardDto(
title = createBoardReqDto.title,
Expand All @@ -64,4 +88,5 @@ class CreateBoardServiceImpl(
board = board,
url = S3_ADDRESS + uploadFileUrl
)

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import com.dotori.v2.domain.board.domain.entity.BoardImage
import com.dotori.v2.domain.board.domain.repository.BoardImageRepository
import com.dotori.v2.domain.board.domain.repository.BoardRepository
import com.dotori.v2.domain.board.exception.BoardNotExistsException
import com.dotori.v2.domain.board.presentation.data.res.ListBoardResDto
import com.dotori.v2.domain.board.service.DeleteBoardService
import com.dotori.v2.global.config.redis.service.RedisCacheService
import com.dotori.v2.global.thirdparty.aws.s3.S3Service
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
Expand All @@ -16,8 +18,12 @@ import org.springframework.transaction.annotation.Transactional
class DeleteBoardServiceImpl(
private val boardRepository: BoardRepository,
private val boardImageRepository: BoardImageRepository,
private val s3Service: S3Service
private val s3Service: S3Service,
private val redisCacheService: RedisCacheService
) : DeleteBoardService {

val CACHE_KEY = "boardList"

override fun execute(boardId: Long) {
val boardInfo: Board = boardRepository.findByIdOrNull(boardId)
?: throw BoardNotExistsException()
Expand All @@ -33,6 +39,18 @@ class DeleteBoardServiceImpl(
}
boardRepository.delete(boardInfo)
}

evictBoardFromCache(boardId)
}

private fun evictBoardFromCache(boardId: Long) {
val cachedData = redisCacheService.getFromCache(CACHE_KEY) as? ListBoardResDto

if (cachedData != null) {
val updatedList = cachedData.boardList.filterNot { it.id == boardId }
redisCacheService.putToCache(CACHE_KEY, ListBoardResDto(updatedList))
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,35 @@ import com.dotori.v2.domain.board.domain.repository.BoardRepository
import com.dotori.v2.domain.board.presentation.data.res.BoardResDto
import com.dotori.v2.domain.board.presentation.data.res.ListBoardResDto
import com.dotori.v2.domain.board.service.GetBoardsService
import com.dotori.v2.global.config.redis.service.RedisCacheService
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
@Transactional(readOnly = true, rollbackFor = [Exception::class])
class GetBoardsServiceImpl(
private val boardRepository: BoardRepository,
private val redisCacheService: RedisCacheService
) : GetBoardsService {

override fun execute(): ListBoardResDto = ListBoardResDto(
boardList = boardRepository.findAllByOrderByCreatedDateDesc()
.map { BoardResDto.of(it) }
)
val CACHE_KEY = "boardList"

override fun execute(): ListBoardResDto {

val cachedData = redisCacheService.getFromCache(CACHE_KEY)
if (cachedData != null) {
return cachedData as ListBoardResDto
}

val boardList = boardRepository.findAllByOrderByCreatedDateDesc()
.map { BoardResDto.of(it) }

val listBoardResDto = ListBoardResDto(boardList)

redisCacheService.putToCache(CACHE_KEY, listBoardResDto)

return listBoardResDto

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,55 @@ import com.dotori.v2.domain.board.domain.repository.BoardRepository
import com.dotori.v2.domain.board.exception.BoardNotExistsException
import com.dotori.v2.domain.board.presentation.data.dto.ModifyBoardDto
import com.dotori.v2.domain.board.presentation.data.req.ModifyBoardReqDto
import com.dotori.v2.domain.board.presentation.data.res.BoardResDto
import com.dotori.v2.domain.board.presentation.data.res.ListBoardResDto
import com.dotori.v2.domain.board.service.ModifyBoardService
import com.dotori.v2.global.config.redis.service.RedisCacheService
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
@Transactional(rollbackFor = [Exception::class])
class ModifyBoardServiceImpl(
private val boardRepository: BoardRepository
private val boardRepository: BoardRepository,
private val redisCacheService: RedisCacheService
) : ModifyBoardService {
override fun execute(modifyBoardReqDto: ModifyBoardReqDto, boardId: Long): Board {

val CACHE_KEY = "boardList"

override fun execute(modifyBoardReqDto: ModifyBoardReqDto, boardId: Long) {
val boardInfo: Board = boardRepository.findByIdOrNull(boardId)
?: throw BoardNotExistsException()

toDto(modifyBoardReqDto)
.let { boardInfo.updateBoard(title = it.title, content = it.content) }

return boardInfo
updateBoardCache(boardInfo)

}
private fun updateBoardCache(board: Board) {
val cachedData = redisCacheService.getFromCache(CACHE_KEY) as? ListBoardResDto

if (cachedData != null) {
val updatedList = cachedData.boardList.map {
if (it.id == board.id) {
BoardResDto.of(board)
} else {
it
}
}.toMutableList()

updatedList.sortByDescending { it.id }

redisCacheService.putToCache(CACHE_KEY, ListBoardResDto(updatedList))
}
}

private fun toDto(modifyBoardReqDto: ModifyBoardReqDto): ModifyBoardDto =
ModifyBoardDto(
title = modifyBoardReqDto.title,
content = modifyBoardReqDto.content
)

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.dotori.v2.domain.massage.util.SaveMassageUtil
import com.dotori.v2.domain.massage.util.ValidDayOfWeekAndHourMassageUtil
import com.dotori.v2.domain.member.enums.MassageStatus
import com.dotori.v2.global.util.UserUtil
import com.dotori.v2.indicator.IndicatorTarget
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Isolation
import org.springframework.transaction.annotation.Transactional
Expand All @@ -21,6 +22,8 @@ class ApplyMassageServiceImpl(
private val saveMassageUtil: SaveMassageUtil,
private val massageCheckUtil: MassageCheckUtil,
) : ApplyMassageService {

@IndicatorTarget
override fun execute() {
validDayOfWeekAndHourMassageUtil.validateApply()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ package com.dotori.v2.domain.member.domain.repository

import com.dotori.v2.domain.member.domain.entity.Member
import com.dotori.v2.domain.member.enums.MassageStatus
import com.dotori.v2.domain.member.enums.MusicStatus
import com.dotori.v2.domain.member.enums.SelfStudyStatus
import javax.persistence.LockModeType
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Lock
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param

interface MemberRepository : JpaRepository<Member, Long>, CustomMemberRepository {
fun save(member: Member): Member
Expand All @@ -17,4 +22,8 @@ interface MemberRepository : JpaRepository<Member, Long>, CustomMemberRepository
fun findAllByOrderByStuNumAsc(): List<Member>
fun findAllByStuNum(stuNum: String): List<Member>
fun countByStuNum(stuNum: String): Int

@Lock(LockModeType.PESSIMISTIC_READ)
@Query(value = "select m.musicStatus from Member m where m.id = :member_id")
fun findMusicStatusByMemberId(@Param("member_id") id: Long): MusicStatus
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.dotori.v2.domain.member.exception

import com.dotori.v2.global.error.ErrorCode
import com.dotori.v2.global.error.exception.BasicException

class NotAcceptImgExtensionException : BasicException(ErrorCode.MEMBER_PROFILE_IMG_NOT_ACCEPT_EXTENSION)
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.dotori.v2.domain.member.service.impl

import com.dotori.v2.domain.member.domain.entity.Member
import com.dotori.v2.global.util.ProfileImageService
import com.dotori.v2.domain.member.service.UpdateProfileImageService
import com.dotori.v2.global.thirdparty.aws.s3.S3Service
import com.dotori.v2.global.util.UserUtil
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
Expand All @@ -11,12 +12,10 @@ import org.springframework.web.multipart.MultipartFile
@Transactional(rollbackFor = [Exception::class])
class UpdateProfileImageServiceImpl(
private val userUtil: UserUtil,
private val s3Service: S3Service
private val profileImageService: ProfileImageService
): UpdateProfileImageService {
override fun execute(multipartFiles: MultipartFile?) {
val member = userUtil.fetchCurrentUser()
var uploadFile: String? = s3Service.uploadSingleFile(multipartFiles)
s3Service.deleteFile(member.profileImage!!)
member.updateProfileImage(uploadFile)
val member: Member = userUtil.fetchCurrentUser()
profileImageService.imageUpload(member = member, multipartFiles = multipartFiles, isUpdate = true)
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.dotori.v2.domain.member.service.impl

import com.dotori.v2.domain.member.domain.entity.Member
import com.dotori.v2.global.util.ProfileImageService
import com.dotori.v2.domain.member.service.UploadProfileImageService
import com.dotori.v2.global.thirdparty.aws.s3.S3Service
import com.dotori.v2.global.util.UserUtil
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
Expand All @@ -12,11 +12,10 @@ import org.springframework.web.multipart.MultipartFile
@Transactional(rollbackFor = [Exception::class])
class UploadProfileImageServiceImpl(
private val userUtil: UserUtil,
private val s3Service: S3Service
private val profileImageService: ProfileImageService
): UploadProfileImageService {
override fun execute(multipartFiles: MultipartFile?) {
val member: Member = userUtil.fetchCurrentUser()
var uploadFile: String? = s3Service.uploadSingleFile(multipartFiles)
member.updateProfileImage(uploadFile)
profileImageService.imageUpload(member = member, multipartFiles = multipartFiles)
}
}
Loading

0 comments on commit 348dfb5

Please sign in to comment.