Skip to content

Commit

Permalink
Merge pull request #354 from Team-Ampersand/352-music-cache3
Browse files Browse the repository at this point in the history
기상음악 캐시
  • Loading branch information
esperar committed Jul 2, 2024
2 parents c8c631a + b3ab587 commit 0ccfa2d
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.dotori.v2.domain.music.schedule

import com.dotori.v2.domain.music.domain.repository.MusicRepository
import com.dotori.v2.global.config.redis.service.RedisCacheService
import org.slf4j.LoggerFactory
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional
Expand All @@ -10,13 +12,18 @@ import java.time.LocalDate
@Component
@Transactional
class MusicSchedule(
private val musicRepository: MusicRepository
private val musicRepository: MusicRepository,
private val redisTemplate: RedisTemplate<String, Any>
) {
private val log = LoggerFactory.getLogger(this.javaClass.simpleName)

@Scheduled(cron = "0 0 0 ? * MON-FRI")
fun weekdayMusicStatusReset() {
musicRepository.updateMusicStatusMemberByMember()
val keys = redisTemplate.keys("musicList:*")
if(keys.isNotEmpty()) {
redisTemplate.delete(keys)
}
log.info("Student Music Status Updated At {}", LocalDate.now())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import com.dotori.v2.domain.music.exception.MusicAlreadyException
import com.dotori.v2.domain.music.exception.MusicCantRequestDateException
import com.dotori.v2.domain.music.presentation.data.dto.ApplyMusicDto
import com.dotori.v2.domain.music.presentation.data.req.ApplyMusicReqDto
import com.dotori.v2.domain.music.presentation.data.res.MusicListResDto
import com.dotori.v2.domain.music.presentation.data.res.MusicResDto
import com.dotori.v2.domain.music.service.ApplyMusicService
import com.dotori.v2.domain.student.presentation.data.req.ModifyStudentInfoRequest
import com.dotori.v2.domain.student.presentation.data.res.FindAllStudentResDto
import com.dotori.v2.global.config.redis.service.RedisCacheService
import com.dotori.v2.global.thirdparty.youtube.service.YoutubeService
import com.dotori.v2.global.thirdparty.youtube.data.res.YoutubeResDto
import com.dotori.v2.global.util.UserUtil
Expand All @@ -23,8 +28,12 @@ class ApplyMusicServiceImpl(
private val userUtil: UserUtil,
private val musicRepository: MusicRepository,
private val youtubeService: YoutubeService,
private val memberRepository: MemberRepository
private val memberRepository: MemberRepository,
private val redisCacheService: RedisCacheService
) : ApplyMusicService {

val CACHE_KEY = "musicList"

override fun execute(applyMusicReqDto: ApplyMusicReqDto, dayOfWeek: DayOfWeek): Music {
validDayOfWeek(dayOfWeek)

Expand All @@ -36,6 +45,7 @@ class ApplyMusicServiceImpl(
val music: Music = toDto(applyMusicReqDto)
.let { musicRepository.save(toEntity(it, memberInfo, youtubeInfo)) }
memberInfo.updateMusicStatus(MusicStatus.APPLIED)
updateCache(music)

return music
}
Expand All @@ -45,6 +55,18 @@ class ApplyMusicServiceImpl(
url = applyMusicReqDto.url
)

private fun toDto(music: Music): MusicResDto =
MusicResDto(
id = music.id,
url = music.url,
title = music.title,
thumbnail = music.thumbnail,
username = music.member.memberName,
email = music.member.email,
createdTime = music.createdDate,
stuNum = music.member.stuNum
)

private fun validDayOfWeek(dayOfWeek: DayOfWeek) {
if (dayOfWeek == DayOfWeek.FRIDAY || dayOfWeek == DayOfWeek.SATURDAY)
throw MusicCantRequestDateException()
Expand All @@ -61,4 +83,15 @@ class ApplyMusicServiceImpl(
title = youtubeResDto.title,
thumbnail = youtubeResDto.thumbnail
)

private fun updateCache(music: Music) {
val cachedData = redisCacheService.getFromCache(CACHE_KEY) as? MusicListResDto

if(cachedData != null) {
val content = cachedData.content.toMutableList()
content.add(toDto(music))
val updatedData = MusicListResDto(content)
redisCacheService.putToCache(CACHE_KEY, updatedData)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,38 @@ import com.dotori.v2.domain.music.domain.repository.MusicRepository
import com.dotori.v2.domain.music.presentation.data.res.MusicListResDto
import com.dotori.v2.domain.music.presentation.data.res.MusicResDto
import com.dotori.v2.domain.music.service.FindMusicsService
import com.dotori.v2.global.config.redis.service.RedisCacheService
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.time.LocalDate
import java.time.LocalDateTime

@Service
@Transactional(readOnly = true, rollbackFor = [Exception::class])
class FindMusicsServiceImpl(
private val musicRepository: MusicRepository
private val musicRepository: MusicRepository,
private val redisCacheService: RedisCacheService
) : FindMusicsService {

val CACHE_KEY = "musicList"

override fun execute(date: LocalDate): MusicListResDto {
return MusicListResDto(

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

val response = MusicListResDto(
content = musicRepository.findAllByCreatedDate(date)
.map { toDto(it) }
)

if(date.isEqual(LocalDate.now())) {
redisCacheService.putToCache(CACHE_KEY, response)
}

return response
}

private fun toDto(music: Music): MusicResDto =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ class FindAllMemberServiceImpl(
private val memberRepository: MemberRepository,
private val redisCacheService: RedisCacheService
) : FindAllMemberService {

val CACHE_KEY = "memberList"

override fun execute(): List<FindAllStudentResDto> {
val cacheKey = "memberList"

val cachedData = redisCacheService.getFromCache(cacheKey)
val cachedData = redisCacheService.getFromCache(CACHE_KEY)
if (cachedData != null) {
return cachedData as List<FindAllStudentResDto>
}
Expand All @@ -35,7 +37,7 @@ class FindAllMemberServiceImpl(
)
}

redisCacheService.putToCache(cacheKey, members)
redisCacheService.putToCache(CACHE_KEY, members)

return members
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import org.springframework.stereotype.Service

@Service
class RedisCacheService(
private val redisTemplate: RedisTemplate<String,Any>
private val redisTemplate: RedisTemplate<String, Any>
) {

fun getFromCache(key: String): Any? {
return redisTemplate.opsForValue().get(key)
}

fun putToCache(key: String,value: Any) {
redisTemplate.opsForValue().set(key,value)
fun putToCache(key: String, value: Any) {
redisTemplate.opsForValue().set(key, value)
}

fun updateCacheFromProfile(memberId: Long, uploadFile: String?) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import com.dotori.v2.domain.music.domain.repository.MusicRepository
import com.dotori.v2.domain.music.exception.MusicAlreadyException
import com.dotori.v2.domain.music.exception.MusicCantRequestDateException
import com.dotori.v2.domain.music.presentation.data.req.ApplyMusicReqDto
import com.dotori.v2.domain.music.presentation.data.res.MusicListResDto
import com.dotori.v2.domain.music.presentation.data.res.MusicResDto
import com.dotori.v2.domain.music.service.impl.ApplyMusicServiceImpl
import com.dotori.v2.global.config.redis.service.RedisCacheService
import com.dotori.v2.global.thirdparty.youtube.data.res.YoutubeResDto
import com.dotori.v2.global.thirdparty.youtube.exception.NotValidUrlException
import com.dotori.v2.global.thirdparty.youtube.service.YoutubeService
Expand All @@ -30,7 +33,8 @@ class ApplyMusicServiceTest : BehaviorSpec({
val musicRepository = mockk<MusicRepository>()
val youtubeService = mockk<YoutubeService>()
val memberRepository = mockk<MemberRepository>()
val applyMusicService = ApplyMusicServiceImpl(userUtil, musicRepository, youtubeService, memberRepository)
val redisCacheService = mockk<RedisCacheService>()
val applyMusicService = ApplyMusicServiceImpl(userUtil, musicRepository, youtubeService, memberRepository, redisCacheService)

given("유저가 주어지고") {
val testMember = Member(
Expand Down Expand Up @@ -70,14 +74,18 @@ class ApplyMusicServiceTest : BehaviorSpec({
title = "test",
thumbnail = "test"
)
val musicListResDto = MusicListResDto(mutableListOf())

every { userUtil.fetchCurrentUser() } returns testMember
every { youtubeService.getYoutubeInfo(applyMusicReqDto.url) } returns youtubeResDto
every { musicRepository.save(any()) } returns testMusic
every { memberRepository.findMusicStatusByMemberId(testMember.id) } returns MusicStatus.CAN
every { redisCacheService.getFromCache(any()) } returns musicListResDto
every { redisCacheService.putToCache(any(), any()) } answers { nothing }

`when`("applyMusicReqDto으로 요청하면") {
val result = applyMusicService.execute(applyMusicReqDto, DayOfWeek.THURSDAY)

then("save가 실행되어야함") {
verify(exactly = 1) { musicRepository.save(any()) }
}
Expand All @@ -93,11 +101,14 @@ class ApplyMusicServiceTest : BehaviorSpec({
every { youtubeService.getYoutubeInfo(applyMusicReqDto2.url) } returns youtubeResDto
every { musicRepository.save(any()) } returns testMusic2
every { memberRepository.findMusicStatusByMemberId(testMember.id) } returns MusicStatus.CAN
every { redisCacheService.getFromCache(any()) } returns musicListResDto
every { redisCacheService.putToCache(any(), any()) } answers { nothing }

testMember.updateMusicStatus(MusicStatus.CAN)

`when`("applyMusicReqDto2로 요청하면") {
val result = applyMusicService.execute(applyMusicReqDto2, DayOfWeek.THURSDAY)

then("save가 실행되어야함") {
verify(exactly = 2) { musicRepository.save(any()) }
}
Expand Down

0 comments on commit 0ccfa2d

Please sign in to comment.