Skip to content

Commit

Permalink
Tech - Correction du cache des unités de contrôles (#3661)
Browse files Browse the repository at this point in the history
## Linked issues

- Resolve #3594 
- Le cache ne gère pas les `Deferred`, il faut le gérer manuellement

----

- [ ] Tests E2E (Cypress)
  • Loading branch information
louptheron authored Sep 18, 2024
2 parents 6f7b558 + 9f68cf5 commit e750675
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package fr.gouv.cnsp.monitorfish.domain.repositories

import fr.gouv.cnsp.monitorfish.domain.entities.mission.ControlUnit
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred

interface ControlUnitRepository {
fun findAll(scope: CoroutineScope): Deferred<List<ControlUnit>>
fun findAll(): List<ControlUnit>
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package fr.gouv.cnsp.monitorfish.domain.use_cases.control_units
import fr.gouv.cnsp.monitorfish.config.UseCase
import fr.gouv.cnsp.monitorfish.domain.entities.mission.ControlUnit
import fr.gouv.cnsp.monitorfish.domain.repositories.ControlUnitRepository
import kotlinx.coroutines.runBlocking
import org.slf4j.Logger
import org.slf4j.LoggerFactory

Expand All @@ -14,8 +13,6 @@ class GetAllControlUnits(
private val logger: Logger = LoggerFactory.getLogger(GetAllControlUnits::class.java)

fun execute(): List<ControlUnit> {
return runBlocking {
return@runBlocking controlUnitsRepository.findAll(this).await()
}
return controlUnitsRepository.findAll()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class CaffeineConfiguration {
val findBeaconCache = buildMinutesCache(findBeacon, ticker, 60)

// Control Units
val controlUnitsCache = buildMinutesCache(controlUnits, ticker, oneWeek)
val controlUnitsCache = buildMinutesCache(controlUnits, ticker, oneDay)

// FAO Areas
val faoAreasCache = buildMinutesCache(faoAreas, ticker, oneWeek)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import fr.gouv.cnsp.monitorfish.domain.entities.mission.ControlUnit
import fr.gouv.cnsp.monitorfish.domain.repositories.ControlUnitRepository
import io.ktor.client.call.*
import io.ktor.client.request.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.cache.annotation.Cacheable
Expand All @@ -22,8 +20,8 @@ class APIControlUnitRepository(
private val logger: Logger = LoggerFactory.getLogger(APIControlUnitRepository::class.java)

@Cacheable(value = ["control_units"])
override fun findAll(scope: CoroutineScope): Deferred<List<ControlUnit>> {
return scope.async {
override fun findAll(): List<ControlUnit> =
runBlocking {
val missionsUrl = "${monitorenvProperties.url}/api/v1/control_units"

try {
Expand All @@ -34,5 +32,4 @@ class APIControlUnitRepository(
listOf()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fr.gouv.cnsp.monitorfish.infrastructure.monitorenv

import com.github.benmanes.caffeine.cache.Caffeine
import fr.gouv.cnsp.monitorfish.config.ApiClient
import fr.gouv.cnsp.monitorfish.config.MonitorenvProperties
import fr.gouv.cnsp.monitorfish.domain.entities.mission.ControlUnit
Expand All @@ -15,10 +16,10 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Repository
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.util.concurrent.TimeUnit

@Repository
class APIMissionRepository(
Expand All @@ -28,16 +29,30 @@ class APIMissionRepository(
private val logger: Logger = LoggerFactory.getLogger(APIMissionRepository::class.java)
private val zoneDateTimeFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.000X")

@Cacheable(value = ["mission_control_units"])
private val cache =
Caffeine.newBuilder()
.maximumSize(500)
.expireAfterWrite(1, TimeUnit.DAYS)
.build<String, List<ControlUnit>>()

override fun findControlUnitsOfMission(
scope: CoroutineScope,
missionId: Int,
): Deferred<List<ControlUnit>> {
val cacheKey = "control_units_$missionId"
val cachedControlUnits = cache.getIfPresent(cacheKey)

cachedControlUnits?.let { return@findControlUnitsOfMission scope.async { it } }

return scope.async {
val missionsUrl = "${monitorenvProperties.url}/api/v1/missions/$missionId"

try {
apiClient.httpClient.get(missionsUrl).body<MissionDataResponse>().controlUnits
val controlUnits = apiClient.httpClient.get(missionsUrl).body<MissionDataResponse>().controlUnits

cache.put(cacheKey, controlUnits)

return@async controlUnits
} catch (e: Exception) {
logger.error("Could not fetch control units for mission $missionId at $missionsUrl", e)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package fr.gouv.cnsp.monitorfish.infrastructure.monitorenv

import fr.gouv.cnsp.monitorfish.config.ApiClient
import fr.gouv.cnsp.monitorfish.config.MonitorenvProperties
import io.ktor.client.engine.mock.*
import io.ktor.http.*
import io.ktor.utils.io.*
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test

class APIControlUnitRepositoryITests {
@Test
fun `findAll Should return control units`() {
// Given
val mockEngine =
MockEngine { _ ->
respond(
content =
ByteReadChannel(
"""[
{
"id": 10016,
"administration": "Douane",
"isArchived": false,
"name": "BSN Ste Maxime",
"resources": [],
"contact": null
},
{
"id": 10017,
"administration": "Douane",
"isArchived": false,
"name": "DF 25 Libecciu",
"resources": [],
"contact": null
},
{
"id": 10018,
"administration": "Douane",
"isArchived": false,
"name": "DF 61 Port-de-Bouc",
"resources": [],
"contact": null
}
]""",
),
status = HttpStatusCode.OK,
headers = headersOf(HttpHeaders.ContentType, "application/json"),
)
}
val apiClient = ApiClient(mockEngine)
val monitorenvProperties = MonitorenvProperties()
monitorenvProperties.url = "http://test"

// When
val controlUnits =
APIControlUnitRepository(monitorenvProperties, apiClient)
.findAll()

assertThat(controlUnits).hasSize(3)
assertThat(controlUnits.first().id).isEqualTo(10016)
}
}

0 comments on commit e750675

Please sign in to comment.