From 7a89c5dad0fe18ebe0d74ea72f67dbb8d4c96d21 Mon Sep 17 00:00:00 2001 From: MinJun Kim Date: Sat, 11 Nov 2023 15:52:19 +0900 Subject: [PATCH 1/8] feat: enable cache when get events --- build.gradle.kts | 1 + .../TicketingserviceApplication.kt | 3 ++- .../ticketingservice/config/CacheConfig.kt | 23 +++++++++++++++++++ .../controller/EventController.kt | 3 +++ 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/com/group4/ticketingservice/config/CacheConfig.kt diff --git a/build.gradle.kts b/build.gradle.kts index e4c0a8d5..c2e66c6b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -52,6 +52,7 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-data-jpa") implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-jdbc") + implementation("org.springframework.boot:spring-boot-starter-cache") implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("com.ninja-squad:springmockk:4.0.2") diff --git a/src/main/kotlin/com/group4/ticketingservice/TicketingserviceApplication.kt b/src/main/kotlin/com/group4/ticketingservice/TicketingserviceApplication.kt index 35084a6b..537ca03c 100644 --- a/src/main/kotlin/com/group4/ticketingservice/TicketingserviceApplication.kt +++ b/src/main/kotlin/com/group4/ticketingservice/TicketingserviceApplication.kt @@ -2,10 +2,11 @@ package com.group4.ticketingservice import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication +import org.springframework.cache.annotation.EnableCaching @SpringBootApplication +@EnableCaching class TicketingserviceApplication - fun main(args: Array) { runApplication(*args) } diff --git a/src/main/kotlin/com/group4/ticketingservice/config/CacheConfig.kt b/src/main/kotlin/com/group4/ticketingservice/config/CacheConfig.kt new file mode 100644 index 00000000..5b07da63 --- /dev/null +++ b/src/main/kotlin/com/group4/ticketingservice/config/CacheConfig.kt @@ -0,0 +1,23 @@ +package com.group4.ticketingservice.config + +import org.springframework.cache.CacheManager +import org.springframework.cache.annotation.EnableCaching +import org.springframework.cache.concurrent.ConcurrentMapCache +import org.springframework.cache.support.SimpleCacheManager +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +@Configuration +@EnableCaching +class CacheConfig { + @Bean + fun cacheManager(): CacheManager { + val simpleCacheManager = SimpleCacheManager() + simpleCacheManager.setCaches( + listOf( + ConcurrentMapCache("getEvents") + ) + ) + return simpleCacheManager + } +} diff --git a/src/main/kotlin/com/group4/ticketingservice/controller/EventController.kt b/src/main/kotlin/com/group4/ticketingservice/controller/EventController.kt index 1904d7a3..d56b2812 100644 --- a/src/main/kotlin/com/group4/ticketingservice/controller/EventController.kt +++ b/src/main/kotlin/com/group4/ticketingservice/controller/EventController.kt @@ -8,6 +8,7 @@ import io.swagger.v3.oas.annotations.Hidden import jakarta.servlet.http.HttpServletRequest import jakarta.validation.Valid import org.springframework.beans.factory.annotation.Autowired +import org.springframework.cache.annotation.Cacheable import org.springframework.data.domain.Page import org.springframework.data.domain.Pageable import org.springframework.data.domain.Sort @@ -82,6 +83,8 @@ class EventController @Autowired constructor( } @GetMapping + // cache 구현체 를 설정해햐 하나 ?,https://yeon-kr.tistory.com/177 + @Cacheable(value = ["getEvents"], key = "#pageable.pageNumber") fun getEvents( request: HttpServletRequest, @RequestParam(required = false) name: String?, From 3cdd507ed942bb571529944974c0576a530c478b Mon Sep 17 00:00:00 2001 From: MinJun Kim Date: Sat, 11 Nov 2023 19:38:09 +0900 Subject: [PATCH 2/8] test: check cache exist --- .../Event/EventControllerTest.kt | 33 +++++++++++++++++++ .../controller/EventController.kt | 1 - .../event/EventControllerTest.kt | 7 ++-- 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 src/integrationTest/kotlin/com/group4/ticketingservice/Event/EventControllerTest.kt diff --git a/src/integrationTest/kotlin/com/group4/ticketingservice/Event/EventControllerTest.kt b/src/integrationTest/kotlin/com/group4/ticketingservice/Event/EventControllerTest.kt new file mode 100644 index 00000000..6898aa54 --- /dev/null +++ b/src/integrationTest/kotlin/com/group4/ticketingservice/Event/EventControllerTest.kt @@ -0,0 +1,33 @@ +package com.group4.ticketingservice.Event + +import com.group4.ticketingservice.AbstractIntegrationTest +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc +import org.springframework.cache.CacheManager +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders + +@AutoConfigureMockMvc +class EventControllerTest : AbstractIntegrationTest() { + @Autowired + private lateinit var mockMvc: MockMvc + + @Autowired + private lateinit var cacheManager: CacheManager + + @Test + fun `getEvents caches the result`() { + mockMvc.perform( + MockMvcRequestBuilders.get("/events") + .param("page", "0") + .param("size", "10") + + ) + + val cache = cacheManager.getCache("getEvents") + val cachedValue = cache!!.get(0) + + assert(cachedValue != null) + } +} diff --git a/src/main/kotlin/com/group4/ticketingservice/controller/EventController.kt b/src/main/kotlin/com/group4/ticketingservice/controller/EventController.kt index d56b2812..188b481b 100644 --- a/src/main/kotlin/com/group4/ticketingservice/controller/EventController.kt +++ b/src/main/kotlin/com/group4/ticketingservice/controller/EventController.kt @@ -83,7 +83,6 @@ class EventController @Autowired constructor( } @GetMapping - // cache 구현체 를 설정해햐 하나 ?,https://yeon-kr.tistory.com/177 @Cacheable(value = ["getEvents"], key = "#pageable.pageNumber") fun getEvents( request: HttpServletRequest, diff --git a/src/test/kotlin/com/group4/ticketingservice/event/EventControllerTest.kt b/src/test/kotlin/com/group4/ticketingservice/event/EventControllerTest.kt index c5933162..405d9d31 100644 --- a/src/test/kotlin/com/group4/ticketingservice/event/EventControllerTest.kt +++ b/src/test/kotlin/com/group4/ticketingservice/event/EventControllerTest.kt @@ -14,6 +14,7 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest +import org.springframework.cache.CacheManager import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.FilterType import org.springframework.data.domain.Page @@ -34,11 +35,12 @@ import java.time.OffsetDateTime @WebMvcTest( EventController::class, includeFilters = arrayOf( - ComponentScan.Filter(value = [(SecurityConfig::class), (TokenProvider::class), (JwtAuthorizationEntryPoint::class)], type = FilterType.ASSIGNABLE_TYPE) + ComponentScan.Filter(value = [(SecurityConfig::class), (TokenProvider::class), (JwtAuthorizationEntryPoint::class), (CacheManager::class)], type = FilterType.ASSIGNABLE_TYPE) ) ) class EventControllerTest( - @Autowired val mockMvc: MockMvc + @Autowired val mockMvc: MockMvc, + @Autowired val cacheManager: CacheManager ) { @MockkBean private lateinit var eventService: EventService @@ -178,6 +180,7 @@ class EventControllerTest( @Test fun `GET List of events should return list of events with pagination and sorting`() { // Given + every { eventService.getEvents(any(), any()) } returns page // When From d6a53d9f32d6d83fa4618192dc681d365b54dbf7 Mon Sep 17 00:00:00 2001 From: Git Actions Date: Sat, 11 Nov 2023 10:40:12 +0000 Subject: [PATCH 3/8] docs: update open-api.yaml --- docs/open-api.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/open-api.yaml b/docs/open-api.yaml index 5b73897d..ae45e5f3 100644 --- a/docs/open-api.yaml +++ b/docs/open-api.yaml @@ -519,10 +519,10 @@ components: pageSize: type: integer format: int32 - unpaged: - type: boolean paged: type: boolean + unpaged: + type: boolean Reservation: required: - address @@ -607,12 +607,12 @@ components: type: string isEnabled: type: boolean + username: + type: string authorities: type: array items: $ref: '#/components/schemas/GrantedAuthority' - username: - type: string isAccountNonExpired: type: boolean isAccountNonLocked: From 2fef5e16cc7a4979de1b1f158d4d35bb2024b995 Mon Sep 17 00:00:00 2001 From: Git Actions Date: Sun, 12 Nov 2023 04:10:53 +0000 Subject: [PATCH 4/8] docs: update open-api.yaml --- docs/open-api.yaml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/open-api.yaml b/docs/open-api.yaml index ae45e5f3..35b68cfe 100644 --- a/docs/open-api.yaml +++ b/docs/open-api.yaml @@ -494,15 +494,15 @@ components: format: int32 sort: $ref: '#/components/schemas/SortObject' - first: - type: boolean - last: - type: boolean numberOfElements: type: integer format: int32 pageable: $ref: '#/components/schemas/PageableObject' + first: + type: boolean + last: + type: boolean empty: type: boolean PageableObject: @@ -640,15 +640,15 @@ components: format: int32 sort: $ref: '#/components/schemas/SortObject' - first: - type: boolean - last: - type: boolean numberOfElements: type: integer format: int32 pageable: $ref: '#/components/schemas/PageableObject' + first: + type: boolean + last: + type: boolean empty: type: boolean EventResponse: @@ -703,14 +703,14 @@ components: format: int32 sort: $ref: '#/components/schemas/SortObject' - first: - type: boolean - last: - type: boolean numberOfElements: type: integer format: int32 pageable: $ref: '#/components/schemas/PageableObject' + first: + type: boolean + last: + type: boolean empty: type: boolean From 1ae31686d7063b361370b030b3ff19a24f8fa6e6 Mon Sep 17 00:00:00 2001 From: MinJun Kim Date: Mon, 13 Nov 2023 19:36:47 +0900 Subject: [PATCH 5/8] feat: expire cache and caching with name --- .../group4/ticketingservice/config/CacheConfig.kt | 12 +++++++++++- .../ticketingservice/controller/EventController.kt | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/group4/ticketingservice/config/CacheConfig.kt b/src/main/kotlin/com/group4/ticketingservice/config/CacheConfig.kt index 5b07da63..23ac5d0e 100644 --- a/src/main/kotlin/com/group4/ticketingservice/config/CacheConfig.kt +++ b/src/main/kotlin/com/group4/ticketingservice/config/CacheConfig.kt @@ -1,23 +1,33 @@ package com.group4.ticketingservice.config import org.springframework.cache.CacheManager +import org.springframework.cache.annotation.CacheEvict import org.springframework.cache.annotation.EnableCaching import org.springframework.cache.concurrent.ConcurrentMapCache import org.springframework.cache.support.SimpleCacheManager import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import org.springframework.scheduling.annotation.Scheduled @Configuration @EnableCaching class CacheConfig { + companion object { + private const val EVENT_CACHE = "getEvents" + } + @Bean fun cacheManager(): CacheManager { val simpleCacheManager = SimpleCacheManager() simpleCacheManager.setCaches( listOf( - ConcurrentMapCache("getEvents") + ConcurrentMapCache(EVENT_CACHE) ) ) return simpleCacheManager } + + @CacheEvict(allEntries = true, value = [EVENT_CACHE]) + @Scheduled(fixedDelay = 10 * 60 * 1000, initialDelay = 500) + fun cacheEvict() {} } diff --git a/src/main/kotlin/com/group4/ticketingservice/controller/EventController.kt b/src/main/kotlin/com/group4/ticketingservice/controller/EventController.kt index 188b481b..1abc9b2d 100644 --- a/src/main/kotlin/com/group4/ticketingservice/controller/EventController.kt +++ b/src/main/kotlin/com/group4/ticketingservice/controller/EventController.kt @@ -83,7 +83,7 @@ class EventController @Autowired constructor( } @GetMapping - @Cacheable(value = ["getEvents"], key = "#pageable.pageNumber") + @Cacheable(value = ["getEvents"], key = "#pageable.pageNumber+#name") fun getEvents( request: HttpServletRequest, @RequestParam(required = false) name: String?, From 02b806288f6d135818cc40c80f0b0ccd7502b831 Mon Sep 17 00:00:00 2001 From: Git Actions Date: Mon, 13 Nov 2023 10:40:35 +0000 Subject: [PATCH 6/8] docs: update open-api.yaml --- docs/open-api.yaml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/open-api.yaml b/docs/open-api.yaml index 35b68cfe..ae45e5f3 100644 --- a/docs/open-api.yaml +++ b/docs/open-api.yaml @@ -494,15 +494,15 @@ components: format: int32 sort: $ref: '#/components/schemas/SortObject' + first: + type: boolean + last: + type: boolean numberOfElements: type: integer format: int32 pageable: $ref: '#/components/schemas/PageableObject' - first: - type: boolean - last: - type: boolean empty: type: boolean PageableObject: @@ -640,15 +640,15 @@ components: format: int32 sort: $ref: '#/components/schemas/SortObject' + first: + type: boolean + last: + type: boolean numberOfElements: type: integer format: int32 pageable: $ref: '#/components/schemas/PageableObject' - first: - type: boolean - last: - type: boolean empty: type: boolean EventResponse: @@ -703,14 +703,14 @@ components: format: int32 sort: $ref: '#/components/schemas/SortObject' + first: + type: boolean + last: + type: boolean numberOfElements: type: integer format: int32 pageable: $ref: '#/components/schemas/PageableObject' - first: - type: boolean - last: - type: boolean empty: type: boolean From 97648aad8b0d65c8d97df84c5000d2bef7c76fde Mon Sep 17 00:00:00 2001 From: MinJun Kim Date: Mon, 13 Nov 2023 22:22:56 +0900 Subject: [PATCH 7/8] feat: apply pr --- .../com/group4/ticketingservice/Event/EventControllerTest.kt | 2 +- .../com/group4/ticketingservice/controller/EventController.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/integrationTest/kotlin/com/group4/ticketingservice/Event/EventControllerTest.kt b/src/integrationTest/kotlin/com/group4/ticketingservice/Event/EventControllerTest.kt index 6898aa54..8d057a0e 100644 --- a/src/integrationTest/kotlin/com/group4/ticketingservice/Event/EventControllerTest.kt +++ b/src/integrationTest/kotlin/com/group4/ticketingservice/Event/EventControllerTest.kt @@ -26,7 +26,7 @@ class EventControllerTest : AbstractIntegrationTest() { ) val cache = cacheManager.getCache("getEvents") - val cachedValue = cache!!.get(0) + val cachedValue = cache!!.get("0-10-id: DESC-null") assert(cachedValue != null) } diff --git a/src/main/kotlin/com/group4/ticketingservice/controller/EventController.kt b/src/main/kotlin/com/group4/ticketingservice/controller/EventController.kt index 1abc9b2d..8d61bbc7 100644 --- a/src/main/kotlin/com/group4/ticketingservice/controller/EventController.kt +++ b/src/main/kotlin/com/group4/ticketingservice/controller/EventController.kt @@ -83,14 +83,14 @@ class EventController @Autowired constructor( } @GetMapping - @Cacheable(value = ["getEvents"], key = "#pageable.pageNumber+#name") + @Cacheable(value = ["getEvents"], key = "#pageable.pageNumber+'-'+#pageable.pageSize+'-'+#pageable.sort.toString()+'-'+#name") fun getEvents( request: HttpServletRequest, @RequestParam(required = false) name: String?, @PageableDefault(size = 10, sort = ["id"], direction = Sort.Direction.DESC) pageable: Pageable ): ResponseEntity> { val page = eventService.getEvents(name, pageable) - + print(pageable.sort.toString()) val headers = HttpHeaders() headers.set("Content-Location", request.requestURI) From f1bd2849941fd6d2e92fccf725da4fc952bb95b3 Mon Sep 17 00:00:00 2001 From: Git Actions Date: Mon, 13 Nov 2023 13:26:01 +0000 Subject: [PATCH 8/8] docs: update open-api.yaml --- docs/open-api.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/open-api.yaml b/docs/open-api.yaml index ae45e5f3..b883770f 100644 --- a/docs/open-api.yaml +++ b/docs/open-api.yaml @@ -519,10 +519,10 @@ components: pageSize: type: integer format: int32 - paged: - type: boolean unpaged: type: boolean + paged: + type: boolean Reservation: required: - address