From b11b1806112873750822c42e91e24785db400971 Mon Sep 17 00:00:00 2001 From: Jim Martens Date: Mon, 25 Aug 2025 15:45:45 +0200 Subject: [PATCH] change: Add timetable id to BahnTimetable --- .../timetable/bahnApi/mapper/BahnTimetableMapper.kt | 4 +++- .../timetable/bahnApi/model/TaskFactory.kt | 6 ++++-- .../timetable/bahnApi/model/db/BahnTimetable.kt | 5 ++++- .../bahnApi/model/db/ScheduledFetchTask.kt | 4 +++- .../bahnApi/repository/BahnTimetableRepository.kt | 6 +++--- .../bahnApi/service/BahnDatabaseService.kt | 5 ++++- .../timetable/bahnApi/service/FetchTaskScheduler.kt | 6 +++++- .../bahnApi/service/ScheduledTaskService.kt | 13 ++++++++----- .../timetable/bahnApi/tasks/FetchTimetableTask.kt | 4 +++- .../timetable/bahnApi/tasks/StoreTimetableTask.kt | 4 +++- .../timetable/timetable/TimetableController.kt | 3 ++- 11 files changed, 42 insertions(+), 18 deletions(-) diff --git a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/mapper/BahnTimetableMapper.kt b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/mapper/BahnTimetableMapper.kt index d2e481f..ba02a3d 100644 --- a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/mapper/BahnTimetableMapper.kt +++ b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/mapper/BahnTimetableMapper.kt @@ -4,6 +4,7 @@ import de.twomartens.timetable.bahnApi.model.db.BahnStationStop import de.twomartens.timetable.bahnApi.model.db.BahnStopEvent import de.twomartens.timetable.bahnApi.model.db.BahnTimetable import de.twomartens.timetable.model.common.RouteId +import de.twomartens.timetable.model.common.TimetableId import de.twomartens.timetable.model.common.UserId import de.twomartens.timetable.types.HourAtDay import de.twomartens.timetable.types.NonEmptyString @@ -21,12 +22,13 @@ interface BahnTimetableMapper { @Mapping(target = "created", ignore = true) @Mapping(target = "lastModified", ignore = true) fun mapToDB(dto: de.twomartens.timetable.bahnApi.model.dto.BahnTimetable, - userId: UserId, routeId: RouteId, + userId: UserId, routeId: RouteId, tswTimetableId: TimetableId, hourAtDay: HourAtDay, clock: Clock): BahnTimetable { return BahnTimetable( userId, routeId, + tswTimetableId, dto.eva, ZonedDateTime.of(hourAtDay.dateTime, clock.zone), NonEmptyString(dto.station), diff --git a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/TaskFactory.kt b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/TaskFactory.kt index edc8bb2..e6a28b2 100644 --- a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/TaskFactory.kt +++ b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/TaskFactory.kt @@ -2,6 +2,7 @@ package de.twomartens.timetable.bahnApi.model import de.twomartens.timetable.bahnApi.model.db.ScheduledFetchTask import de.twomartens.timetable.model.common.RouteId +import de.twomartens.timetable.model.common.TimetableId import de.twomartens.timetable.model.common.UserId import de.twomartens.timetable.types.HourAtDay import org.springframework.stereotype.Component @@ -20,11 +21,12 @@ class TaskFactory { countTasks(existingTasks) } - fun createTaskAndUpdateCounter(userId: UserId, routeId: RouteId, eva: Eva, + fun createTaskAndUpdateCounter(userId: UserId, routeId: RouteId, + tswTimetableId: TimetableId, eva: Eva, hourAtDay: HourAtDay): ScheduledFetchTask { val fetchDateTime = calculateNextAvailableFetchDateTime(hourAtDay) incrementTaskCountForHourAtDay(hourAtDay) - return ScheduledFetchTask(userId, routeId, eva, hourAtDay, fetchDateTime) + return ScheduledFetchTask(userId, routeId, tswTimetableId, eva, hourAtDay, fetchDateTime) } private fun calculateNextAvailableFetchDateTime(hourAtDay: HourAtDay): LocalDateTime { diff --git a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/BahnTimetable.kt b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/BahnTimetable.kt index 181ac39..21098e0 100644 --- a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/BahnTimetable.kt +++ b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/BahnTimetable.kt @@ -2,6 +2,7 @@ package de.twomartens.timetable.bahnApi.model.db import de.twomartens.timetable.bahnApi.model.Eva import de.twomartens.timetable.model.common.RouteId +import de.twomartens.timetable.model.common.TimetableId import de.twomartens.timetable.model.common.UserId import de.twomartens.timetable.types.NonEmptyString import org.bson.types.ObjectId @@ -14,10 +15,12 @@ import java.time.Instant import java.time.ZonedDateTime @Document -@CompoundIndex(def = "{'userId': 1, 'routeId': 1, 'eva': 1, 'hourAtDay': 1}", unique = true) +@CompoundIndex(def = "{'userId': 1, 'routeId': 1, 'tswTimetableId': 1, 'eva': 1, 'hourAtDay': 1}", + unique = true) data class BahnTimetable( var userId: UserId, var routeId: RouteId, + var tswTimetableId: TimetableId, var eva: Eva, var hourAtDay: ZonedDateTime, var station: NonEmptyString, diff --git a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/ScheduledFetchTask.kt b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/ScheduledFetchTask.kt index 3bc1cfb..702b107 100644 --- a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/ScheduledFetchTask.kt +++ b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/model/db/ScheduledFetchTask.kt @@ -2,6 +2,7 @@ package de.twomartens.timetable.bahnApi.model.db import de.twomartens.timetable.bahnApi.model.Eva import de.twomartens.timetable.model.common.RouteId +import de.twomartens.timetable.model.common.TimetableId import de.twomartens.timetable.model.common.UserId import de.twomartens.timetable.types.HourAtDay import org.bson.types.ObjectId @@ -14,10 +15,11 @@ import java.time.Instant import java.time.LocalDateTime @Document -@CompoundIndex(def = "{'userId': 1, 'routeId': 1, 'eva': 1, 'fetchedDateTime': 1}") +@CompoundIndex(def = "{'userId': 1, 'routeId': 1, 'tswTimetableId': 1, 'eva': 1, 'fetchedDateTime': 1}") data class ScheduledFetchTask( var userId: UserId, var routeId: RouteId, + var tswTimetableId: TimetableId, var eva: Eva, var fetchedDateTime: HourAtDay, var scheduledExecutionDateTime: LocalDateTime diff --git a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/repository/BahnTimetableRepository.kt b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/repository/BahnTimetableRepository.kt index 3946b25..8844ebc 100644 --- a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/repository/BahnTimetableRepository.kt +++ b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/repository/BahnTimetableRepository.kt @@ -2,19 +2,19 @@ package de.twomartens.timetable.bahnApi.repository import de.twomartens.timetable.bahnApi.model.Eva import de.twomartens.timetable.bahnApi.model.db.BahnTimetable -import de.twomartens.timetable.types.HourAtDay import org.bson.types.ObjectId import org.springframework.data.domain.ExampleMatcher import org.springframework.data.mongodb.repository.MongoRepository +import java.time.ZonedDateTime -// TODO: figure out what ID type should be interface BahnTimetableRepository : MongoRepository { - fun findByEvaAndHourAtDay(eva: Eva, hourAtDay: HourAtDay): BahnTimetable? + fun findByEvaAndHourAtDay(eva: Eva, hourAtDay: ZonedDateTime): BahnTimetable? fun getExampleMatcher(): ExampleMatcher { return ExampleMatcher.matching() .withMatcher("userId", ExampleMatcher.GenericPropertyMatchers.exact()) .withMatcher("routeId", ExampleMatcher.GenericPropertyMatchers.exact()) + .withMatcher("tswTimetableId", ExampleMatcher.GenericPropertyMatchers.exact()) .withMatcher("eva", ExampleMatcher.GenericPropertyMatchers.exact()) .withMatcher("hourAtDay", ExampleMatcher.GenericPropertyMatchers.exact()) } diff --git a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/service/BahnDatabaseService.kt b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/service/BahnDatabaseService.kt index 99da7ae..f62c6e0 100644 --- a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/service/BahnDatabaseService.kt +++ b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/service/BahnDatabaseService.kt @@ -7,6 +7,7 @@ import de.twomartens.timetable.bahnApi.model.dto.BahnTimetable import de.twomartens.timetable.bahnApi.repository.BahnStationRepository import de.twomartens.timetable.bahnApi.repository.BahnTimetableRepository import de.twomartens.timetable.model.common.RouteId +import de.twomartens.timetable.model.common.TimetableId import de.twomartens.timetable.model.common.UserId import de.twomartens.timetable.model.db.Station import de.twomartens.timetable.model.repository.StationRepository @@ -93,9 +94,11 @@ open class BahnDatabaseService( } fun storeTimetable(timetable: BahnTimetable, userId: UserId, routeId: RouteId, + tswTimetableId: TimetableId, hourAtDay: HourAtDay) { val matcher = bahnTimetableRepository.getExampleMatcher() - val dbTimetable = bahnTimetableMapper.mapToDB(timetable, userId, routeId, hourAtDay, clock) + val dbTimetable = bahnTimetableMapper.mapToDB(timetable, userId, routeId, + tswTimetableId, hourAtDay, clock) val existingTimetable = bahnTimetableRepository.findOne(Example.of(dbTimetable, matcher)) existingTimetable .map { diff --git a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/service/FetchTaskScheduler.kt b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/service/FetchTaskScheduler.kt index 19fef80..f88b441 100644 --- a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/service/FetchTaskScheduler.kt +++ b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/service/FetchTaskScheduler.kt @@ -7,6 +7,7 @@ import de.twomartens.timetable.bahnApi.tasks.DeleteScheduledTask import de.twomartens.timetable.bahnApi.tasks.FetchTimetableTask import de.twomartens.timetable.bahnApi.tasks.StoreTimetableTask import de.twomartens.timetable.model.common.RouteId +import de.twomartens.timetable.model.common.TimetableId import de.twomartens.timetable.model.common.UserId import de.twomartens.timetable.types.HourAtDay import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor @@ -27,8 +28,10 @@ class FetchTaskScheduler( private val scheduledFetchTaskRepository: ScheduledFetchTaskRepository ) { fun scheduleStoreTask(timetable: BahnTimetable, userId: UserId, routeId: RouteId, + tswTimetableId: TimetableId, hourAtDay: HourAtDay) { - val storeTask = StoreTimetableTask(timetable, userId, routeId, hourAtDay, bahnDatabaseService) + val storeTask = StoreTimetableTask(timetable, userId, routeId, tswTimetableId, + hourAtDay, bahnDatabaseService) threadPoolTaskExecutor.execute(storeTask) } @@ -82,6 +85,7 @@ class FetchTaskScheduler( zonedExecutionTime: ZonedDateTime ) { val timetableTask = FetchTimetableTask(scheduledFetchTask.userId, scheduledFetchTask.routeId, + scheduledFetchTask.tswTimetableId, scheduledFetchTask.eva, scheduledFetchTask.fetchedDateTime, bahnApiService, this) threadPoolTaskScheduler.schedule(timetableTask, zonedExecutionTime.toInstant()) diff --git a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/service/ScheduledTaskService.kt b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/service/ScheduledTaskService.kt index 15b252d..b1f3b54 100644 --- a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/service/ScheduledTaskService.kt +++ b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/service/ScheduledTaskService.kt @@ -6,6 +6,7 @@ import de.twomartens.timetable.bahnApi.model.FetchDates import de.twomartens.timetable.bahnApi.model.TaskFactory import de.twomartens.timetable.bahnApi.model.db.ScheduledFetchTask import de.twomartens.timetable.bahnApi.repository.ScheduledFetchTaskRepository +import de.twomartens.timetable.model.common.TimetableId import de.twomartens.timetable.model.db.TswRoute import de.twomartens.timetable.types.Hour import de.twomartens.timetable.types.HourAtDay @@ -52,12 +53,13 @@ class ScheduledTaskService( lastUpdate = updateTime } - fun triggerTimetableFetch(tswRoute: TswRoute, fetchedDate: LocalDate) { + fun triggerTimetableFetch(tswRoute: TswRoute, tswTimetableId: TimetableId, + fetchedDate: LocalDate) { log.info { "Trigger timetable fetch: [route ${tswRoute.name}]" } val fetchDates = calculateDatesToFetch(fetchedDate) - val newTasks = buildScheduledTasks(tswRoute, fetchDates) + val newTasks = buildScheduledTasks(tswRoute, tswTimetableId, fetchDates) storeTasksInDatabaseAndStoreCreationTime(newTasks) val event = FetchTasksCreatedEvent(this) @@ -72,6 +74,7 @@ class ScheduledTaskService( private fun buildScheduledTasks( tswRoute: TswRoute, + tswTimetableId: TimetableId, fetchDates: FetchDates ): List { val newTasks = mutableListOf() @@ -80,18 +83,18 @@ class ScheduledTaskService( val eva = Eva.of(stationId) var hourAtDay = HourAtDay.of(Hour.of(23), fetchDates.previousDay) var newTask = taskFactory.createTaskAndUpdateCounter(tswRoute.userId, - tswRoute.routeId, eva, hourAtDay) + tswRoute.routeId, tswTimetableId, eva, hourAtDay) newTasks.add(newTask) for (hour in 0..23) { hourAtDay = HourAtDay.of(Hour.of(hour), fetchDates.fetchDate) newTask = taskFactory.createTaskAndUpdateCounter(tswRoute.userId, - tswRoute.routeId, eva, hourAtDay) + tswRoute.routeId, tswTimetableId, eva, hourAtDay) newTasks.add(newTask) } for (hour in 0..3) { hourAtDay = HourAtDay.of(Hour.of(hour), fetchDates.nextDate) newTask = taskFactory.createTaskAndUpdateCounter(tswRoute.userId, - tswRoute.routeId, eva, hourAtDay) + tswRoute.routeId, tswTimetableId, eva, hourAtDay) newTasks.add(newTask) } } diff --git a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/tasks/FetchTimetableTask.kt b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/tasks/FetchTimetableTask.kt index a0f6228..c1988d7 100644 --- a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/tasks/FetchTimetableTask.kt +++ b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/tasks/FetchTimetableTask.kt @@ -4,6 +4,7 @@ import de.twomartens.timetable.bahnApi.model.Eva import de.twomartens.timetable.bahnApi.service.BahnApiService import de.twomartens.timetable.bahnApi.service.FetchTaskScheduler import de.twomartens.timetable.model.common.RouteId +import de.twomartens.timetable.model.common.TimetableId import de.twomartens.timetable.model.common.UserId import de.twomartens.timetable.types.HourAtDay import mu.KotlinLogging @@ -13,6 +14,7 @@ import org.springframework.scheduling.annotation.Async open class FetchTimetableTask( private val userId: UserId, private val routeId: RouteId, + private val tswTimetableId: TimetableId, private val eva: Eva, private val hourAtDay: HourAtDay, private val bahnApiService: BahnApiService, @@ -22,7 +24,7 @@ open class FetchTimetableTask( "Fetch timetable: [eva: $eva], [date: ${hourAtDay.date}], [hour: ${hourAtDay.hour}]" } val timetable = bahnApiService.fetchTimetable(eva, hourAtDay) - scheduler.scheduleStoreTask(timetable, userId, routeId, hourAtDay) + scheduler.scheduleStoreTask(timetable, userId, routeId, tswTimetableId, hourAtDay) } companion object { diff --git a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/tasks/StoreTimetableTask.kt b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/tasks/StoreTimetableTask.kt index d4f653e..a517fd6 100644 --- a/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/tasks/StoreTimetableTask.kt +++ b/module-bahnApi/src/main/kotlin/de/twomartens/timetable/bahnApi/tasks/StoreTimetableTask.kt @@ -3,6 +3,7 @@ package de.twomartens.timetable.bahnApi.tasks import de.twomartens.timetable.bahnApi.model.dto.BahnTimetable import de.twomartens.timetable.bahnApi.service.BahnDatabaseService import de.twomartens.timetable.model.common.RouteId +import de.twomartens.timetable.model.common.TimetableId import de.twomartens.timetable.model.common.UserId import de.twomartens.timetable.types.HourAtDay import mu.KotlinLogging @@ -13,12 +14,13 @@ open class StoreTimetableTask( private val timetable: BahnTimetable, private val userId: UserId, private val routeId: RouteId, + private val tswTimetableId: TimetableId, private val hourAtDay: HourAtDay, private val bahnDatabaseService: BahnDatabaseService ) : Runnable { override fun run() { log.info { "Store timetable: [eva: ${timetable.eva}], [station: ${timetable.station}], [hour: ${hourAtDay}]" } - bahnDatabaseService.storeTimetable(timetable, userId, routeId, hourAtDay) + bahnDatabaseService.storeTimetable(timetable, userId, routeId, tswTimetableId, hourAtDay) } companion object { diff --git a/module-server/src/main/kotlin/de/twomartens/timetable/timetable/TimetableController.kt b/module-server/src/main/kotlin/de/twomartens/timetable/timetable/TimetableController.kt index c12a903..0e7d4b9 100644 --- a/module-server/src/main/kotlin/de/twomartens/timetable/timetable/TimetableController.kt +++ b/module-server/src/main/kotlin/de/twomartens/timetable/timetable/TimetableController.kt @@ -181,7 +181,8 @@ class TimetableController( HttpStatus.BAD_REQUEST, "Route name must belong to existing route" ) - scheduledTaskService.triggerTimetableFetch(route, timetable.fetchDate) + scheduledTaskService.triggerTimetableFetch(route, timetable.timetableId, + timetable.fetchDate) } else { timetable.name = NonEmptyString(body.name) }