diff --git a/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/contract/EventToClazzTable.kt b/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/contract/EventToClazzTable.kt deleted file mode 100644 index 4650cd0c..00000000 --- a/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/contract/EventToClazzTable.kt +++ /dev/null @@ -1,33 +0,0 @@ -package no.iktdev.mediaprocessing.shared.common.contract - -import com.google.gson.reflect.TypeToken -import mu.KotlinLogging -import no.iktdev.eventi.core.WGson -import no.iktdev.mediaprocessing.shared.common.contract.data.* - -private val log = KotlinLogging.logger {} - -fun String.fromJsonWithDeserializer(event: Events): Event { - val clazz = event.dataClass - clazz?.let { eventClass -> - try { - val type = TypeToken.getParameterized(eventClass).type - return WGson.gson.fromJson(this, type) - } catch (e: Exception) { - e.printStackTrace() - } - } - try { - // Fallback - val type = object : TypeToken() {}.type - return WGson.gson.fromJson(this, type) - } catch (e: Exception) { - e.printStackTrace() - } - - // Default - val type = object : TypeToken() {}.type - log.error { "Failed to convert event: $event and data: $this to proper type!" } - return WGson.gson.fromJson(this, type) - -} \ No newline at end of file diff --git a/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/contract/Events.kt b/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/contract/Events.kt index 16f3e42f..c221b320 100644 --- a/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/contract/Events.kt +++ b/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/contract/Events.kt @@ -1,55 +1,94 @@ package no.iktdev.mediaprocessing.shared.common.contract +import com.google.gson.reflect.TypeToken +import mu.KotlinLogging +import no.iktdev.eventi.core.WGson import no.iktdev.mediaprocessing.shared.common.contract.data.* -enum class Events(val event: String, val dataClass: Class) { - ProcessStarted ("event:media-process:started", dataClass = MediaProcessStartEvent::class.java), +private val log = KotlinLogging.logger {} - ReadStreamPerformed ("event:media-read-stream:performed", MediaFileStreamsReadEvent::class.java), - ParseStreamPerformed ("event:media-parse-stream:performed", MediaFileStreamsParsedEvent::class.java), - ReadBaseInfoPerformed ("event:media-read-base-info:performed", BaseInfoEvent::class.java), - MetadataSearchPerformed ("event:media-metadata-search:performed", MediaMetadataReceivedEvent::class.java), - ReadOutNameAndType ("event:media-read-out-name-and-type:performed", MediaOutInformationConstructedEvent::class.java), - ReadOutCover ("event:media-read-out-cover:performed", MediaCoverInfoReceivedEvent::class.java), - ParameterEncodeCreated ("event:media-encode-parameter:created", EncodeArgumentCreatedEvent::class.java), - ParameterExtractCreated ("event:media-extract-parameter:created", ExtractArgumentCreatedEvent::class.java), +enum class Events(val event: String) { + ProcessStarted ("event:media-process:started"), - //EventMediaParameterDownloadCoverCreated ("event:media-download-cover-parameter:created"), - - WorkProceedPermitted ("event:media-work-proceed:permitted", PermitWorkCreationEvent::class.java), - - //EventNotificationOfWorkItemRemoval("event:notification-work-item-removal"), - - WorkEncodeCreated ("event:work-encode:created", EncodeWorkCreatedEvent::class.java), - WorkExtractCreated ("event:work-extract:created", ExtractWorkCreatedEvent::class.java), - WorkConvertCreated ("event:work-convert:created", ConvertWorkCreatedEvent::class.java), - - WorkEncodePerformed ("event:work-encode:performed", EncodeWorkPerformedEvent::class.java), - WorkExtractPerformed ("event:work-extract:performed", ExtractWorkPerformedEvent::class.java), - WorkConvertPerformed ("event:work-convert:performed", ConvertWorkPerformed::class.java), - WorkDownloadCoverPerformed ("event:work-download-cover:performed", MediaCoverDownloadedEvent::class.java), - - PersistContentPerformed ("event:media-persist:completed", PersistedContentEvent::class.java), - ProcessCompleted ("event:media-process:completed", MediaProcessCompletedEvent::class.java), + ReadStreamPerformed ("event:media-read-stream:performed", ), + ParseStreamPerformed ("event:media-parse-stream:performed", ), + ReadBaseInfoPerformed ("event:media-read-base-info:performed", ), + MetadataSearchPerformed ("event:media-metadata-search:performed", ), + ReadOutNameAndType ("event:media-read-out-name-and-type:performed", ), + ReadOutCover ("event:media-read-out-cover:performed", ), + ParameterEncodeCreated ("event:media-encode-parameter:created", ), + ParameterExtractCreated ("event:media-extract-parameter:created", ), + WorkProceedPermitted ("event:media-work-proceed:permitted", ), + WorkEncodeCreated ("event:work-encode:created", ), + WorkExtractCreated ("event:work-extract:created", ), + WorkConvertCreated ("event:work-convert:created", ), + WorkEncodePerformed ("event:work-encode:performed", ), + WorkExtractPerformed ("event:work-extract:performed", ), + WorkConvertPerformed ("event:work-convert:performed", ), + WorkDownloadCoverPerformed ("event:work-download-cover:performed", ), + PersistContentPerformed ("event:media-persist:completed", ), + ProcessCompleted ("event:media-process:completed", ), ; companion object { fun toEvent(event: String): Events? { return Events.entries.find { it.event == event } } + } +} - fun isOfWork(event: Events): Boolean { - return event in listOf( +fun Events.toEventClass(): Class { + return when(this) { + Events.ProcessStarted -> MediaProcessStartEvent::class.java - WorkConvertCreated, - WorkExtractCreated, - WorkEncodeCreated, + Events.ReadStreamPerformed -> MediaFileStreamsReadEvent::class.java + Events.ParseStreamPerformed -> MediaFileStreamsParsedEvent::class.java + Events.ReadBaseInfoPerformed -> BaseInfoEvent::class.java + Events.MetadataSearchPerformed -> MediaMetadataReceivedEvent::class.java + Events.ReadOutNameAndType -> MediaOutInformationConstructedEvent::class.java + Events.ReadOutCover -> MediaCoverInfoReceivedEvent::class.java - WorkEncodePerformed, - WorkConvertPerformed, - WorkExtractPerformed - ) + Events.ParameterEncodeCreated -> EncodeArgumentCreatedEvent::class.java + Events.ParameterExtractCreated -> ExtractArgumentCreatedEvent::class.java + + Events.WorkProceedPermitted -> PermitWorkCreationEvent::class.java + + Events.WorkEncodeCreated -> EncodeWorkCreatedEvent::class.java + Events.WorkExtractCreated -> ExtractWorkCreatedEvent::class.java + Events.WorkConvertCreated -> ConvertWorkCreatedEvent::class.java + + Events.WorkEncodePerformed -> EncodeWorkPerformedEvent::class.java + Events.WorkExtractPerformed -> ExtractWorkPerformedEvent::class.java + Events.WorkConvertPerformed -> ConvertWorkPerformed::class.java + Events.WorkDownloadCoverPerformed -> MediaCoverDownloadedEvent::class.java + + Events.PersistContentPerformed -> PersistedContentEvent::class.java + Events.ProcessCompleted -> MediaProcessCompletedEvent::class.java + else -> Event::class.java + } +} + +fun String.jsonToEvent(eventType: String): Event { + val clazz = Events.toEvent(eventType)?.toEventClass() + clazz.let { eventClass -> + try { + val type = TypeToken.getParameterized(eventClass).type + return WGson.gson.fromJson(this, type) + } catch (e: Exception) { + e.printStackTrace() } } + try { + // Fallback + val type = object : TypeToken() {}.type + return WGson.gson.fromJson(this, type) + } catch (e: Exception) { + e.printStackTrace() + } + + // Default + val type = object : TypeToken() {}.type + log.error { "Failed to convert event: $eventType and data: $this to proper type!" } + return WGson.gson.fromJson(this, type) } \ No newline at end of file diff --git a/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/contract/EventsUtil.kt b/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/contract/EventsUtil.kt index b6ef0267..e227de34 100644 --- a/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/contract/EventsUtil.kt +++ b/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/contract/EventsUtil.kt @@ -1,7 +1,12 @@ package no.iktdev.mediaprocessing.shared.common.contract +import mu.KotlinLogging import no.iktdev.eventi.data.EventImpl import no.iktdev.eventi.data.isSuccessful +import no.iktdev.mediaprocessing.shared.common.contract.data.Event + +private val log = KotlinLogging.logger {} + fun List.lastOrSuccess(): EventImpl? { return this.lastOrNull { it.isSuccessful() } ?: this.lastOrNull() @@ -15,4 +20,5 @@ fun List.lastOrSuccessOf(event: no.iktdev.mediaprocessing.shared.comm fun List.lastOrSuccessOf(event: no.iktdev.mediaprocessing.shared.common.contract.Events, predicate: (EventImpl) -> Boolean): EventImpl? { val validEvents = this.filter { it.eventType == event && predicate(it) } return validEvents.lastOrNull() -} \ No newline at end of file +} + diff --git a/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/database/cal/EventsManager.kt b/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/database/cal/EventsManager.kt index 84913bfc..afb7b6c2 100644 --- a/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/database/cal/EventsManager.kt +++ b/shared/common/src/main/kotlin/no/iktdev/mediaprocessing/shared/common/database/cal/EventsManager.kt @@ -14,7 +14,7 @@ import no.iktdev.mediaprocessing.shared.common.database.tables.events import no.iktdev.mediaprocessing.shared.common.contract.Events import no.iktdev.mediaprocessing.shared.common.contract.EventsManagerContract import no.iktdev.mediaprocessing.shared.common.contract.data.Event -import no.iktdev.mediaprocessing.shared.common.contract.fromJsonWithDeserializer +import no.iktdev.mediaprocessing.shared.common.contract.jsonToEvent import org.jetbrains.exposed.exceptions.ExposedSQLException import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq @@ -180,14 +180,8 @@ class EventsManager(dataSource: DataSource) : EventsManagerContract(dataSource) } - private fun ResultRow.toEvent(): Event? { - val kev = try { - Events.toEvent(this[events.event]) - } catch (e: IllegalArgumentException) { - e.printStackTrace() - return null - }?: return null - return this[events.data].fromJsonWithDeserializer(kev) + private fun ResultRow.toEvent(): Event { + return this[events.data].jsonToEvent(this[events.event]) } } diff --git a/shared/common/src/test/kotlin/no/iktdev/mediaprocessing/shared/common/DatabaseDeserializerTest.kt b/shared/common/src/test/kotlin/no/iktdev/mediaprocessing/shared/common/DatabaseDeserializerTest.kt new file mode 100644 index 00000000..7f022c41 --- /dev/null +++ b/shared/common/src/test/kotlin/no/iktdev/mediaprocessing/shared/common/DatabaseDeserializerTest.kt @@ -0,0 +1,20 @@ +package no.iktdev.mediaprocessing.shared.common + +import no.iktdev.mediaprocessing.shared.common.contract.Events +import no.iktdev.mediaprocessing.shared.common.contract.data.StartEventData +import no.iktdev.mediaprocessing.shared.common.contract.jsonToEvent +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +class DatabaseDeserializerTest { + + @Test + fun validateParsingOfStartEvent() { + //language=json + val data = """{"metadata":{"eventId":"45e92856-37a6-4266-81cd-a8cf16dd7eb2","referenceId":"a42bf0a4-d31d-4715-8e4d-1432d52f9786","status":"Success","created":"2025-02-10T21:35:52.437791666","source":"Coordinator"},"data":{"type":"FLOW","operations":["ENCODE","EXTRACT","CONVERT"],"file":"/potato"},"eventType":"EventMediaProcessStarted"}""" + val result = data.jsonToEvent("event:media-process:started") + assertThat(result.data!!.javaClass).hasSameClassAs(StartEventData::class.java) + } + + +} \ No newline at end of file