diff --git a/apps/coordinator/src/main/kotlin/no/iktdev/mediaprocessing/coordinator/services/SequenceAggregatorService.kt b/apps/coordinator/src/main/kotlin/no/iktdev/mediaprocessing/coordinator/services/SequenceAggregatorService.kt index 34568bc5..89e03cdb 100644 --- a/apps/coordinator/src/main/kotlin/no/iktdev/mediaprocessing/coordinator/services/SequenceAggregatorService.kt +++ b/apps/coordinator/src/main/kotlin/no/iktdev/mediaprocessing/coordinator/services/SequenceAggregatorService.kt @@ -2,18 +2,18 @@ package no.iktdev.mediaprocessing.coordinator.services import no.iktdev.eventi.ZDS.toEvent import no.iktdev.eventi.models.store.PersistedEvent -import no.iktdev.mediaprocessing.shared.common.LocalDateTimeEpoch import no.iktdev.mediaprocessing.shared.common.dto.SequenceSummary import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.CollectedEvent import no.iktdev.mediaprocessing.shared.common.projection.CollectProjection import no.iktdev.mediaprocessing.shared.database.stores.EventStore import org.springframework.stereotype.Service +import java.time.Instant @Service class SequenceAggregatorService() { fun getActiveSequences(): List { - val allEvents = EventStore.getPersistedEventsAfter(LocalDateTimeEpoch) + val allEvents = EventStore.getPersistedEventsAfter(Instant.EPOCH) // Gruppér først, deserialiser senere val grouped = allEvents.groupBy { it.referenceId } @@ -26,7 +26,7 @@ class SequenceAggregatorService() { } fun getRecentSequences(limit: Int): List { - val allEvents = EventStore.getPersistedEventsAfter(LocalDateTimeEpoch) + val allEvents = EventStore.getPersistedEventsAfter(Instant.EPOCH) val grouped = allEvents.groupBy { it.referenceId } diff --git a/apps/py-metadata/utils/time.py b/apps/py-metadata/utils/time.py index 0081fa6c..b4c1db66 100644 --- a/apps/py-metadata/utils/time.py +++ b/apps/py-metadata/utils/time.py @@ -2,9 +2,8 @@ from datetime import datetime, timezone def utc_now(): """ - Returnerer en UTC-basert LocalDateTime uten Z eller offset, - med nanosekund-lignende presisjon (mikrosekunder + padding). + Matcher nøyaktig formatet Kotlin/Exposed skriver til databasen: + yyyy-MM-dd HH:mm:ss.SSSSSS (UTC) """ - dt = datetime.now(timezone.utc).replace(tzinfo=None) - return dt.strftime("%Y-%m-%dT%H:%M:%S.") + f"{dt.microsecond:06d}000" - + dt = datetime.now(timezone.utc) + return dt.strftime("%Y-%m-%d %H:%M:%S.%f") diff --git a/apps/py-watcher/utils/time.py b/apps/py-watcher/utils/time.py index 0081fa6c..b4c1db66 100644 --- a/apps/py-watcher/utils/time.py +++ b/apps/py-watcher/utils/time.py @@ -2,9 +2,8 @@ from datetime import datetime, timezone def utc_now(): """ - Returnerer en UTC-basert LocalDateTime uten Z eller offset, - med nanosekund-lignende presisjon (mikrosekunder + padding). + Matcher nøyaktig formatet Kotlin/Exposed skriver til databasen: + yyyy-MM-dd HH:mm:ss.SSSSSS (UTC) """ - dt = datetime.now(timezone.utc).replace(tzinfo=None) - return dt.strftime("%Y-%m-%dT%H:%M:%S.") + f"{dt.microsecond:06d}000" - + dt = datetime.now(timezone.utc) + return dt.strftime("%Y-%m-%d %H:%M:%S.%f") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3e026bf0..427b30b4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -eventi = "1.0-rc29" +eventi = "1.0-rc30" exfl = "1.0-rc1" [libraries] diff --git a/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/Utils.kt b/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/Utils.kt index b3e70086..b0da6f8a 100644 --- a/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/Utils.kt +++ b/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/Utils.kt @@ -10,8 +10,7 @@ import java.io.FileInputStream import java.io.RandomAccessFile import java.net.InetAddress import java.security.MessageDigest -import java.time.Clock -import java.time.LocalDateTime +import java.time.Instant import java.util.zip.CRC32 private val logger = KotlinLogging.logger {} @@ -217,9 +216,4 @@ fun File.resolveConflict(): File { return candidate } -val LocalDateTimeEpoch: LocalDateTime = - LocalDateTime.of(1970, 1, 1, 0, 0, 0) - -fun UtcNow(): LocalDateTime { - return LocalDateTime.now(Clock.systemUTC()) -} \ No newline at end of file +fun UtcNow(): Instant = Instant.now() \ No newline at end of file diff --git a/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/dto/FileTableItem.kt b/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/dto/FileTableItem.kt index a8300d4b..e6d06db2 100644 --- a/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/dto/FileTableItem.kt +++ b/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/dto/FileTableItem.kt @@ -1,10 +1,10 @@ package no.iktdev.mediaprocessing.shared.common.dto -import java.time.LocalDateTime +import java.time.Instant data class FileTableItem( val name: String, val uri: String, val checksum: String, - val identifiedAt: LocalDateTime, + val identifiedAt: Instant, ) \ No newline at end of file diff --git a/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/dto/SequenceEvent.kt b/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/dto/SequenceEvent.kt index 27addd3d..ef691769 100644 --- a/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/dto/SequenceEvent.kt +++ b/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/dto/SequenceEvent.kt @@ -2,7 +2,7 @@ package no.iktdev.mediaprocessing.shared.common.dto import no.iktdev.eventi.models.Event import no.iktdev.eventi.models.store.PersistedEvent -import java.time.LocalDateTime +import java.time.Instant import java.util.* import kotlin.reflect.KProperty1 @@ -10,14 +10,14 @@ data class SequenceEvent( val eventId: UUID, val referenceId: UUID, val type: String, - val timestamp: LocalDateTime, + val timestamp: Instant, val metadata: MetadataDto, val payload: Map? ) data class MetadataDto( val derivedFromEventIds: Set?, - val createdAt: LocalDateTime + val createdAt: Instant ) fun Event.extractPayload(): Map? { diff --git a/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/dto/SequenceSummary.kt b/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/dto/SequenceSummary.kt index 9e93a142..01d7366d 100644 --- a/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/dto/SequenceSummary.kt +++ b/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/dto/SequenceSummary.kt @@ -1,7 +1,7 @@ package no.iktdev.mediaprocessing.shared.common.dto import no.iktdev.mediaprocessing.shared.common.projection.CollectProjection -import java.time.LocalDateTime +import java.time.Instant data class SequenceSummary( val referenceId: String, @@ -9,7 +9,7 @@ data class SequenceSummary( val inputFileName: String?, val type: ContextType = ContextType.Content, val lastEventId: String, - val lastEventTime: LocalDateTime, + val lastEventTime: Instant, val metadataTaskStatus: CollectProjection.TaskStatus, val encodeTaskStatus: CollectProjection.TaskStatus, val extractTaskStatus: CollectProjection.TaskStatus, diff --git a/shared/database/src/main/kotlin/no/iktdev/mediaprocessing/shared/database/stores/EventStore.kt b/shared/database/src/main/kotlin/no/iktdev/mediaprocessing/shared/database/stores/EventStore.kt index 398b819e..88cbf3c4 100644 --- a/shared/database/src/main/kotlin/no/iktdev/mediaprocessing/shared/database/stores/EventStore.kt +++ b/shared/database/src/main/kotlin/no/iktdev/mediaprocessing/shared/database/stores/EventStore.kt @@ -9,11 +9,11 @@ import no.iktdev.mediaprocessing.shared.database.tables.EventsTable import no.iktdev.mediaprocessing.shared.database.withTransaction import org.jetbrains.exposed.sql.insert import org.jetbrains.exposed.sql.selectAll -import java.time.LocalDateTime +import java.time.Instant import java.util.* object EventStore: EventStore { - override fun getPersistedEventsAfter(timestamp: LocalDateTime): List { + override fun getPersistedEventsAfter(timestamp: Instant): List { val result = withTransaction { EventsTable.selectAll() .where { EventsTable.persistedAt greater timestamp } diff --git a/shared/database/src/main/kotlin/no/iktdev/mediaprocessing/shared/database/tables/EventsTable.kt b/shared/database/src/main/kotlin/no/iktdev/mediaprocessing/shared/database/tables/EventsTable.kt index 8d28fe48..aa7bfa3d 100644 --- a/shared/database/src/main/kotlin/no/iktdev/mediaprocessing/shared/database/tables/EventsTable.kt +++ b/shared/database/src/main/kotlin/no/iktdev/mediaprocessing/shared/database/tables/EventsTable.kt @@ -1,17 +1,18 @@ package no.iktdev.mediaprocessing.shared.database.tables +import no.iktdev.mediaprocessing.shared.common.UtcNow import org.jetbrains.exposed.dao.id.IntIdTable import org.jetbrains.exposed.sql.Column -import org.jetbrains.exposed.sql.javatime.CurrentDateTime -import org.jetbrains.exposed.sql.javatime.datetime -import java.time.LocalDateTime +import org.jetbrains.exposed.sql.javatime.timestamp object EventsTable: IntIdTable(name = "EVENTS") { val referenceId: Column = varchar("REFERENCE_ID", 36) val eventId: Column = varchar("EVENT_ID", 36) val event: Column = varchar("EVENT",100) val data: Column = text("DATA") - val persistedAt: Column = datetime("PERSISTED_AT").defaultExpression(CurrentDateTime) + val persistedAt = timestamp("PERSISTED_AT") + .clientDefault { UtcNow() } + init { uniqueIndex(referenceId, eventId, event) diff --git a/shared/database/src/main/kotlin/no/iktdev/mediaprocessing/shared/database/tables/FilesTable.kt b/shared/database/src/main/kotlin/no/iktdev/mediaprocessing/shared/database/tables/FilesTable.kt index d1ff5dc3..5ff5836a 100644 --- a/shared/database/src/main/kotlin/no/iktdev/mediaprocessing/shared/database/tables/FilesTable.kt +++ b/shared/database/src/main/kotlin/no/iktdev/mediaprocessing/shared/database/tables/FilesTable.kt @@ -2,12 +2,12 @@ package no.iktdev.mediaprocessing.shared.database.tables import org.jetbrains.exposed.dao.id.IntIdTable import org.jetbrains.exposed.sql.Column -import org.jetbrains.exposed.sql.javatime.datetime -import java.time.LocalDateTime +import org.jetbrains.exposed.sql.javatime.timestamp +import java.time.Instant object FilesTable: IntIdTable("FILES") { val name: Column = varchar("NAME", 255) val uri: Column = text("URI") val checksum: Column = char("CHECKSUM", 64) - val identifiedAt: Column = datetime("IDENTIFIED_AT") + val identifiedAt: Column = timestamp("IDENTIFIED_AT") } \ No newline at end of file diff --git a/shared/database/src/main/kotlin/no/iktdev/mediaprocessing/shared/database/tables/TasksTable.kt b/shared/database/src/main/kotlin/no/iktdev/mediaprocessing/shared/database/tables/TasksTable.kt index bd5bcf39..5e2463e7 100644 --- a/shared/database/src/main/kotlin/no/iktdev/mediaprocessing/shared/database/tables/TasksTable.kt +++ b/shared/database/src/main/kotlin/no/iktdev/mediaprocessing/shared/database/tables/TasksTable.kt @@ -1,11 +1,11 @@ package no.iktdev.mediaprocessing.shared.database.tables import no.iktdev.eventi.models.store.TaskStatus +import no.iktdev.mediaprocessing.shared.common.UtcNow import org.jetbrains.exposed.dao.id.IntIdTable import org.jetbrains.exposed.sql.Column -import org.jetbrains.exposed.sql.javatime.CurrentDateTime -import org.jetbrains.exposed.sql.javatime.datetime -import java.time.LocalDateTime +import org.jetbrains.exposed.sql.javatime.timestamp +import java.time.Instant object TasksTable: IntIdTable(name = "TASKS") { val referenceId: Column = varchar("REFERENCE_ID", 36) @@ -16,6 +16,7 @@ object TasksTable: IntIdTable(name = "TASKS") { val claimed: Column = bool("CLAIMED").default(false) val claimedBy: Column = varchar("CLAIMED_BY",100).nullable() val consumed: Column = bool("CONSUMED").default(false) - val lastCheckIn: Column = datetime("LAST_CHECK_IN").nullable() - val persistedAt: Column = datetime("PERSISTED_AT").defaultExpression(CurrentDateTime) + val lastCheckIn: Column = timestamp("LAST_CHECK_IN").nullable() + val persistedAt = timestamp("PERSISTED_AT") + .clientDefault { UtcNow() } } \ No newline at end of file diff --git a/shared/ffmpeg/src/main/kotlin/no/iktdev/mediaprocessing/ffmpeg/FFmpeg.kt b/shared/ffmpeg/src/main/kotlin/no/iktdev/mediaprocessing/ffmpeg/FFmpeg.kt index 1e4cf130..087705b9 100644 --- a/shared/ffmpeg/src/main/kotlin/no/iktdev/mediaprocessing/ffmpeg/FFmpeg.kt +++ b/shared/ffmpeg/src/main/kotlin/no/iktdev/mediaprocessing/ffmpeg/FFmpeg.kt @@ -10,6 +10,7 @@ import no.iktdev.mediaprocessing.ffmpeg.decoder.FfmpegProgressDecoder import no.iktdev.mediaprocessing.ffmpeg.util.UtcNow import java.io.File import java.io.FileOutputStream +import java.time.ZoneId import java.time.format.DateTimeFormatter open class FFmpeg(val executable: String, val logDir: File) { @@ -20,9 +21,12 @@ open class FFmpeg(val executable: String, val logDir: File) { private val outputCache = mutableListOf() //region Log File formatting - val currentDateTime = UtcNow() + val currentDateTime = UtcNow() // Instant, alltid UTC val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd.HH.mm") - val formattedDateTime = currentDateTime.format(formatter) + val formattedDateTime = currentDateTime + .atZone(ZoneId.systemDefault()) + .format(formatter) + //endregion lateinit var logFile: File diff --git a/shared/ffmpeg/src/main/kotlin/no/iktdev/mediaprocessing/ffmpeg/util/Utils.kt b/shared/ffmpeg/src/main/kotlin/no/iktdev/mediaprocessing/ffmpeg/util/Utils.kt index 0edb26de..441d3d16 100644 --- a/shared/ffmpeg/src/main/kotlin/no/iktdev/mediaprocessing/ffmpeg/util/Utils.kt +++ b/shared/ffmpeg/src/main/kotlin/no/iktdev/mediaprocessing/ffmpeg/util/Utils.kt @@ -1,8 +1,5 @@ package no.iktdev.mediaprocessing.ffmpeg.util -import java.time.Clock -import java.time.LocalDateTime +import java.time.Instant -fun UtcNow(): LocalDateTime { - return LocalDateTime.now(Clock.systemUTC()) -} \ No newline at end of file +fun UtcNow(): Instant = Instant.now()