Migrated database stuff to seperate module

This commit is contained in:
Brage Skjønborg 2026-01-16 20:18:29 +01:00
parent 3925fb758b
commit 2bcdc38f09
56 changed files with 269 additions and 139 deletions

View File

@ -49,12 +49,14 @@ dependencies {
implementation("com.github.pgreze:kotlin-process:1.4.1")
implementation(project(mapOf("path" to ":shared:common")))
implementation(project(mapOf("path" to ":shared:database")))
implementation(kotlin("stdlib-jdk8"))
testImplementation("io.mockk:mockk:1.12.0")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation(project(":shared:common", configuration = "testArtifacts"))
testImplementation(project(":shared:database", configuration = "testArtifacts"))
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.10.2")
val exposedVersion = "0.61.0"

View File

@ -6,15 +6,15 @@ import no.iktdev.eventi.tasks.TaskTypeRegistry
import no.iktdev.exfl.coroutines.CoroutinesDefault
import no.iktdev.exfl.coroutines.CoroutinesIO
import no.iktdev.exfl.observable.Observables
import no.iktdev.mediaprocessing.shared.common.DatabaseApplication
import no.iktdev.mediaprocessing.shared.common.MediaProcessingApp
import no.iktdev.mediaprocessing.shared.common.event_task_contract.EventRegistry
import no.iktdev.mediaprocessing.shared.common.event_task_contract.TaskRegistry
import no.iktdev.mediaprocessing.shared.common.getAppVersion
import no.iktdev.mediaprocessing.shared.database.DatabaseApplication
import no.iktdev.mediaprocessing.shared.database.DatabasebasedMediaProcessingApp
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Configuration
@MediaProcessingApp
@DatabasebasedMediaProcessingApp
open class ConverterApplication: DatabaseApplication() {
}

View File

@ -7,11 +7,11 @@ import no.iktdev.eventi.models.Event
import no.iktdev.eventi.models.store.TaskStatus
import no.iktdev.eventi.tasks.TaskPollerImplementation
import no.iktdev.eventi.tasks.TaskReporter
import no.iktdev.mediaprocessing.shared.common.stores.EventStore
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.EventStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.springframework.boot.ApplicationArguments
import org.springframework.boot.ApplicationRunner
import org.springframework.context.annotation.Bean
import org.springframework.stereotype.Component
import org.springframework.stereotype.Service
import java.util.UUID

View File

@ -6,8 +6,9 @@ import io.mockk.mockkObject
import io.mockk.verify
import no.iktdev.eventi.models.Task
import no.iktdev.mediaprocessing.shared.common.TestBase
import no.iktdev.mediaprocessing.shared.common.config.DatasourceConfiguration
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.config.DatasourceConfiguration
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.jetbrains.exposed.sql.Database
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.Test

View File

@ -48,6 +48,7 @@ dependencies {
implementation(project(mapOf("path" to ":shared:ffmpeg")))
implementation(project(mapOf("path" to ":shared:common")))
implementation(project(mapOf("path" to ":shared:database")))
@ -81,6 +82,7 @@ dependencies {
testImplementation("org.mockito.kotlin:mockito-kotlin:5.2.1")
testImplementation("org.mockito:mockito-junit-jupiter:5.11.0")
testImplementation(project(":shared:common", configuration = "testArtifacts"))
testImplementation(project(":shared:database", configuration = "testArtifacts"))
testImplementation("org.springframework.boot:spring-boot-starter-test")
val exposedVersion = "0.61.0"
testImplementation("org.jetbrains.exposed:exposed-core:${exposedVersion}")

View File

@ -7,16 +7,16 @@ import no.iktdev.exfl.coroutines.CoroutinesDefault
import no.iktdev.exfl.coroutines.CoroutinesIO
import no.iktdev.exfl.observable.Observables
import no.iktdev.mediaprocessing.coordinator.config.ExecutablesConfig
import no.iktdev.mediaprocessing.shared.common.DatabaseApplication
import no.iktdev.mediaprocessing.shared.common.MediaProcessingApp
import no.iktdev.mediaprocessing.shared.common.event_task_contract.EventRegistry
import no.iktdev.mediaprocessing.shared.common.event_task_contract.TaskRegistry
import no.iktdev.mediaprocessing.shared.common.getAppVersion
import no.iktdev.mediaprocessing.shared.database.DatabaseApplication
import no.iktdev.mediaprocessing.shared.database.DatabasebasedMediaProcessingApp
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Configuration
@MediaProcessingApp
@DatabasebasedMediaProcessingApp
class CoordinatorApplication: DatabaseApplication() {
}

View File

@ -7,7 +7,7 @@ import kotlinx.coroutines.launch
import no.iktdev.eventi.events.EventDispatcher
import no.iktdev.eventi.events.EventPollerImplementation
import no.iktdev.eventi.events.SequenceDispatchQueue
import no.iktdev.mediaprocessing.shared.common.stores.EventStore
import no.iktdev.mediaprocessing.shared.database.stores.EventStore
import org.springframework.context.SmartLifecycle
import org.springframework.context.annotation.DependsOn
import org.springframework.stereotype.Component

View File

@ -1,7 +1,7 @@
package no.iktdev.mediaprocessing.coordinator.controller
import no.iktdev.mediaprocessing.shared.common.database.queries.FilesTableQueries
import no.iktdev.mediaprocessing.shared.common.dto.FileTableItem
import no.iktdev.mediaprocessing.shared.database.queries.FilesTableQueries
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping

View File

@ -9,7 +9,7 @@ import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.Operat
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.ProcesserExtractResultEvent
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.StartProcessingEvent
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.ConvertTask
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.springframework.stereotype.Component
import java.io.File
import java.nio.file.Files

View File

@ -7,7 +7,8 @@ import no.iktdev.eventi.models.store.TaskStatus
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.CoverDownloadTaskCreatedEvent
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.MetadataSearchResultEvent
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.CoverDownloadTask
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.springframework.stereotype.Component
@Component

View File

@ -7,7 +7,8 @@ import no.iktdev.mediaprocessing.ffmpeg.dsl.*
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.*
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.EncodeData
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.EncodeTask
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.springframework.stereotype.Component
import java.io.File

View File

@ -11,7 +11,8 @@ import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.Proces
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.StartProcessingEvent
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.ExtractSubtitleData
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.ExtractSubtitleTask
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.springframework.stereotype.Component
import java.io.File
import java.util.UUID

View File

@ -8,7 +8,8 @@ import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.MediaP
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.MetadataSearchResultEvent
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.MetadataSearchTaskCreatedEvent
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.MetadataSearchTask
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.jetbrains.annotations.VisibleForTesting
import org.springframework.stereotype.Component
import java.util.*

View File

@ -7,7 +7,8 @@ import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.Coordi
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.MediaParsedInfoEvent
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.StartProcessingEvent
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.MediaReadTask
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.springframework.stereotype.Component
@ListenerOrder(3)

View File

@ -9,7 +9,8 @@ import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.Migrat
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.MigrateToContentStoreTask
import no.iktdev.mediaprocessing.shared.common.projection.CollectProjection
import no.iktdev.mediaprocessing.shared.common.projection.MigrateContentProject
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.springframework.stereotype.Component
@Component

View File

@ -9,7 +9,8 @@ import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.StoreC
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.StoreContentAndMetadataTask
import no.iktdev.mediaprocessing.shared.common.model.ContentExport
import no.iktdev.mediaprocessing.shared.common.projection.StoreProjection
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.springframework.stereotype.Component
@Component

View File

@ -5,7 +5,7 @@ import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.StartD
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.StartFlow
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.StartProcessingEvent
import no.iktdev.mediaprocessing.shared.common.notExist
import no.iktdev.mediaprocessing.shared.common.stores.EventStore
import no.iktdev.mediaprocessing.shared.database.stores.EventStore
import org.springframework.stereotype.Service
import java.io.File
import java.util.*

View File

@ -3,7 +3,7 @@ package no.iktdev.mediaprocessing.coordinator.services
import no.iktdev.eventi.ZDS.toEvent
import no.iktdev.mediaprocessing.shared.common.dto.SequenceEvent
import no.iktdev.mediaprocessing.shared.common.dto.toDto
import no.iktdev.mediaprocessing.shared.common.stores.EventStore
import no.iktdev.mediaprocessing.shared.database.stores.EventStore
import org.springframework.stereotype.Service
import java.util.*

View File

@ -6,7 +6,7 @@ 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.common.stores.EventStore
import no.iktdev.mediaprocessing.shared.database.stores.EventStore
import org.springframework.stereotype.Service
@Service

View File

@ -5,7 +5,7 @@ import no.iktdev.eventi.ListenerOrder
import no.iktdev.eventi.events.EventListenerRegistry
import no.iktdev.mediaprocessing.coordinator.CoordinatorApplication
import no.iktdev.mediaprocessing.coordinator.listeners.events.*
import no.iktdev.mediaprocessing.shared.common.config.DatasourceConfiguration
import no.iktdev.mediaprocessing.shared.database.config.DatasourceConfiguration
import no.iktdev.mediaprocessing.shared.common.event_task_contract.EventRegistry
import no.iktdev.mediaprocessing.shared.common.event_task_contract.TaskRegistry
import org.assertj.core.api.Assertions.assertThat

View File

@ -9,7 +9,8 @@ import no.iktdev.mediaprocessing.ffmpeg.dsl.VideoCodec
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.OperationType
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.StartData
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.StartProcessingEvent
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.junit.jupiter.api.BeforeEach
import java.io.File
import java.util.*

View File

@ -9,7 +9,6 @@ import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.StartD
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.StartProcessingEvent
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import java.io.File
@ -17,10 +16,10 @@ import java.io.File
import io.mockk.*
import no.iktdev.eventi.models.Event
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.ConvertTask
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.mockito.Mockito.mockStatic
import org.mockito.kotlin.any
import org.mockito.kotlin.whenever
import java.nio.file.Files
import java.nio.file.Path

View File

@ -6,7 +6,8 @@ import no.iktdev.mediaprocessing.MockData.metadataEvent
import no.iktdev.mediaprocessing.TestBase
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.CoverDownloadTaskCreatedEvent
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.CoverDownloadTask
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test

View File

@ -10,7 +10,8 @@ import no.iktdev.mediaprocessing.ffmpeg.dsl.AudioCodec
import no.iktdev.mediaprocessing.ffmpeg.dsl.VideoCodec
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.*
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.EncodeTask
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.BeforeEach

View File

@ -20,7 +20,8 @@ import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.Proces
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.StartData
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.StartProcessingEvent
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.ExtractSubtitleTask
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.DisplayName

View File

@ -11,7 +11,8 @@ import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.Metada
import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.MetadataSearchTaskCreatedEvent
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.MetadataSearchTask
import no.iktdev.mediaprocessing.shared.common.model.MediaType
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test

View File

@ -15,7 +15,8 @@ import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.Migrat
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.MigrateToContentStoreTask
import no.iktdev.mediaprocessing.shared.common.model.MediaType
import no.iktdev.mediaprocessing.shared.common.model.MigrateStatus
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test

View File

@ -12,7 +12,8 @@ import no.iktdev.mediaprocessing.shared.common.event_task_contract.events.StoreC
import no.iktdev.mediaprocessing.shared.common.event_task_contract.tasks.StoreContentAndMetadataTask
import no.iktdev.mediaprocessing.shared.common.model.MediaType
import no.iktdev.mediaprocessing.shared.common.model.MigrateStatus
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test

View File

@ -47,6 +47,7 @@ dependencies {
//implementation(project(mapOf("path" to ":shared")))
implementation(project(mapOf("path" to ":shared:ffmpeg")))
implementation(project(mapOf("path" to ":shared:common")))
implementation(project(mapOf("path" to ":shared:database")))
implementation(kotlin("stdlib-jdk8"))
@ -73,6 +74,7 @@ dependencies {
// --- Hvis du trenger test artifacts fra shared:common ---
testImplementation(project(":shared:common", configuration = "testArtifacts"))
testImplementation(project(":shared:database", configuration = "testArtifacts"))
val exposedVersion = "0.61.0"
testImplementation("org.jetbrains.exposed:exposed-core:${exposedVersion}")

View File

@ -6,16 +6,16 @@ import no.iktdev.eventi.tasks.TaskTypeRegistry
import no.iktdev.exfl.coroutines.CoroutinesDefault
import no.iktdev.exfl.coroutines.CoroutinesIO
import no.iktdev.exfl.observable.Observables
import no.iktdev.mediaprocessing.shared.common.DatabaseApplication
import no.iktdev.mediaprocessing.shared.common.MediaProcessingApp
import no.iktdev.mediaprocessing.shared.common.event_task_contract.EventRegistry
import no.iktdev.mediaprocessing.shared.common.event_task_contract.TaskRegistry
import no.iktdev.mediaprocessing.shared.common.getAppVersion
import no.iktdev.mediaprocessing.shared.database.DatabaseApplication
import no.iktdev.mediaprocessing.shared.database.DatabasebasedMediaProcessingApp
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Configuration
@MediaProcessingApp
@DatabasebasedMediaProcessingApp
class ProcesserApplication: DatabaseApplication() {
}

View File

@ -7,8 +7,9 @@ import no.iktdev.eventi.models.Event
import no.iktdev.eventi.models.store.TaskStatus
import no.iktdev.eventi.tasks.TaskPollerImplementation
import no.iktdev.eventi.tasks.TaskReporter
import no.iktdev.mediaprocessing.shared.common.stores.EventStore
import no.iktdev.mediaprocessing.shared.common.stores.TaskStore
import no.iktdev.mediaprocessing.shared.database.stores.EventStore
import no.iktdev.mediaprocessing.shared.database.stores.TaskStore
import org.springframework.boot.ApplicationArguments
import org.springframework.boot.ApplicationRunner
import org.springframework.stereotype.Component

View File

@ -23,4 +23,6 @@ include("shared")
include("shared:common")
include("shared:ffmpeg")
include("shared:event-task-contract")
include("shared:event-task-contract")
include("shared:database")
include("shared:database")

View File

@ -23,13 +23,10 @@ repositories {
}
}
val exposedVersion = "0.61.0"
dependencies {
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.boot:spring-boot-starter-websocket")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("com.github.pgreze:kotlin-process:1.3.1")
@ -45,24 +42,9 @@ dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.5.0")
implementation("org.jetbrains.exposed:exposed-core:$exposedVersion")
implementation("org.jetbrains.exposed:exposed-dao:$exposedVersion")
implementation("org.jetbrains.exposed:exposed-jdbc:$exposedVersion")
implementation("org.jetbrains.exposed:exposed-java-time:$exposedVersion")
implementation ("mysql:mysql-connector-java:8.0.33")
implementation("org.postgresql:postgresql:42.7.7")
implementation("org.xerial:sqlite-jdbc:3.43.2.0")
implementation("org.apache.commons:commons-lang3:3.12.0")
implementation("com.zaxxer:HikariCP:7.0.2")
implementation(project(":shared:ffmpeg"))
implementation(libs.eventi)
@ -72,7 +54,6 @@ dependencies {
testImplementation("org.springframework.boot:spring-boot-starter-test")
implementation("com.h2database:h2:2.2.220")
testImplementation("org.assertj:assertj-core:3.24.2")
testImplementation("io.kotest:kotest-assertions-core:5.7.2")

View File

@ -1,44 +1,28 @@
package no.iktdev.mediaprocessing.shared.common
import mu.KotlinLogging
import no.iktdev.mediaprocessing.shared.common.configs.MediaPaths
import no.iktdev.mediaprocessing.shared.common.configs.StreamItConfig
import org.jetbrains.exposed.sql.Database
import org.springframework.beans.factory.InitializingBean
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.runApplication
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Import
import org.springframework.stereotype.Component
import javax.sql.DataSource
abstract class DatabaseApplication {
abstract class MediaProcessingApplication {
companion object {
inline fun <reified T : DatabaseApplication> launch(args: Array<String>) {
inline fun <reified T : MediaProcessingApplication> launch(args: Array<String>) {
runApplication<T>(*args)
}
}
}
@Component("ExposedInit")
class ExposedInitializer(
private val dataSource: DataSource
) : InitializingBean {
private val log = KotlinLogging.logger {}
override fun afterPropertiesSet() {
log.info { "Starting database connection" }
Database.connect(dataSource)
}
}
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@SpringBootApplication
@ComponentScan("no.iktdev.mediaprocessing") // sikrer at common beans blir plukket opp
@ComponentScan(
basePackages = ["no.iktdev.mediaprocessing.shared.common"]
) // sikrer at common beans blir plukket opp
@Import(SharedConfig::class)
annotation class MediaProcessingApp

View File

@ -1,15 +1,3 @@
spring:
flyway:
enabled: true
locations: classpath:flyway
baseline-on-migrate: false
datasource:
url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
driver-class-name: org.h2.Driver
username: sa
password:
media:
cache: /src/cache
outgoing: /src/output

View File

@ -1,6 +1,5 @@
package no.iktdev.mediaprocessing.shared.common
import no.iktdev.mediaprocessing.shared.common.config.DatasourceConfiguration
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.web.client.TestRestTemplate
@ -11,8 +10,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension
import java.net.URI
@SpringBootTest(
classes = [DatabaseApplication::class,
DatasourceConfiguration::class],
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
@ExtendWith(SpringExtension::class)

View File

@ -0,0 +1,104 @@
plugins {
id("java")
kotlin("jvm")
kotlin("plugin.spring")
id("org.jetbrains.kotlin.plugin.serialization")
id("org.springframework.boot")
id("io.spring.dependency-management")
}
group = "no.iktdev.mediaprocessing"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
maven("https://jitpack.io")
maven {
name = "ReposiliteReleases"
url = uri("https://reposilite.iktdev.no/releases")
}
maven {
name = "ReposiliteSnapshot"
url = uri("https://reposilite.iktdev.no/snapshots")
}
}
val exposedVersion = "0.61.0"
dependencies {
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.boot:spring-boot-starter-websocket")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("com.github.pgreze:kotlin-process:1.3.1")
implementation("io.github.microutils:kotlin-logging-jvm:2.0.11")
implementation(libs.exfl)
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1")
implementation("com.google.code.gson:gson:2.8.9")
implementation("org.json:json:20231013")
implementation("org.flywaydb:flyway-core")
implementation("org.flywaydb:flyway-mysql")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.5.0")
implementation("org.jetbrains.exposed:exposed-core:$exposedVersion")
implementation("org.jetbrains.exposed:exposed-dao:$exposedVersion")
implementation("org.jetbrains.exposed:exposed-jdbc:$exposedVersion")
implementation("org.jetbrains.exposed:exposed-java-time:$exposedVersion")
implementation ("mysql:mysql-connector-java:8.0.33")
implementation("org.postgresql:postgresql:42.7.7")
implementation("org.xerial:sqlite-jdbc:3.43.2.0")
implementation("org.apache.commons:commons-lang3:3.12.0")
implementation("com.zaxxer:HikariCP:7.0.2")
implementation(project(":shared:ffmpeg"))
implementation(project(":shared:common"))
implementation(libs.eventi)
testImplementation(kotlin("test"))
testImplementation(platform("org.junit:junit-bom:5.10.0"))
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation("org.springframework.boot:spring-boot-starter-test")
implementation("com.h2database:h2:2.2.220")
testImplementation("org.assertj:assertj-core:3.24.2")
testImplementation("io.kotest:kotest-assertions-core:5.7.2")
testImplementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.0")
testImplementation("io.github.classgraph:classgraph:4.8.184")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.10.2")
testImplementation("io.mockk:mockk:1.13.9")
testImplementation(project(":shared:common", configuration = "testArtifacts"))
}
kotlin {
jvmToolchain(21)
}
tasks.test {
useJUnitPlatform()
}
configurations { create("testArtifacts") }
tasks.register<Jar>("testJar") {
from(sourceSets.test.get().output)
archiveClassifier.set("tests")
}
artifacts {
add("testArtifacts", tasks.named("testJar"))
}

View File

@ -0,0 +1,40 @@
package no.iktdev.mediaprocessing.shared.database
import mu.KotlinLogging
import no.iktdev.mediaprocessing.shared.common.MediaProcessingApp
import no.iktdev.mediaprocessing.shared.common.MediaProcessingApplication
import org.jetbrains.exposed.sql.Database
import org.springframework.beans.factory.InitializingBean
import org.springframework.boot.runApplication
import org.springframework.context.annotation.ComponentScan
import org.springframework.stereotype.Component
import javax.sql.DataSource
abstract class DatabaseApplication: MediaProcessingApplication() {
companion object {
inline fun <reified T : DatabaseApplication> launch(args: Array<String>) {
runApplication<T>(*args)
}
}
}
@Component("ExposedInit")
class ExposedInitializer(
private val dataSource: DataSource
) : InitializingBean {
private val log = KotlinLogging.logger {}
override fun afterPropertiesSet() {
log.info { "Starting database connection" }
Database.connect(dataSource)
}
}
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MediaProcessingApp
@ComponentScan(
basePackages = ["no.iktdev.mediaprocessing.shared.database"]
)
annotation class DatabasebasedMediaProcessingApp

View File

@ -1,4 +1,4 @@
package no.iktdev.mediaprocessing.shared.common.database
package no.iktdev.mediaprocessing.shared.database
data class Access(
val username: String,

View File

@ -1,4 +1,4 @@
package no.iktdev.mediaprocessing.shared.common.database
package no.iktdev.mediaprocessing.shared.database
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
@ -13,11 +13,11 @@ import org.springframework.context.annotation.Configuration
import javax.sql.DataSource
@Configuration
open class DatabaseConfiguration {
class DatabaseConfiguration {
@Bean
fun dataSource(): DataSource {
val maxPoolSize: Int = 10
val maxPoolSize = 10
val access = DatabaseEnv.toAccess()
val jdbcUrl = when (access.dbType) {

View File

@ -1,4 +1,4 @@
package no.iktdev.mediaprocessing.shared.common.database
package no.iktdev.mediaprocessing.shared.database
object DatabaseEnv {
@ -27,4 +27,4 @@ object DatabaseEnv {
)
}
}
}

View File

@ -1,4 +1,4 @@
package no.iktdev.mediaprocessing.shared.common.database
package no.iktdev.mediaprocessing.shared.database
import org.jetbrains.exposed.sql.transactions.transaction
import org.springframework.boot.actuate.health.Health

View File

@ -1,4 +1,4 @@
package no.iktdev.mediaprocessing.shared.common.database
package no.iktdev.mediaprocessing.shared.database
enum class DatabaseTypes {
MySQL, PostgreSQL, SQLite, H2

View File

@ -1,4 +1,4 @@
package no.iktdev.mediaprocessing.shared.common.database
package no.iktdev.mediaprocessing.shared.database
import org.jetbrains.exposed.sql.transactions.transaction

View File

@ -1,8 +1,8 @@
package no.iktdev.mediaprocessing.shared.common.database.queries
package no.iktdev.mediaprocessing.shared.database.queries
import no.iktdev.mediaprocessing.shared.common.database.tables.FilesTable
import no.iktdev.mediaprocessing.shared.common.database.withTransaction
import no.iktdev.mediaprocessing.shared.common.dto.FileTableItem
import no.iktdev.mediaprocessing.shared.database.tables.FilesTable
import no.iktdev.mediaprocessing.shared.database.withTransaction
import org.jetbrains.exposed.sql.selectAll
class FilesTableQueries {

View File

@ -1,16 +1,15 @@
package no.iktdev.mediaprocessing.shared.common.stores
package no.iktdev.mediaprocessing.shared.database.stores
import com.google.gson.Gson
import no.iktdev.eventi.ZDS.toPersisted
import no.iktdev.eventi.models.Event
import no.iktdev.eventi.models.store.PersistedEvent
import no.iktdev.eventi.stores.EventStore
import no.iktdev.mediaprocessing.shared.common.database.tables.EventsTable
import no.iktdev.mediaprocessing.shared.common.database.withTransaction
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.util.UUID
import java.util.*
object EventStore: EventStore {
override fun getPersistedEventsAfter(timestamp: LocalDateTime): List<PersistedEvent> {

View File

@ -1,13 +1,12 @@
package no.iktdev.mediaprocessing.shared.common.stores
package no.iktdev.mediaprocessing.shared.database.stores
import com.google.gson.Gson
import no.iktdev.eventi.ZDS
import no.iktdev.eventi.models.Task
import no.iktdev.eventi.models.store.PersistedTask
import no.iktdev.eventi.models.store.TaskStatus
import no.iktdev.eventi.stores.TaskStore
import no.iktdev.mediaprocessing.shared.common.database.tables.TasksTable
import no.iktdev.mediaprocessing.shared.common.database.withTransaction
import no.iktdev.mediaprocessing.shared.database.tables.TasksTable
import no.iktdev.mediaprocessing.shared.database.withTransaction
import org.jetbrains.exposed.sql.and
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.selectAll

View File

@ -1,11 +1,11 @@
package no.iktdev.mediaprocessing.shared.common.database.tables
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.CurrentDateTime
import org.jetbrains.exposed.sql.javatime.datetime
import java.time.LocalDateTime
import java.util.UUID
import java.util.*
object EventsTable: IntIdTable(name = "EVENTS") {
val referenceId: Column<UUID> = uuid("REFERENCE_ID")

View File

@ -1,12 +1,13 @@
package no.iktdev.mediaprocessing.shared.common.database.tables
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
object FilesTable: IntIdTable("FILES") {
val name: Column<String> = varchar("NAME", 255)
val uri: Column<String> = text("URI")
val checksum: Column<String> = char("CHECKSUM", 64)
val identifiedAt: Column<java.time.LocalDateTime> = datetime("IDENTIFIED_AT")
val identifiedAt: Column<LocalDateTime> = datetime("IDENTIFIED_AT")
}

View File

@ -1,11 +1,12 @@
package no.iktdev.mediaprocessing.shared.common.database.tables
package no.iktdev.mediaprocessing.shared.database.tables
import no.iktdev.eventi.models.store.TaskStatus
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.util.UUID
import java.time.LocalDateTime
import java.util.*
object TasksTable: IntIdTable(name = "TASKS") {
val referenceId: Column<UUID> = uuid("REFERENCE_ID")
@ -16,6 +17,6 @@ object TasksTable: IntIdTable(name = "TASKS") {
val claimed: Column<Boolean> = bool("CLAIMED").default(false)
val claimedBy: Column<String?> = varchar("CLAIMED_BY",100).nullable()
val consumed: Column<Boolean> = bool("CONSUMED").default(false)
val lastCheckIn: Column<java.time.LocalDateTime?> = datetime("LAST_CHECK_IN").nullable()
val persistedAt: Column<java.time.LocalDateTime> = datetime("PERSISTED_AT").defaultExpression(CurrentDateTime)
val lastCheckIn: Column<LocalDateTime?> = datetime("LAST_CHECK_IN").nullable()
val persistedAt: Column<LocalDateTime> = datetime("PERSISTED_AT").defaultExpression(CurrentDateTime)
}

View File

@ -0,0 +1,5 @@
spring:
flyway:
enabled: true
locations: classpath:flyway
baseline-on-migrate: false

View File

@ -1,21 +1,29 @@
package no.iktdev.mediaprocessing.shared.common
package no.iktdev.mediaprocessing.shared.database
import com.fasterxml.jackson.databind.ObjectMapper
import mu.KotlinLogging
import no.iktdev.mediaprocessing.shared.common.database.Access
import no.iktdev.mediaprocessing.shared.common.database.DatabaseTypes
import no.iktdev.mediaprocessing.shared.common.database.withTransaction
import no.iktdev.mediaprocessing.shared.common.TestBase
import no.iktdev.mediaprocessing.shared.database.config.DatasourceConfiguration
import org.flywaydb.core.Flyway
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.statements.jdbc.JdbcConnectionImpl
import org.jetbrains.exposed.sql.transactions.TransactionManager
import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit.jupiter.SpringExtension
import javax.sql.DataSource
@SpringBootTest(
classes = [DatabaseApplication::class,
DatasourceConfiguration::class],
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
@ExtendWith(SpringExtension::class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
abstract class TestBaseWithDatabase: TestBase() {
val log = KotlinLogging.logger {}
@ -41,7 +49,7 @@ abstract class TestBaseWithDatabase: TestBase() {
databaseName = "testdb",
dbType = DatabaseTypes.H2
)
database = Database.connect(dataSource)
database = Database.Companion.connect(dataSource)
flyway = Flyway.configure()
.dataSource(dataSource)
.locations("classpath:flyway")
@ -53,7 +61,7 @@ abstract class TestBaseWithDatabase: TestBase() {
withTransaction {
val jdbc = (TransactionManager.current().connection as JdbcConnectionImpl).connection
val jdbc = (TransactionManager.Companion.current().connection as JdbcConnectionImpl).connection
val meta = jdbc.metaData
val tableNames = listOf<String>(
@ -65,7 +73,7 @@ abstract class TestBaseWithDatabase: TestBase() {
}
existingTables.forEach { (tableName, exists) ->
assertTrue(exists, "Table $tableName should exist after migration")
Assertions.assertTrue(exists, "Table $tableName should exist after migration")
}
log.info { "Found migrations: ${flyway.info().all().map { it.script }}" }
@ -75,7 +83,7 @@ abstract class TestBaseWithDatabase: TestBase() {
@AfterAll
fun clearDatabase() {
flyway.clean()
TransactionManager.closeAndUnregister(database)
TransactionManager.Companion.closeAndUnregister(database)
}
}
}

View File

@ -1,9 +1,9 @@
package no.iktdev.mediaprocessing.shared.common.config
package no.iktdev.mediaprocessing.shared.database.config
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import no.iktdev.mediaprocessing.shared.common.database.Access
import no.iktdev.mediaprocessing.shared.common.database.DatabaseTypes
import no.iktdev.mediaprocessing.shared.database.Access
import no.iktdev.mediaprocessing.shared.database.DatabaseTypes
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Primary
@ -23,7 +23,7 @@ class DatasourceConfiguration {
dbType = DatabaseTypes.H2
)
val maxPoolSize: Int = 10
val maxPoolSize = 10
val config = HikariConfig().apply {
this.jdbcUrl = "jdbc:h2:mem:${access.databaseName};MODE=MySQL;DB_CLOSE_DELAY=-1"
this.driverClassName = "org.h2.Driver"