diff --git a/backend/.gitignore b/backend/.gitignore index 276fa5c0a3..4102fdeaff 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -1,5 +1,6 @@ HELP.md .gradle +/.gradle-user/ build/ !gradle/wrapper/gradle-wrapper.jar !**/src/main/**/build/ @@ -42,3 +43,4 @@ out/ ### plantuml ### plantuml.jar +tmp/ diff --git a/backend/build.gradle b/backend/build.gradle index 06fb2c5479..74e9c7cba0 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -2,7 +2,6 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent plugins { - id 'org.springframework.boot' version '3.5.7' id 'io.spring.dependency-management' version '1.1.7' // If kotlin version bumped, check if gradle version can be bumped as well // Check here: https://kotlinlang.org/docs/gradle-configure-project.html#apply-the-plugin @@ -12,6 +11,7 @@ plugins { id 'org.jetbrains.kotlin.plugin.spring' version '2.2.21' id 'org.jlleitschuh.gradle.ktlint' version '14.0.1' id 'org.springdoc.openapi-gradle-plugin' version '1.9.0' + id 'org.springframework.boot' version '4.0.0' } group = 'org.loculus' @@ -39,47 +39,50 @@ repositories { } dependencies { - implementation "org.springframework.boot:spring-boot-starter-web" - implementation 'org.springframework.boot:spring-boot-starter-actuator' - implementation "com.fasterxml.jackson.module:jackson-module-kotlin" - implementation "org.jetbrains.kotlin:kotlin-reflect" + implementation "tools.jackson.module:jackson-module-kotlin" implementation "io.github.microutils:kotlin-logging-jvm:3.0.5" - implementation "org.postgresql:postgresql" implementation "org.apache.commons:commons-csv:1.14.1" - implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.14" - implementation "org.flywaydb:flyway-database-postgresql" // Version managed by Spring Boot to ensure compatibility + implementation "org.flywaydb:flyway-database-postgresql" + implementation "org.hibernate.validator:hibernate-validator" implementation platform("org.jetbrains.exposed:exposed-bom:0.61.0") - implementation "org.jetbrains.exposed:exposed-spring-boot-starter" implementation "org.jetbrains.exposed:exposed-jdbc" implementation "org.jetbrains.exposed:exposed-json" implementation "org.jetbrains.exposed:exposed-kotlin-datetime" + implementation "org.jetbrains.exposed:exposed-spring-boot-starter" + implementation "org.jetbrains.kotlin:kotlin-reflect" implementation "org.jetbrains.kotlinx:kotlinx-datetime:0.7.1-0.6.x-compat" - implementation "org.hibernate.validator:hibernate-validator" + implementation "org.jsoup:jsoup:1.21.2" implementation "org.keycloak:keycloak-admin-client:26.0.7" - implementation("io.minio:minio:8.6.0") - implementation("software.amazon.awssdk:s3:2.40.8") - + runtimeOnly "org.postgresql:postgresql" + implementation "org.redundent:kotlin-xml-builder:1.9.3" + implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.14" + implementation "org.springframework.boot:spring-boot-starter-flyway" + implementation "org.springframework.boot:spring-boot-starter-jdbc" implementation "org.springframework.boot:spring-boot-starter-oauth2-resource-server" implementation "org.springframework.boot:spring-boot-starter-security" - - implementation 'org.apache.commons:commons-compress' + implementation "org.springframework.boot:spring-boot-starter-web" + implementation "software.amazon.awssdk:s3:2.40.8" implementation 'com.github.luben:zstd-jni:1.5.7-6' - implementation 'org.tukaani:xz:1.11' - - implementation("org.redundent:kotlin-xml-builder:1.9.3") - implementation("org.jsoup:jsoup:1.21.2") + implementation 'org.apache.commons:commons-compress:1.28.0' + implementation 'org.springframework.boot:spring-boot-starter-actuator' - testImplementation("org.springframework.boot:spring-boot-starter-test") { - exclude group: "org.mockito" - } + testImplementation "tools.jackson.dataformat:jackson-dataformat-yaml" + testImplementation "io.minio:minio:8.6.0" + testImplementation "org.tukaani:xz:1.11" + testImplementation "com.ninja-squad:springmockk:5.0.1" testImplementation platform("io.jsonwebtoken:jjwt-bom:0.13.0") testImplementation "io.jsonwebtoken:jjwt-api" testImplementation "io.jsonwebtoken:jjwt-impl" testImplementation "io.jsonwebtoken:jjwt-jackson" - testImplementation "com.ninja-squad:springmockk:5.0.1" - testImplementation "org.testcontainers:postgresql" - testImplementation "org.testcontainers:minio" testImplementation "org.junit.platform:junit-platform-launcher" + testImplementation "org.springframework.boot:spring-boot-test-autoconfigure" + testImplementation("org.springframework.boot:spring-boot-starter-test") { + exclude group: "org.mockito" + } + testImplementation "org.springframework.boot:spring-boot-webmvc-test" + testImplementation platform("org.testcontainers:testcontainers-bom:2.0.3") + testImplementation "org.testcontainers:testcontainers-minio" + testImplementation "org.testcontainers:testcontainers-postgresql" ktlint("com.pinterest.ktlint:ktlint-cli:1.8.0") { attributes { attribute(Bundling.BUNDLING_ATTRIBUTE, getObjects().named(Bundling, Bundling.EXTERNAL)) diff --git a/backend/gradle.lockfile b/backend/gradle.lockfile index e0ba279e5f..a1a2a832c4 100644 --- a/backend/gradle.lockfile +++ b/backend/gradle.lockfile @@ -1,41 +1,41 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.20=compileClasspath,implementationDependenciesMetadata,ktlint,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.20=compileClasspath,implementationDependenciesMetadata,ktlint,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.carrotsearch.thirdparty:simple-xml-safe:2.7.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.fasterxml.jackson.core:jackson-annotations:2.19.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.fasterxml.jackson.core:jackson-core:2.19.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.fasterxml.jackson.core:jackson-databind:2.19.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.19.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.19.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.19.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.19.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-base:2.19.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-json-provider:2.19.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-annotations:2.19.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.fasterxml.jackson.module:jackson-module-kotlin:2.19.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.fasterxml.jackson.module:jackson-module-parameter-names:2.19.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.fasterxml.jackson:jackson-bom:2.19.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +biz.aQute.bnd:biz.aQute.bnd.annotation:7.1.0=compileClasspath,implementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata +ch.qos.logback:logback-classic:1.5.21=compileClasspath,implementationDependenciesMetadata,ktlint,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.21=compileClasspath,implementationDependenciesMetadata,ktlint,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.carrotsearch.thirdparty:simple-xml-safe:2.7.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.fasterxml.jackson.core:jackson-annotations:2.20=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.fasterxml.jackson.core:jackson-core:2.20.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.fasterxml.jackson.core:jackson-databind:2.20.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.20.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.20.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.20.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-base:2.20.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-json-provider:2.20.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-annotations:2.20.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.fasterxml.jackson:jackson-bom:2.20.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath com.fasterxml:classmate:1.7.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath com.github.ajalt.clikt:clikt-jvm:5.0.3=ktlint com.github.ajalt.clikt:clikt:5.0.3=ktlint -com.github.ben-manes.caffeine:caffeine:3.2.2=swiftExportClasspathResolvable -com.github.docker-java:docker-java-api:3.4.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.github.docker-java:docker-java-transport-zerodep:3.4.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.github.docker-java:docker-java-transport:3.4.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.github.ben-manes.caffeine:caffeine:3.2.3=swiftExportClasspathResolvable +com.github.docker-java:docker-java-api:3.7.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.github.docker-java:docker-java-transport-zerodep:3.7.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.github.docker-java:docker-java-transport:3.7.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath com.github.java-json-tools:json-patch:1.13=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath com.github.luben:zstd-jni:1.5.7-6=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.google.errorprone:error_prone_annotations:2.36.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.google.errorprone:error_prone_annotations:2.40.0=swiftExportClasspathResolvable -com.google.guava:failureaccess:1.0.3=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.google.guava:guava:33.4.8-jre=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.google.j2objc:j2objc-annotations:3.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.github.spotbugs:spotbugs-annotations:4.8.6=compileClasspath,implementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata +com.google.code.findbugs:jsr305:3.0.2=compileClasspath,implementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata +com.google.errorprone:error_prone_annotations:2.36.0=testRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.38.0=compileClasspath,implementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata +com.google.errorprone:error_prone_annotations:2.43.0=swiftExportClasspathResolvable +com.google.guava:failureaccess:1.0.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.google.guava:guava:33.4.8-jre=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath com.ibm.async:asyncutil:0.1.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.nimbusds:nimbus-jose-jwt:9.37.4=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.nimbusds:nimbus-jose-jwt:10.4=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath com.ninja-squad:springmockk:5.0.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath com.pinterest.ktlint:ktlint-cli-reporter-baseline:1.5.0=ktlintBaselineReporter com.pinterest.ktlint:ktlint-cli-reporter-baseline:1.8.0=ktlint @@ -54,19 +54,19 @@ com.pinterest.ktlint:ktlint-rule-engine-core:1.8.0=ktlint,ktlintBaselineReporter com.pinterest.ktlint:ktlint-rule-engine:1.8.0=ktlint com.pinterest.ktlint:ktlint-ruleset-standard:1.5.0=ktlintRuleset com.pinterest.ktlint:ktlint-ruleset-standard:1.8.0=ktlint -com.squareup.okhttp3:okhttp-jvm:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.squareup.okhttp3:okhttp:5.1.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.squareup.okio:okio-jvm:3.15.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.squareup.okio:okio:3.15.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.squareup.okhttp3:okhttp-jvm:5.1.0=testCompileClasspath,testRuntimeClasspath +com.squareup.okhttp3:okhttp:5.1.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.squareup.okio:okio-jvm:3.15.0=testCompileClasspath,testRuntimeClasspath +com.squareup.okio:okio:3.15.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath com.sun.istack:istack-commons-runtime:4.1.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath com.sun.istack:istack-commons-tools:4.1.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath com.sun.xml.bind.external:relaxng-datatype:4.0.3=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath com.sun.xml.bind.external:rngom:4.0.3=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -com.zaxxer:HikariCP:6.3.3=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -commons-codec:commons-codec:1.18.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +com.zaxxer:HikariCP:7.0.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +commons-codec:commons-codec:1.19.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath commons-io:commons-io:2.20.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -commons-logging:commons-logging:1.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +commons-logging:commons-logging:1.3.5=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath dev.drewhamilton.poko:poko-annotations-jvm:0.20.1=ktlint,ktlintBaselineReporter,ktlintRuleset dev.drewhamilton.poko:poko-annotations:0.20.1=ktlint,ktlintBaselineReporter,ktlintRuleset io.github.detekt.sarif4k:sarif4k-jvm:0.5.0=ktlint,ktlintReporter @@ -79,11 +79,11 @@ io.jsonwebtoken:jjwt-api:0.13.0=testCompileClasspath,testImplementationDependenc io.jsonwebtoken:jjwt-bom:0.13.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath io.jsonwebtoken:jjwt-impl:0.13.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath io.jsonwebtoken:jjwt-jackson:0.13.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -io.micrometer:micrometer-commons:1.15.5=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -io.micrometer:micrometer-core:1.15.5=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.15.5=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -io.micrometer:micrometer-observation:1.15.5=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -io.minio:minio:8.6.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +io.micrometer:micrometer-commons:1.16.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +io.micrometer:micrometer-core:1.16.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.16.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +io.micrometer:micrometer-observation:1.16.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +io.minio:minio:8.6.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath io.mockk:mockk-agent-api-jvm:1.14.6=testCompileClasspath,testRuntimeClasspath io.mockk:mockk-agent-api:1.14.6=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath io.mockk:mockk-agent-jvm:1.14.6=testCompileClasspath,testRuntimeClasspath @@ -93,62 +93,67 @@ io.mockk:mockk-core:1.14.6=testCompileClasspath,testImplementationDependenciesMe io.mockk:mockk-dsl-jvm:1.14.6=testCompileClasspath,testRuntimeClasspath io.mockk:mockk-dsl:1.14.6=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath io.mockk:mockk-jvm:1.14.6=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -io.netty:netty-buffer:4.1.128.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.netty:netty-codec-http2:4.1.128.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.netty:netty-codec-http:4.1.128.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.netty:netty-codec:4.1.128.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.netty:netty-common:4.1.128.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.netty:netty-handler:4.1.128.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.netty:netty-resolver:4.1.128.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.netty:netty-transport-classes-epoll:4.1.128.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.netty:netty-transport-native-unix-common:4.1.128.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.netty:netty-transport:4.1.128.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.opentelemetry:opentelemetry-api:1.49.0=swiftExportClasspathResolvable -io.opentelemetry:opentelemetry-context:1.49.0=swiftExportClasspathResolvable +io.netty:netty-buffer:4.2.7.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.netty:netty-codec-base:4.2.7.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.netty:netty-codec-compression:4.2.7.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.netty:netty-codec-http2:4.2.7.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.netty:netty-codec-http:4.2.7.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.netty:netty-codec-marshalling:4.2.7.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.netty:netty-codec-protobuf:4.2.7.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.netty:netty-codec:4.2.7.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.netty:netty-common:4.2.7.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.netty:netty-handler:4.2.7.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.netty:netty-resolver:4.2.7.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.netty:netty-transport-classes-epoll:4.2.7.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.netty:netty-transport-native-unix-common:4.2.7.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.netty:netty-transport:4.2.7.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.opentelemetry:opentelemetry-api:1.55.0=swiftExportClasspathResolvable +io.opentelemetry:opentelemetry-common:1.55.0=swiftExportClasspathResolvable +io.opentelemetry:opentelemetry-context:1.55.0=swiftExportClasspathResolvable io.swagger.core.v3:swagger-annotations-jakarta:2.2.38=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.38=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.38=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.4=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +jakarta.annotation:jakarta.annotation-api:3.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath jakarta.mail:jakarta.mail-api:2.1.5=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -jakarta.ws.rs:jakarta.ws.rs-api:3.1.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +jakarta.validation:jakarta.validation-api:3.1.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +jakarta.ws.rs:jakarta.ws.rs-api:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.4=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -junit:junit:4.13.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +junit:junit:4.13.2=testRuntimeClasspath net.bytebuddy:byte-buddy-agent:1.17.8=testCompileClasspath,testRuntimeClasspath net.bytebuddy:byte-buddy:1.17.8=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -net.java.dev.jna:jna:5.13.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -net.minidev:accessors-smart:2.5.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -net.minidev:json-smart:2.5.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +net.java.dev.jna:jna:5.18.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +net.minidev:accessors-smart:2.6.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +net.minidev:json-smart:2.6.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.apache.commons:commons-compress:1.28.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.apache.commons:commons-csv:1.14.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.apache.commons:commons-lang3:3.17.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.apache.commons:commons-lang3:3.19.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.apache.httpcomponents:httpclient:4.5.14=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.apache.httpcomponents:httpcore:4.4.16=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.apache.james:apache-mime4j-core:0.8.11=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.apache.james:apache-mime4j-dom:0.8.11=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.apache.james:apache-mime4j-storage:0.8.11=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.apache.logging.log4j:log4j-api:2.24.3=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.apache.logging.log4j:log4j-to-slf4j:2.24.3=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.48=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.48=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.48=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.apache.logging.log4j:log4j-api:2.25.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.apache.logging.log4j:log4j-to-slf4j:2.25.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:11.0.14=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:11.0.14=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:11.0.14=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata org.assertj:assertj-core:3.27.6=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.awaitility:awaitility:4.2.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.awaitility:awaitility:4.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.bouncycastle:bcpg-jdk18on:1.80=kotlinBouncyCastleConfiguration org.bouncycastle:bcpkix-jdk18on:1.80=kotlinBouncyCastleConfiguration org.bouncycastle:bcprov-jdk18on:1.80=kotlinBouncyCastleConfiguration -org.bouncycastle:bcprov-jdk18on:1.81=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.bouncycastle:bcprov-jdk18on:1.81=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.bouncycastle:bcutil-jdk18on:1.80=kotlinBouncyCastleConfiguration org.checkerframework:checker-qual:3.43.0=swiftExportClasspathResolvable org.checkerframework:checker-qual:3.49.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.ec4j.core:ec4j-core:1.1.1=ktlint,ktlintBaselineReporter,ktlintRuleset -org.eclipse.angus:angus-activation:2.0.3=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.eclipse.angus:angus-activation:1.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.eclipse.angus:angus-mail:2.0.5=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.eclipse.microprofile.openapi:microprofile-openapi-api:3.1.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.flywaydb:flyway-core:11.7.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.flywaydb:flyway-database-postgresql:11.7.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.flywaydb:flyway-core:11.14.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.flywaydb:flyway-database-postgresql:11.14.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.glassfish.jaxb:codemodel:4.0.6=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.glassfish.jaxb:jaxb-core:4.0.6=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.glassfish.jaxb:jaxb-jxc:4.0.6=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath @@ -156,10 +161,10 @@ org.glassfish.jaxb:jaxb-runtime:4.0.6=compileClasspath,implementationDependencie org.glassfish.jaxb:jaxb-xjc:4.0.6=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.glassfish.jaxb:txw2:4.0.6=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.glassfish.jaxb:xsom:4.0.6=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.hamcrest:hamcrest-core:3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.hamcrest:hamcrest-core:3.0=testRuntimeClasspath org.hamcrest:hamcrest:3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.validator:hibernate-validator:8.0.3.Final=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.hibernate.validator:hibernate-validator:9.0.1.Final=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.jboss.logging:commons-logging-jboss-logging:1.0.0.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.jboss.logging:jboss-logging:3.6.1.Final=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.jboss.resteasy:resteasy-client-api:6.2.9.Final=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath @@ -195,99 +200,124 @@ org.jetbrains.kotlin:kotlin-scripting-common:2.2.21=kotlinBuildToolsApiClasspath org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.2.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.2.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest org.jetbrains.kotlin:kotlin-scripting-jvm:2.2.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest -org.jetbrains.kotlin:kotlin-stdlib-common:2.2.21=compileClasspath,implementationDependenciesMetadata,ktlintReporter,productionRuntimeClasspath,runtimeClasspath,swiftExportClasspathResolvable,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-common:2.2.21=compileClasspath,implementationDependenciesMetadata,ktlintReporter,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.2.21=compileClasspath,implementationDependenciesMetadata,ktlintReporter,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.2.21=compileClasspath,implementationDependenciesMetadata,ktlintReporter,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib:2.2.21=apiDependenciesMetadata,compileClasspath,implementationDependenciesMetadata,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,ktlint,ktlintBaselineReporter,ktlintReporter,ktlintRuleset,productionRuntimeClasspath,runtimeClasspath,swiftExportClasspathResolvable,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.jetbrains.kotlin:swift-export-embeddable:2.2.21=swiftExportClasspathResolvable org.jetbrains.kotlinx:atomicfu:0.23.1=implementationDependenciesMetadata,testImplementationDependenciesMetadata -org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.1=testRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1=compileClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,ktlint,ktlintBaselineReporter,ktlintRuleset,productionRuntimeClasspath,runtimeClasspath,swiftExportClasspathResolvable,testCompileClasspath,testRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2=compileClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,ktlint,ktlintBaselineReporter,ktlintRuleset,productionRuntimeClasspath,runtimeClasspath,swiftExportClasspathResolvable,testCompileClasspath,testRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.2=implementationDependenciesMetadata,testImplementationDependenciesMetadata org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.7.1-0.6.x-compat=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jetbrains.kotlinx:kotlinx-datetime:0.7.1-0.6.x-compat=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-serialization-bom:1.6.3=compileClasspath,ktlintReporter,productionRuntimeClasspath,runtimeClasspath,swiftExportClasspathResolvable,testCompileClasspath,testRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.6.3=compileClasspath,ktlintReporter,productionRuntimeClasspath,runtimeClasspath,swiftExportClasspathResolvable,testCompileClasspath,testRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.3=compileClasspath,implementationDependenciesMetadata,ktlintReporter,productionRuntimeClasspath,runtimeClasspath,swiftExportClasspathResolvable,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.6.3=compileClasspath,ktlintReporter,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3=compileClasspath,implementationDependenciesMetadata,ktlintReporter,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-bom:1.9.0=compileClasspath,ktlintReporter,productionRuntimeClasspath,runtimeClasspath,swiftExportClasspathResolvable,testCompileClasspath,testRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.9.0=compileClasspath,ktlintReporter,productionRuntimeClasspath,runtimeClasspath,swiftExportClasspathResolvable,testCompileClasspath,testRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-core:1.9.0=compileClasspath,implementationDependenciesMetadata,ktlintReporter,productionRuntimeClasspath,runtimeClasspath,swiftExportClasspathResolvable,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.9.0=compileClasspath,ktlintReporter,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0=compileClasspath,implementationDependenciesMetadata,ktlintReporter,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.jetbrains:annotations:13.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,ktlint,ktlintBaselineReporter,ktlintReporter,ktlintRuleset,swiftExportClasspathResolvable org.jetbrains:annotations:17.0.0=testImplementationDependenciesMetadata org.jetbrains:annotations:23.0.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jsoup:jsoup:1.21.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.jspecify:jspecify:1.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,swiftExportClasspathResolvable,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.junit.jupiter:junit-jupiter-api:5.12.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.junit.jupiter:junit-jupiter-engine:5.12.2=testRuntimeClasspath -org.junit.jupiter:junit-jupiter-params:5.12.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.junit.jupiter:junit-jupiter:5.12.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.junit.platform:junit-platform-commons:1.12.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.junit.platform:junit-platform-engine:1.12.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.junit.platform:junit-platform-launcher:1.12.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.junit:junit-bom:5.12.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.junit.jupiter:junit-jupiter-api:6.0.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.junit.jupiter:junit-jupiter-engine:6.0.1=testRuntimeClasspath +org.junit.jupiter:junit-jupiter-params:6.0.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.junit.jupiter:junit-jupiter:6.0.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.junit.platform:junit-platform-commons:6.0.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.junit.platform:junit-platform-engine:6.0.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.junit.platform:junit-platform-launcher:6.0.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.junit:junit-bom:6.0.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.keycloak:keycloak-admin-client:26.0.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.keycloak:keycloak-client-common-synced:26.0.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.latencyutils:LatencyUtils:2.0.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.objenesis:objenesis:3.3=testCompileClasspath,testRuntimeClasspath org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.osgi:org.osgi.annotation.bundle:2.0.0=compileClasspath,implementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata +org.osgi:org.osgi.annotation.versioning:1.1.2=compileClasspath,implementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata +org.osgi:org.osgi.resource:1.0.0=compileClasspath,implementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata +org.osgi:org.osgi.service.serviceloader:1.0.0=compileClasspath,implementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata org.ow2.asm:asm:9.7.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.postgresql:postgresql:42.7.8=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.postgresql:postgresql:42.7.8=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.reactivestreams:reactive-streams:1.0.4=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.redundent:kotlin-xml-builder:1.9.3=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.17=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.slf4j:slf4j-api:2.0.17=compileClasspath,implementationDependenciesMetadata,ktlint,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.snakeyaml:snakeyaml-engine:2.10=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-common:2.8.14=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.8.14=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.14=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.5.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.5.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.5.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.5.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.5.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.5.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.5.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.5.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.5.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.5.7=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.5.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.5.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.5.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.5.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.5.7=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.5.7=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.boot:spring-boot:3.5.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.security:spring-security-config:6.5.6=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.security:spring-security-core:6.5.6=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.security:spring-security-crypto:6.5.6=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.security:spring-security-oauth2-core:6.5.6=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.security:spring-security-oauth2-jose:6.5.6=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.security:spring-security-oauth2-resource-server:6.5.6=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework.security:spring-security-web:6.5.6=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework:spring-aop:6.2.12=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework:spring-beans:6.2.12=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework:spring-context:6.2.12=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework:spring-core:6.2.12=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework:spring-expression:6.2.12=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework:spring-jcl:6.2.12=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework:spring-jdbc:6.2.12=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework:spring-test:6.2.12=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework:spring-tx:6.2.12=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework:spring-web:6.2.12=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.springframework:spring-webmvc:6.2.12=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.testcontainers:database-commons:1.21.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.testcontainers:jdbc:1.21.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.testcontainers:minio:1.21.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.testcontainers:postgresql:1.21.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.testcontainers:testcontainers:1.21.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.tukaani:xz:1.11=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-flyway:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-health:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-http-converter:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-jackson:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-jdbc:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-micrometer-metrics:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-micrometer-observation:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-persistence:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-security-oauth2-resource-server:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-security:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-servlet:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-sql:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-flyway:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jackson:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-micrometer-metrics:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:4.0.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat-runtime:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:4.0.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-test:4.0.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-tomcat:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-transaction:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-validation:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-web-server:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-webmvc-test:4.0.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot-webmvc:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.boot:spring-boot:4.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.security:spring-security-config:7.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.security:spring-security-core:7.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.security:spring-security-crypto:7.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.security:spring-security-oauth2-core:7.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.security:spring-security-oauth2-jose:7.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.security:spring-security-oauth2-resource-server:7.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework.security:spring-security-web:7.0.0=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework:spring-aop:7.0.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework:spring-beans:7.0.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework:spring-context:7.0.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework:spring-core:7.0.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework:spring-expression:7.0.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework:spring-jdbc:7.0.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework:spring-test:7.0.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework:spring-tx:7.0.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework:spring-web:7.0.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.springframework:spring-webmvc:7.0.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.testcontainers:testcontainers-bom:2.0.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.testcontainers:testcontainers-database-commons:2.0.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.testcontainers:testcontainers-jdbc:2.0.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.testcontainers:testcontainers-minio:2.0.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.testcontainers:testcontainers-postgresql:2.0.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.testcontainers:testcontainers:2.0.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.tukaani:xz:1.11=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.webjars:swagger-ui:5.30.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.webjars:webjars-locator-lite:1.1.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.xerial.snappy:snappy-java:1.1.10.7=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.xerial.snappy:snappy-java:1.1.10.7=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath org.xmlunit:xmlunit-core:2.10.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -org.yaml:snakeyaml:2.4=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +org.yaml:snakeyaml:2.5=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath software.amazon.awssdk:annotations:2.40.8=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath software.amazon.awssdk:apache-client:2.40.8=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath software.amazon.awssdk:arns:2.40.8=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath @@ -319,4 +349,9 @@ software.amazon.awssdk:third-party-jackson-core:2.40.8=compileClasspath,implemen software.amazon.awssdk:utils-lite:2.40.8=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath software.amazon.awssdk:utils:2.40.8=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath software.amazon.eventstream:eventstream:1.0.1=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath -empty=annotationProcessor,compileOnlyDependenciesMetadata,developmentOnly,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,testAndDevelopmentOnly,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions +tools.jackson.core:jackson-core:3.0.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +tools.jackson.core:jackson-databind:3.0.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +tools.jackson.dataformat:jackson-dataformat-yaml:3.0.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +tools.jackson.module:jackson-module-kotlin:3.0.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +tools.jackson:jackson-bom:3.0.2=compileClasspath,implementationDependenciesMetadata,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath +empty=annotationProcessor,combinedGraphClasspath,compileOnlyDependenciesMetadata,developmentOnly,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,projectHealthClasspath,resolvedDepsClasspath,testAndDevelopmentOnly,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions diff --git a/backend/src/main/kotlin/org/loculus/backend/BackendApplication.kt b/backend/src/main/kotlin/org/loculus/backend/BackendApplication.kt index 1df177ab69..f1edbf8b36 100644 --- a/backend/src/main/kotlin/org/loculus/backend/BackendApplication.kt +++ b/backend/src/main/kotlin/org/loculus/backend/BackendApplication.kt @@ -3,7 +3,9 @@ package org.loculus.backend import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication -@SpringBootApplication +@SpringBootApplication( + excludeName = ["org.jetbrains.exposed.spring.autoconfigure.ExposedAutoConfiguration"], +) class BackendApplication fun main(args: Array) { diff --git a/backend/src/main/kotlin/org/loculus/backend/api/DataUseTerms.kt b/backend/src/main/kotlin/org/loculus/backend/api/DataUseTerms.kt index 5bba9e10d6..67eb1de276 100644 --- a/backend/src/main/kotlin/org/loculus/backend/api/DataUseTerms.kt +++ b/backend/src/main/kotlin/org/loculus/backend/api/DataUseTerms.kt @@ -6,15 +6,15 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder import com.fasterxml.jackson.annotation.JsonSubTypes import com.fasterxml.jackson.annotation.JsonTypeInfo import com.fasterxml.jackson.annotation.JsonTypeName -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.databind.SerializerProvider -import com.fasterxml.jackson.databind.annotation.JsonSerialize -import com.fasterxml.jackson.databind.ser.std.StdSerializer import io.swagger.v3.oas.annotations.media.Schema import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDateTime import org.loculus.backend.controller.BadRequestException import org.loculus.backend.utils.Accession +import tools.jackson.core.JsonGenerator +import tools.jackson.databind.SerializationContext +import tools.jackson.databind.annotation.JsonSerialize +import tools.jackson.databind.ser.std.StdSerializer data class DataUseTermsHistoryEntry( val accession: Accession, @@ -117,13 +117,13 @@ data class DataUseTermsChangeRequest( ) private class LocalDateSerializer : StdSerializer(LocalDate::class.java) { - override fun serialize(value: LocalDate, gen: JsonGenerator, provider: SerializerProvider) { + override fun serialize(value: LocalDate, gen: JsonGenerator, provider: SerializationContext) { gen.writeString(value.toString()) } } private class LocalDateTimeSerializer : StdSerializer(LocalDateTime::class.java) { - override fun serialize(value: LocalDateTime, gen: JsonGenerator, provider: SerializerProvider) { + override fun serialize(value: LocalDateTime, gen: JsonGenerator, provider: SerializationContext) { gen.writeString(value.toString()) } } diff --git a/backend/src/main/kotlin/org/loculus/backend/api/SubmissionTypes.kt b/backend/src/main/kotlin/org/loculus/backend/api/SubmissionTypes.kt index b9a99a0249..7b0fd9ed9b 100644 --- a/backend/src/main/kotlin/org/loculus/backend/api/SubmissionTypes.kt +++ b/backend/src/main/kotlin/org/loculus/backend/api/SubmissionTypes.kt @@ -2,11 +2,6 @@ package org.loculus.backend.api import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonValue -import com.fasterxml.jackson.core.JsonParser -import com.fasterxml.jackson.databind.DeserializationContext -import com.fasterxml.jackson.databind.JsonDeserializer -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.annotation.JsonDeserialize import io.swagger.v3.oas.annotations.media.Schema import org.loculus.backend.model.FastaId import org.loculus.backend.model.SubmissionId @@ -15,6 +10,11 @@ import org.loculus.backend.utils.Accession import org.loculus.backend.utils.Version import org.springframework.core.convert.converter.Converter import org.springframework.stereotype.Component +import tools.jackson.core.JsonParser +import tools.jackson.databind.DeserializationContext +import tools.jackson.databind.JsonNode +import tools.jackson.databind.ValueDeserializer +import tools.jackson.databind.annotation.JsonDeserialize data class Accessions(val accessions: List) @@ -134,7 +134,7 @@ data class SequenceEntryVersionToEdit( typealias SegmentName = String typealias GeneName = String typealias GeneticSequence = String -typealias MetadataMap = Map +typealias MetadataMap = Map data class ProcessedData( @Schema( @@ -239,7 +239,7 @@ data class Insertion( override fun toString(): String = "$position:$sequence" } -class InsertionDeserializer : JsonDeserializer() { +class InsertionDeserializer : ValueDeserializer() { override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Insertion = Insertion.fromString(p.valueAsString) } diff --git a/backend/src/main/kotlin/org/loculus/backend/config/BackendSpringConfig.kt b/backend/src/main/kotlin/org/loculus/backend/config/BackendSpringConfig.kt index e9ab9640a1..22a2d21e1b 100644 --- a/backend/src/main/kotlin/org/loculus/backend/config/BackendSpringConfig.kt +++ b/backend/src/main/kotlin/org/loculus/backend/config/BackendSpringConfig.kt @@ -1,13 +1,9 @@ package org.loculus.backend.config -import com.fasterxml.jackson.databind.DeserializationFeature -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue import io.swagger.v3.oas.models.headers.Header import io.swagger.v3.oas.models.media.StringSchema import io.swagger.v3.oas.models.parameters.HeaderParameter import org.flywaydb.core.Flyway -import org.jetbrains.exposed.spring.autoconfigure.ExposedAutoConfiguration import org.jetbrains.exposed.sql.Database import org.jetbrains.exposed.sql.DatabaseConfig import org.jetbrains.exposed.sql.Slf4jSqlDebugLogger @@ -21,14 +17,20 @@ import org.springdoc.core.customizers.OperationCustomizer import org.springframework.beans.factory.InitializingBean import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.ImportAutoConfiguration -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration import org.springframework.boot.context.properties.ConfigurationPropertiesScan +import org.springframework.boot.jackson.autoconfigure.JsonMapperBuilderCustomizer +import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Profile import org.springframework.scheduling.annotation.EnableScheduling import org.springframework.stereotype.Component import org.springframework.web.filter.CommonsRequestLoggingFilter +import tools.jackson.databind.DeserializationFeature +import tools.jackson.databind.ObjectMapper +import tools.jackson.databind.json.JsonMapper +import tools.jackson.module.kotlin.KotlinModule +import tools.jackson.module.kotlin.readValue import java.io.File import javax.sql.DataSource @@ -59,7 +61,7 @@ private val logger = mu.KotlinLogging.logger {} @Configuration @EnableScheduling @ImportAutoConfiguration( - value = [ExposedAutoConfiguration::class], + value = [ExposedAutoConfigurationCompat::class], // TODO(#5754) Revert shim once exposed supports spring boot 4 exclude = [DataSourceTransactionManagerAutoConfiguration::class], ) @ConfigurationPropertiesScan("org.loculus.backend") @@ -82,6 +84,17 @@ class BackendSpringConfig { sqlLogger = Slf4jSqlDebugLogger } + @Bean + fun loculusJacksonCustomizer(): JsonMapperBuilderCustomizer = JsonMapperBuilderCustomizer { builder -> + builder.addModule( + KotlinModule.Builder() + .disable(tools.jackson.module.kotlin.KotlinFeature.StrictNullChecks) + .build(), + ) + builder.disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) + builder.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + } + @Bean fun backendConfig( objectMapper: ObjectMapper, @@ -198,9 +211,12 @@ internal fun validateEarliestReleaseDateFields(config: BackendConfig): List(File(configPath)) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .build() + val config = mapper.readValue(File(configPath)) logger.info { "Loaded backend config from $configPath" } logger.info { "Config: $config" } val validationErrors = validateEarliestReleaseDateFields(config) diff --git a/backend/src/main/kotlin/org/loculus/backend/config/ExposedAutoConfigurationCompat.kt b/backend/src/main/kotlin/org/loculus/backend/config/ExposedAutoConfigurationCompat.kt new file mode 100644 index 0000000000..7c33be62b3 --- /dev/null +++ b/backend/src/main/kotlin/org/loculus/backend/config/ExposedAutoConfigurationCompat.kt @@ -0,0 +1,45 @@ +// TODO(#5754) Remove shim once exposed supports spring boot 4 +package org.loculus.backend.config + +import org.jetbrains.exposed.spring.DatabaseInitializer +import org.jetbrains.exposed.spring.ExposedSpringTransactionAttributeSource +import org.jetbrains.exposed.spring.SpringTransactionManager +import org.jetbrains.exposed.sql.DatabaseConfig +import org.springframework.beans.factory.annotation.Value +import org.springframework.boot.autoconfigure.AutoConfiguration +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.context.ApplicationContext +import org.springframework.context.annotation.Bean +import javax.sql.DataSource + +// Compatibility shim for EXPOSED-944 (Boot 4 moved DataSourceAutoConfiguration packages). +@AutoConfiguration( + afterName = [ + "org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration", + "org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration", + ], +) +class ExposedAutoConfigurationCompat(private val applicationContext: ApplicationContext) { + @Value("\${spring.exposed.excluded-packages:}#{T(java.util.Collections).emptyList()}") + private lateinit var excludedPackages: List + + @Value("\${spring.exposed.show-sql:false}") + private var showSql: Boolean = false + + @Bean + fun springTransactionManager(dataSource: DataSource, databaseConfig: DatabaseConfig): SpringTransactionManager = + SpringTransactionManager(dataSource, databaseConfig, showSql) + + @Bean + @ConditionalOnMissingBean + fun databaseConfig(): DatabaseConfig = DatabaseConfig { } + + @Bean + @ConditionalOnProperty(value = ["spring.exposed.generate-ddl"], havingValue = "true") + fun databaseInitializer(): DatabaseInitializer = DatabaseInitializer(applicationContext, excludedPackages) + + @Bean + fun exposedSpringTransactionAttributeSource(): ExposedSpringTransactionAttributeSource = + ExposedSpringTransactionAttributeSource() +} diff --git a/backend/src/main/kotlin/org/loculus/backend/controller/SubmissionController.kt b/backend/src/main/kotlin/org/loculus/backend/controller/SubmissionController.kt index a7e3c4ffbf..e848dd0134 100644 --- a/backend/src/main/kotlin/org/loculus/backend/controller/SubmissionController.kt +++ b/backend/src/main/kotlin/org/loculus/backend/controller/SubmissionController.kt @@ -1,7 +1,5 @@ package org.loculus.backend.controller -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue import io.swagger.v3.oas.annotations.Operation import io.swagger.v3.oas.annotations.Parameter import io.swagger.v3.oas.annotations.headers.Header @@ -69,6 +67,8 @@ import org.springframework.web.bind.annotation.ResponseStatus import org.springframework.web.bind.annotation.RestController import org.springframework.web.multipart.MultipartFile import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody +import tools.jackson.databind.ObjectMapper +import tools.jackson.module.kotlin.readValue import java.util.UUID import io.swagger.v3.oas.annotations.parameters.RequestBody as SwaggerRequestBody diff --git a/backend/src/main/kotlin/org/loculus/backend/model/ReleasedDataModel.kt b/backend/src/main/kotlin/org/loculus/backend/model/ReleasedDataModel.kt index ed3419fb8b..1fe885321a 100644 --- a/backend/src/main/kotlin/org/loculus/backend/model/ReleasedDataModel.kt +++ b/backend/src/main/kotlin/org/loculus/backend/model/ReleasedDataModel.kt @@ -1,11 +1,5 @@ package org.loculus.backend.model -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.node.BooleanNode -import com.fasterxml.jackson.databind.node.IntNode -import com.fasterxml.jackson.databind.node.LongNode -import com.fasterxml.jackson.databind.node.NullNode -import com.fasterxml.jackson.databind.node.TextNode import mu.KotlinLogging import org.loculus.backend.api.DataUseTerms import org.loculus.backend.api.FileCategory @@ -37,6 +31,12 @@ import org.loculus.backend.utils.toTimestamp import org.loculus.backend.utils.toUtcDateString import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional +import tools.jackson.databind.ObjectMapper +import tools.jackson.databind.node.BooleanNode +import tools.jackson.databind.node.IntNode +import tools.jackson.databind.node.LongNode +import tools.jackson.databind.node.NullNode +import tools.jackson.databind.node.StringNode import java.net.URLEncoder import java.nio.charset.StandardCharsets @@ -120,7 +120,7 @@ open class ReleasedDataModel( val currentDataUseTerms = computeDataUseTerm(rawProcessedData) val restrictedDataUseTermsUntil = if (currentDataUseTerms is DataUseTerms.Restricted) { - TextNode(currentDataUseTerms.restrictedUntil.toString()) + StringNode(currentDataUseTerms.restrictedUntil.toString()) } else { NullNode.getInstance() } @@ -138,26 +138,26 @@ open class ReleasedDataModel( val metadata = rawProcessedData.processedData.metadata + mapOf( - ("accession" to TextNode(rawProcessedData.accession)), + ("accession" to StringNode(rawProcessedData.accession)), ("version" to LongNode(rawProcessedData.version)), - ("submissionId" to TextNode(rawProcessedData.submissionId)), - ("accessionVersion" to TextNode(rawProcessedData.displayAccessionVersion())), + ("submissionId" to StringNode(rawProcessedData.submissionId)), + ("accessionVersion" to StringNode(rawProcessedData.displayAccessionVersion())), ("isRevocation" to BooleanNode.valueOf(rawProcessedData.isRevocation)), - ("submitter" to TextNode(rawProcessedData.submitter)), + ("submitter" to StringNode(rawProcessedData.submitter)), ("groupId" to IntNode(rawProcessedData.groupId)), - ("groupName" to TextNode(rawProcessedData.groupName)), - ("submittedDate" to TextNode(rawProcessedData.submittedAtTimestamp.toUtcDateString())), + ("groupName" to StringNode(rawProcessedData.groupName)), + ("submittedDate" to StringNode(rawProcessedData.submittedAtTimestamp.toUtcDateString())), ("submittedAtTimestamp" to LongNode(rawProcessedData.submittedAtTimestamp.toTimestamp())), ("releasedAtTimestamp" to LongNode(rawProcessedData.releasedAtTimestamp.toTimestamp())), - ("releasedDate" to TextNode(rawProcessedData.releasedAtTimestamp.toUtcDateString())), - ("versionStatus" to TextNode(versionStatus.name)), + ("releasedDate" to StringNode(rawProcessedData.releasedAtTimestamp.toUtcDateString())), + ("versionStatus" to StringNode(versionStatus.name)), ("pipelineVersion" to LongNode(rawProcessedData.pipelineVersion)), ) + conditionalMetadata( backendConfig.dataUseTerms.enabled, { mapOf( - "dataUseTerms" to TextNode(currentDataUseTerms.type.name), + "dataUseTerms" to StringNode(currentDataUseTerms.type.name), "dataUseTermsRestrictedUntil" to restrictedDataUseTermsUntil, ) }, @@ -166,7 +166,8 @@ open class ReleasedDataModel( rawProcessedData.isRevocation, { mapOf( - "versionComment" to TextNode(rawProcessedData.versionComment), + "versionComment" to + (rawProcessedData.versionComment?.let { StringNode(it) } ?: NullNode.instance), ) }, ) + @@ -174,7 +175,7 @@ open class ReleasedDataModel( earliestReleaseDate != null, { mapOf( - "earliestReleaseDate" to TextNode(earliestReleaseDate!!.toUtcDateString()), + "earliestReleaseDate" to StringNode(earliestReleaseDate!!.toUtcDateString()), ) }, ) + @@ -182,7 +183,7 @@ open class ReleasedDataModel( dataUseTermsUrl != null, { mapOf( - "dataUseTermsUrl" to TextNode(dataUseTermsUrl!!), + "dataUseTermsUrl" to StringNode(dataUseTermsUrl!!), ) }, ) + @@ -195,7 +196,9 @@ open class ReleasedDataModel( rawProcessedData.processedData.files ?: emptyMap(), ) filesFieldNames.associateWith { NullNode.instance } + filesWithUrls.mapValues { (_, value) -> - TextNode(objectMapper.writeValueAsString(value)) + // TODO(#5754) This produces a double-encoded JSON string in the metadata map. + // Change to valueToTree(value) once the API consumer (website) is ready. + StringNode(objectMapper.writeValueAsString(value)) } }, ) diff --git a/backend/src/main/kotlin/org/loculus/backend/service/JacksonSerializableJsonb.kt b/backend/src/main/kotlin/org/loculus/backend/service/JacksonSerializableJsonb.kt index f3eb08ca55..f2773ad1af 100644 --- a/backend/src/main/kotlin/org/loculus/backend/service/JacksonSerializableJsonb.kt +++ b/backend/src/main/kotlin/org/loculus/backend/service/JacksonSerializableJsonb.kt @@ -1,12 +1,24 @@ package org.loculus.backend.service -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue import org.jetbrains.exposed.sql.Table import org.jetbrains.exposed.sql.json.jsonb +import tools.jackson.databind.DeserializationFeature +import tools.jackson.databind.ObjectMapper +import tools.jackson.databind.json.JsonMapper +import tools.jackson.module.kotlin.KotlinModule +import tools.jackson.module.kotlin.readValue + +val jacksonObjectMapper: ObjectMapper = JsonMapper.builder() + .addModule( + KotlinModule.Builder() + .disable(tools.jackson.module.kotlin.KotlinFeature.StrictNullChecks) + .build(), + ) + .findAndAddModules() + .disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .build() -val jacksonObjectMapper: ObjectMapper = jacksonObjectMapper().findAndRegisterModules() inline fun Table.jacksonSerializableJsonb(columnName: String) = jsonb( columnName, ::serialize, diff --git a/backend/src/main/kotlin/org/loculus/backend/service/submission/EmptyProcessedDataProvider.kt b/backend/src/main/kotlin/org/loculus/backend/service/submission/EmptyProcessedDataProvider.kt index 8de2774f41..ebf956647c 100644 --- a/backend/src/main/kotlin/org/loculus/backend/service/submission/EmptyProcessedDataProvider.kt +++ b/backend/src/main/kotlin/org/loculus/backend/service/submission/EmptyProcessedDataProvider.kt @@ -1,11 +1,11 @@ package org.loculus.backend.service.submission -import com.fasterxml.jackson.databind.node.NullNode import org.loculus.backend.api.GeneticSequence import org.loculus.backend.api.Organism import org.loculus.backend.api.ProcessedData import org.loculus.backend.config.BackendConfig import org.springframework.stereotype.Component +import tools.jackson.databind.node.NullNode @Component class EmptyProcessedDataProvider(private val backendConfig: BackendConfig) { diff --git a/backend/src/main/kotlin/org/loculus/backend/service/submission/ProcessedMetadataPostprocessor.kt b/backend/src/main/kotlin/org/loculus/backend/service/submission/ProcessedMetadataPostprocessor.kt index 8e37e632a2..19c24c6099 100644 --- a/backend/src/main/kotlin/org/loculus/backend/service/submission/ProcessedMetadataPostprocessor.kt +++ b/backend/src/main/kotlin/org/loculus/backend/service/submission/ProcessedMetadataPostprocessor.kt @@ -1,15 +1,15 @@ package org.loculus.backend.service.submission -import com.fasterxml.jackson.databind.node.NullNode import org.loculus.backend.api.Organism import org.loculus.backend.api.ProcessedData import org.loculus.backend.config.BackendConfig import org.springframework.stereotype.Service +import tools.jackson.databind.node.NullNode @Service class ProcessedMetadataPostprocessor(private val backendConfig: BackendConfig) { fun stripNullValuesFromMetadata(processedData: ProcessedData) = - processedData.copy(metadata = processedData.metadata.filterNot { (_, value) -> value.isNull }) + processedData.copy(metadata = processedData.metadata.filterNot { (_, value) -> value == null || value.isNull }) /** Filter out any extra fields that are not in the current schema and add nulls for any missing fields. */ fun filterOutExtraFieldsAndAddNulls(processedData: ProcessedData, organism: Organism) = diff --git a/backend/src/main/kotlin/org/loculus/backend/service/submission/ProcessedSequenceEntryValidator.kt b/backend/src/main/kotlin/org/loculus/backend/service/submission/ProcessedSequenceEntryValidator.kt index e803ddbb95..b7a515ffca 100644 --- a/backend/src/main/kotlin/org/loculus/backend/service/submission/ProcessedSequenceEntryValidator.kt +++ b/backend/src/main/kotlin/org/loculus/backend/service/submission/ProcessedSequenceEntryValidator.kt @@ -1,7 +1,5 @@ package org.loculus.backend.service.submission -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.node.NullNode import org.loculus.backend.api.GeneticSequence import org.loculus.backend.api.Insertion import org.loculus.backend.api.MetadataMap @@ -15,6 +13,8 @@ import org.loculus.backend.config.ReferenceSequence import org.loculus.backend.config.Schema import org.loculus.backend.controller.ProcessingValidationException import org.springframework.stereotype.Component +import tools.jackson.databind.JsonNode +import tools.jackson.databind.node.NullNode import java.time.LocalDate import java.time.format.DateTimeFormatter import java.time.format.DateTimeParseException @@ -127,7 +127,7 @@ private fun validateType(fieldValue: JsonNode, metadata: BaseMetadata) { when (metadata.type) { MetadataType.DATE -> { - if (!isValidDate(fieldValue.asText())) { + if (!isValidDate(fieldValue.asString())) { throw ProcessingValidationException( "Expected type 'date' in format '$DATE_FORMAT' for field '${metadata.name}', " + "found value '$fieldValue'.", @@ -140,7 +140,7 @@ private fun validateType(fieldValue: JsonNode, metadata: BaseMetadata) { } val isOfCorrectPrimitiveType = when (metadata.type) { - MetadataType.STRING, MetadataType.AUTHORS -> fieldValue.isTextual + MetadataType.STRING, MetadataType.AUTHORS -> fieldValue.isString MetadataType.INTEGER -> fieldValue.isInt MetadataType.FLOAT -> fieldValue.isFloatingPointNumber MetadataType.NUMBER -> fieldValue.isNumber diff --git a/backend/src/main/kotlin/org/loculus/backend/service/submission/ProcessedSequencesPostprocessor.kt b/backend/src/main/kotlin/org/loculus/backend/service/submission/ProcessedSequencesPostprocessor.kt index e73312ca0d..0018da9acc 100644 --- a/backend/src/main/kotlin/org/loculus/backend/service/submission/ProcessedSequencesPostprocessor.kt +++ b/backend/src/main/kotlin/org/loculus/backend/service/submission/ProcessedSequencesPostprocessor.kt @@ -1,10 +1,10 @@ package org.loculus.backend.service.submission -import com.fasterxml.jackson.databind.node.NullNode import org.loculus.backend.api.Organism import org.loculus.backend.api.ProcessedData import org.loculus.backend.config.BackendConfig import org.springframework.stereotype.Service +import tools.jackson.databind.node.NullNode @Service class ProcessedSequencesPostprocessor(private val backendConfig: BackendConfig) { diff --git a/backend/src/main/kotlin/org/loculus/backend/service/submission/SubmissionDatabaseService.kt b/backend/src/main/kotlin/org/loculus/backend/service/submission/SubmissionDatabaseService.kt index babc956715..859bcad3f8 100644 --- a/backend/src/main/kotlin/org/loculus/backend/service/submission/SubmissionDatabaseService.kt +++ b/backend/src/main/kotlin/org/loculus/backend/service/submission/SubmissionDatabaseService.kt @@ -1,8 +1,5 @@ package org.loculus.backend.service.submission -import com.fasterxml.jackson.core.JacksonException -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue import kotlinx.datetime.DateTimeUnit import kotlinx.datetime.LocalDateTime import kotlinx.datetime.minus @@ -94,6 +91,9 @@ import org.loculus.backend.utils.toTimestamp import org.springframework.beans.factory.annotation.Value import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional +import tools.jackson.core.JacksonException +import tools.jackson.databind.ObjectMapper +import tools.jackson.module.kotlin.readValue import java.io.BufferedReader import java.io.InputStream import java.io.InputStreamReader diff --git a/backend/src/main/kotlin/org/loculus/backend/utils/EarliestReleaseDateFinder.kt b/backend/src/main/kotlin/org/loculus/backend/utils/EarliestReleaseDateFinder.kt index d34e7419c3..78dad4880c 100644 --- a/backend/src/main/kotlin/org/loculus/backend/utils/EarliestReleaseDateFinder.kt +++ b/backend/src/main/kotlin/org/loculus/backend/utils/EarliestReleaseDateFinder.kt @@ -37,7 +37,7 @@ class EarliestReleaseDateFinder(private val fields: List) { var earliestReleaseDate = rawProcessedData.releasedAtTimestamp fields.forEach { field -> - rawProcessedData.processedData.metadata[field]?.textValue()?.let { dateText -> + rawProcessedData.processedData.metadata[field]?.stringValue()?.let { dateText -> val date = try { LocalDateTime(LocalDate.parse(dateText), LocalTime.fromSecondOfDay(0)) } catch (e: IllegalArgumentException) { diff --git a/backend/src/main/kotlin/org/loculus/backend/utils/IteratorStreamer.kt b/backend/src/main/kotlin/org/loculus/backend/utils/IteratorStreamer.kt index e8cf7f1b74..394983a1d2 100644 --- a/backend/src/main/kotlin/org/loculus/backend/utils/IteratorStreamer.kt +++ b/backend/src/main/kotlin/org/loculus/backend/utils/IteratorStreamer.kt @@ -1,7 +1,7 @@ package org.loculus.backend.utils -import com.fasterxml.jackson.databind.ObjectMapper import org.springframework.stereotype.Service +import tools.jackson.databind.ObjectMapper import java.io.OutputStream @Service diff --git a/backend/src/main/kotlin/org/loculus/backend/utils/LocalDateJacksonModule.kt b/backend/src/main/kotlin/org/loculus/backend/utils/LocalDateJacksonModule.kt index be687bfc7c..6c7f599a27 100644 --- a/backend/src/main/kotlin/org/loculus/backend/utils/LocalDateJacksonModule.kt +++ b/backend/src/main/kotlin/org/loculus/backend/utils/LocalDateJacksonModule.kt @@ -1,14 +1,14 @@ package org.loculus.backend.utils -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.JsonParser -import com.fasterxml.jackson.databind.DeserializationContext -import com.fasterxml.jackson.databind.JsonDeserializer -import com.fasterxml.jackson.databind.JsonSerializer -import com.fasterxml.jackson.databind.SerializerProvider -import com.fasterxml.jackson.databind.module.SimpleModule import kotlinx.datetime.LocalDate import org.springframework.context.annotation.Configuration +import tools.jackson.core.JsonGenerator +import tools.jackson.core.JsonParser +import tools.jackson.databind.DeserializationContext +import tools.jackson.databind.SerializationContext +import tools.jackson.databind.ValueDeserializer +import tools.jackson.databind.ValueSerializer +import tools.jackson.databind.module.SimpleModule @Configuration class LocalDateJacksonModule : SimpleModule() { @@ -18,12 +18,12 @@ class LocalDateJacksonModule : SimpleModule() { } } -class LocalDateSerializer : JsonSerializer() { - override fun serialize(value: LocalDate, gen: JsonGenerator, serializers: SerializerProvider) { +class LocalDateSerializer : ValueSerializer() { + override fun serialize(value: LocalDate, gen: JsonGenerator, ctxt: SerializationContext) { gen.writeString(value.toString()) } } -class LocalDateDeserializer : JsonDeserializer() { - override fun deserialize(p: JsonParser, ctxt: DeserializationContext): LocalDate = LocalDate.parse(p.text) +class LocalDateDeserializer : ValueDeserializer() { + override fun deserialize(p: JsonParser, ctxt: DeserializationContext): LocalDate = LocalDate.parse(p.string) } diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index 1ce6999fef..1d1b24073a 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -12,6 +12,11 @@ spring.servlet.multipart.max-file-size=5000MB spring.servlet.multipart.max-request-size=5000MB spring.mvc.async.request-timeout=36000000 +# Avoid warning: "Sharing is only supported for boot loader classes because bootstrap classpath has been appended" +# See e.g. https://gradle.com/gradle/issues/19989 +org.gradle.jvmargs=-Xshare:off + + server.compression.enabled=true spring.datasource.driverClassName=org.postgresql.Driver @@ -38,3 +43,4 @@ loculus.s3.bucket.bucket= loculus.s3.bucket.region= loculus.s3.bucket.access-key= loculus.s3.bucket.secret-key= + diff --git a/backend/src/test/kotlin/org/loculus/backend/SwaggerUiTest.kt b/backend/src/test/kotlin/org/loculus/backend/SwaggerUiTest.kt index 155269a2c1..5d6d0bd9b3 100644 --- a/backend/src/test/kotlin/org/loculus/backend/SwaggerUiTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/SwaggerUiTest.kt @@ -1,18 +1,19 @@ package org.loculus.backend -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory -import com.fasterxml.jackson.module.kotlin.registerKotlinModule import org.hamcrest.core.StringContains.containsString import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import tools.jackson.databind.ObjectMapper +import tools.jackson.dataformat.yaml.YAMLFactory +import tools.jackson.dataformat.yaml.YAMLMapper +import tools.jackson.module.kotlin.KotlinModule @SpringBootTestWithoutDatabase @AutoConfigureMockMvc @@ -42,7 +43,9 @@ class SwaggerUiTest(@Autowired val mockMvc: MockMvc) { .andExpect(content().contentType("application/vnd.oai.openapi")) .andReturn() - val objectMapper = ObjectMapper(YAMLFactory()).registerKotlinModule() + val objectMapper = YAMLMapper.builder(YAMLFactory()) + .addModule(KotlinModule.Builder().build()) + .build() val yaml = objectMapper.readTree(result.response.contentAsString) assertTrue(yaml.has("openapi")) assertTrue(yaml.get("paths").has("/{organism}/submit")) diff --git a/backend/src/test/kotlin/org/loculus/backend/api/DataUseTermsTest.kt b/backend/src/test/kotlin/org/loculus/backend/api/DataUseTermsTest.kt index af4bbeacf8..0b3aa4c81a 100644 --- a/backend/src/test/kotlin/org/loculus/backend/api/DataUseTermsTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/api/DataUseTermsTest.kt @@ -1,7 +1,5 @@ package org.loculus.backend.api -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue import kotlinx.datetime.LocalDate import org.hamcrest.CoreMatchers.equalTo import org.hamcrest.CoreMatchers.`is` @@ -9,6 +7,8 @@ import org.hamcrest.MatcherAssert.assertThat import org.junit.jupiter.api.Test import org.loculus.backend.SpringBootTestWithoutDatabase import org.springframework.beans.factory.annotation.Autowired +import tools.jackson.databind.ObjectMapper +import tools.jackson.module.kotlin.readValue @SpringBootTestWithoutDatabase class DataUseTermsTest(@Autowired private val objectMapper: ObjectMapper) { diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/EndpointTestExtension.kt b/backend/src/test/kotlin/org/loculus/backend/controller/EndpointTestExtension.kt index 93a0469cbb..4fb5b65469 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/EndpointTestExtension.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/EndpointTestExtension.kt @@ -31,8 +31,8 @@ import org.loculus.backend.service.submission.SEQUENCE_ENTRIES_TABLE_NAME import org.loculus.backend.service.submission.SEQUENCE_UPLOAD_AUX_TABLE_NAME import org.loculus.backend.service.submission.dbtables.CURRENT_PROCESSING_PIPELINE_TABLE_NAME import org.loculus.backend.testutil.TestEnvironment -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc import org.springframework.context.annotation.Import import org.springframework.core.annotation.AliasFor import org.springframework.test.annotation.DirtiesContext diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/ExceptionHandlerTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/ExceptionHandlerTest.kt index d8b9a519e8..c8c4608bd2 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/ExceptionHandlerTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/ExceptionHandlerTest.kt @@ -12,7 +12,7 @@ import org.loculus.backend.api.DataUseTermsType import org.loculus.backend.api.SubmissionIdMapping import org.loculus.backend.model.SubmitModel import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc import org.springframework.http.MediaType import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder @@ -25,7 +25,7 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status private val validRoute = addOrganismToPath("submit") -private val validRequest: MockHttpServletRequestBuilder = multipart(validRoute) +private val validRequest = multipart(validRoute) .file("sequenceFile", "sequences".toByteArray()) .file("metadataFile", "metadata".toByteArray()) .param("groupId", "5") @@ -80,7 +80,7 @@ class ExceptionHandlerTest(@Autowired val mockMvc: MockMvc) { every { validControllerCall() } throws UnprocessableEntityException("SomeMessage") mockMvc.perform(validRequest) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect(jsonPath("$.title").value("Unprocessable Entity")) .andExpect(jsonPath("$.detail").value("SomeMessage")) @@ -91,7 +91,7 @@ class ExceptionHandlerTest(@Autowired val mockMvc: MockMvc) { every { validControllerCall() } throws ProcessingValidationException("SomeMessage") mockMvc.perform(validRequest) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect(jsonPath("$.title").value("Unprocessable Entity")) .andExpect(jsonPath("$.detail").value("SomeMessage")) diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/RequestAuthorization.kt b/backend/src/test/kotlin/org/loculus/backend/controller/RequestAuthorization.kt index 0d6d28429f..5d5a7dd84f 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/RequestAuthorization.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/RequestAuthorization.kt @@ -4,6 +4,7 @@ import io.jsonwebtoken.Jwts import org.loculus.backend.auth.Roles.EXTERNAL_METADATA_UPDATER import org.loculus.backend.auth.Roles.PREPROCESSING_PIPELINE import org.loculus.backend.auth.Roles.SUPER_USER +import org.springframework.test.web.servlet.request.AbstractMockHttpServletRequestBuilder import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder import java.security.KeyPair import java.time.Instant @@ -27,8 +28,6 @@ fun generateJwtFor(username: String, roles: List = emptyList()): String .claim("realm_access", mapOf("roles" to roles)) .compact() -fun MockHttpServletRequestBuilder.withAuth(bearerToken: String? = jwtForDefaultUser): MockHttpServletRequestBuilder = - when (bearerToken) { - null -> this - else -> this.header("Authorization", "Bearer $bearerToken") - } +// Generic extension function that works with all MockMvc request builder types +fun > T.withAuth(bearerToken: String? = jwtForDefaultUser): T = + apply { if (bearerToken != null) header("Authorization", "Bearer $bearerToken") } diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/TestHelpers.kt b/backend/src/test/kotlin/org/loculus/backend/controller/TestHelpers.kt index f0216ef59c..a02cb1d667 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/TestHelpers.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/TestHelpers.kt @@ -1,8 +1,5 @@ package org.loculus.backend.controller -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue import kotlinx.datetime.DateTimeUnit.Companion.MONTH import kotlinx.datetime.plus import kotlinx.datetime.toLocalDateTime @@ -27,6 +24,11 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import org.testcontainers.shaded.org.awaitility.Awaitility.await +import tools.jackson.databind.DeserializationFeature +import tools.jackson.databind.ObjectMapper +import tools.jackson.databind.json.JsonMapper +import tools.jackson.module.kotlin.KotlinModule +import tools.jackson.module.kotlin.readValue import kotlin.time.Clock const val DEFAULT_ORGANISM = "dummyOrganism" @@ -64,7 +66,16 @@ fun jsonContainsAccessionVersionsInAnyOrder(expectedVersions: List ResultActions.expectNdjsonAndGetContent(): List { andExpect(status().isOk) diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/datauseterms/DataUseTermsControllerClient.kt b/backend/src/test/kotlin/org/loculus/backend/controller/datauseterms/DataUseTermsControllerClient.kt index bf0b6b4241..72a7157d5c 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/datauseterms/DataUseTermsControllerClient.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/datauseterms/DataUseTermsControllerClient.kt @@ -1,6 +1,5 @@ package org.loculus.backend.controller.datauseterms -import com.fasterxml.jackson.databind.ObjectMapper import org.loculus.backend.api.DataUseTerms import org.loculus.backend.api.DataUseTermsChangeRequest import org.loculus.backend.controller.jwtForDefaultUser @@ -11,6 +10,7 @@ import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.ResultActions import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put +import tools.jackson.databind.ObjectMapper val DEFAULT_DATA_USE_CHANGE_REQUEST = DataUseTermsChangeRequest( accessions = listOf("1", "2"), diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/datauseterms/DataUseTermsControllerTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/datauseterms/DataUseTermsControllerTest.kt index 30cd036888..19726c38d7 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/datauseterms/DataUseTermsControllerTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/datauseterms/DataUseTermsControllerTest.kt @@ -94,7 +94,7 @@ class DataUseTermsControllerTest( @Test fun `GIVEN non-existing accessions WHEN setting new data use terms THEN return unprocessable entity`() { client.changeDataUseTerms(DEFAULT_DATA_USE_CHANGE_REQUEST) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail", containsString("Accessions 1, 2 do not exist")), @@ -199,7 +199,7 @@ class DataUseTermsControllerTest( DataUseTermsTestCase( setupDataUseTerms = DataUseTerms.Open, newDataUseTerms = DataUseTerms.Open, - expectedStatus = status().isUnprocessableEntity, + expectedStatus = status().isUnprocessableContent, expectedContentType = MediaType.APPLICATION_PROBLEM_JSON_VALUE, expectedDetailContains = "The data use terms have already been set to 'Open'", ), @@ -213,7 +213,7 @@ class DataUseTermsControllerTest( DataUseTermsTestCase( setupDataUseTerms = DataUseTerms.Open, newDataUseTerms = DataUseTerms.Restricted(dateMonthsFromNow(6)), - expectedStatus = status().isUnprocessableEntity, + expectedStatus = status().isUnprocessableContent, expectedContentType = MediaType.APPLICATION_PROBLEM_JSON_VALUE, expectedDetailContains = "Cannot change data use terms from OPEN to RESTRICTED.", ), @@ -228,7 +228,7 @@ class DataUseTermsControllerTest( DataUseTermsTestCase( setupDataUseTerms = DataUseTerms.Restricted(dateMonthsFromNow(6)), newDataUseTerms = DataUseTerms.Restricted(dateMonthsFromNow(7)), - expectedStatus = status().isUnprocessableEntity, + expectedStatus = status().isUnprocessableContent, expectedContentType = MediaType.APPLICATION_PROBLEM_JSON_VALUE, expectedDetailContains = "Cannot extend restricted data use period. " + "Please choose a date before ${dateMonthsFromNow(6)}.", diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/debug/DeleteAllSequenceDataEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/debug/DeleteAllSequenceDataEndpointTest.kt index b39aa9dacb..f8d1b5a154 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/debug/DeleteAllSequenceDataEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/debug/DeleteAllSequenceDataEndpointTest.kt @@ -135,7 +135,7 @@ class DeleteAllSequenceDataEndpointTest( useNewerProcessingPipelineVersionTask.task() submissionControllerClient.extractUnprocessedData(numberOfSequenceEntries = 1, pipelineVersion = 1) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) deleteAllSequences(jwtForSuperUser) .andExpect(status().isNoContent) @@ -170,14 +170,14 @@ class DeleteAllSequenceDataEndpointTest( fun `GIVEN I deleted all sequences WHEN submitting again THEN new sequences are present`() { submissionConvenienceClient.prepareDataTo(Status.APPROVED_FOR_RELEASE) val accessionsBeforeDeletion = submissionConvenienceClient.getReleasedData() - .map { it.metadata["accession"]?.textValue() } + .map { it.metadata["accession"]?.stringValue() } deleteAllSequences(jwtForSuperUser) .andExpect(status().isNoContent) val firstNewAccession = submissionConvenienceClient.prepareDataTo(Status.APPROVED_FOR_RELEASE).first().accession val accessionsAfterDeletion = submissionConvenienceClient.getReleasedData() - .map { it.metadata["accession"]?.textValue() } + .map { it.metadata["accession"]?.stringValue() } assertThat(accessionsAfterDeletion, hasSize(NUMBER_OF_SEQUENCES)) assertThat(accessionsAfterDeletion, hasItem(firstNewAccession)) assertThat(accessionsAfterDeletion, not(hasItem(accessionsBeforeDeletion.first()))) diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/files/CompleteMultipartUploadEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/files/CompleteMultipartUploadEndpointTest.kt index befb4f00ff..19178f7dfd 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/files/CompleteMultipartUploadEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/files/CompleteMultipartUploadEndpointTest.kt @@ -60,7 +60,7 @@ class CompleteMultipartUploadEndpointTest( .andGetFileIdsAndMultipartUrls()[0] filesClient.completeMultipartUploads(listOf(FileIdAndEtags(fileIdAndUrls.fileId, emptyList()))) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().string(containsString("No etags provided"))) } @@ -75,7 +75,7 @@ class CompleteMultipartUploadEndpointTest( val wrongEtag2 = (if (etag2[0] != 'a') 'a' else 'b') + etag2.substring(1) filesClient.completeMultipartUploads(listOf(FileIdAndEtags(fileIdAndUrls.fileId, listOf(etag1, wrongEtag2)))) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().string(containsString("InvalidPart"))) } @@ -89,7 +89,7 @@ class CompleteMultipartUploadEndpointTest( .headers().map()["etag"]!![0] filesClient.completeMultipartUploads(listOf(FileIdAndEtags(fileIdAndUrls.fileId, listOf(etag1, etag2)))) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().string(containsString("EntityTooSmall"))) } } diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/files/FilesClient.kt b/backend/src/test/kotlin/org/loculus/backend/controller/files/FilesClient.kt index b23a3a4806..71ef380053 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/files/FilesClient.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/files/FilesClient.kt @@ -1,6 +1,5 @@ package org.loculus.backend.controller.files -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import org.loculus.backend.api.FileCategory import org.loculus.backend.api.FileIdAndEtags import org.loculus.backend.api.FileIdAndMultipartWriteUrl @@ -50,7 +49,7 @@ class FilesClient(private val mockMvc: MockMvc) { val request = post("/files/complete-multipart-upload") .withAuth(jwt) .contentType(MediaType.APPLICATION_JSON) - fileIdAndEtags?.let { request.content(jacksonObjectMapper().writeValueAsString(it)) } + fileIdAndEtags?.let { request.content(jacksonObjectMapper.writeValueAsString(it)) } return mockMvc.perform(request) } @@ -94,26 +93,28 @@ fun ResultActions.andGetFileIds(): List = andReturn() .response .contentAsString .let { - val responseJson = jacksonObjectMapper().readTree(it) - responseJson.map { UUID.fromString(it.get("fileId").textValue()) } + val responseJson = jacksonObjectMapper.readTree(it) + responseJson.map { UUID.fromString(it.get("fileId").stringValue()) } } fun ResultActions.andGetFileIdsAndUrls(): List = andReturn() .response .contentAsString .let { - val responseJson = jacksonObjectMapper().readTree(it) - responseJson.map { FileIdAndWriteUrl(UUID.fromString(it.get("fileId").textValue()), it.get("url").textValue()) } + val responseJson = jacksonObjectMapper.readTree(it) + responseJson.map { + FileIdAndWriteUrl(UUID.fromString(it.get("fileId").stringValue()), it.get("url").stringValue()) + } } fun ResultActions.andGetFileIdsAndMultipartUrls(): List = andReturn() .response .contentAsString .let { body -> - val root = jacksonObjectMapper().readTree(body) + val root = jacksonObjectMapper.readTree(body) root.map { node -> - val fileId = UUID.fromString(node.get("fileId").textValue()) - val urls = node.get("urls").map { it.textValue() } + val fileId = UUID.fromString(node.get("fileId").stringValue()) + val urls = node.get("urls").map { it.stringValue() } FileIdAndMultipartWriteUrl(fileId, urls) } } diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/files/RequestMultipartUploadEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/files/RequestMultipartUploadEndpointTest.kt index db76f8af45..999b438973 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/files/RequestMultipartUploadEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/files/RequestMultipartUploadEndpointTest.kt @@ -1,6 +1,5 @@ package org.loculus.backend.controller.files -import com.fasterxml.jackson.databind.ObjectMapper import org.apache.http.client.methods.HttpPut import org.apache.http.entity.ByteArrayEntity import org.apache.http.entity.ContentType @@ -17,6 +16,7 @@ import org.loculus.backend.controller.jwtForAlternativeUser import org.loculus.backend.controller.jwtForProcessingPipeline import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import tools.jackson.databind.ObjectMapper @EndpointTest( properties = ["${BackendSpringProperty.BACKEND_CONFIG_PATH}=$S3_CONFIG"], @@ -82,7 +82,7 @@ class RequestMultipartUploadEndpointTest( val httpClient = HttpClients.createDefault() urls.forEach { urlNode -> - val put = HttpPut(urlNode.textValue()).apply { + val put = HttpPut(urlNode.stringValue()).apply { entity = ByteArrayEntity(partContent, ContentType.APPLICATION_OCTET_STREAM) } val response = httpClient.execute(put) diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/files/RequestUploadEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/files/RequestUploadEndpointTest.kt index ff795c4c76..f9e2f21c5c 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/files/RequestUploadEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/files/RequestUploadEndpointTest.kt @@ -1,6 +1,5 @@ package org.loculus.backend.controller.files -import com.fasterxml.jackson.databind.ObjectMapper import org.apache.http.client.methods.HttpPut import org.apache.http.entity.ByteArrayEntity import org.apache.http.entity.ContentType @@ -24,6 +23,7 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content import org.springframework.test.web.servlet.result.MockMvcResultMatchers.header import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import tools.jackson.databind.ObjectMapper @EndpointTest( properties = ["${BackendSpringProperty.BACKEND_CONFIG_PATH}=$S3_CONFIG"], @@ -77,7 +77,7 @@ class RequestUploadEndpointTest( val url = objectMapper.readTree(responseContent) .get(0) .get("url") - .textValue() + .stringValue() val content = "test content".toByteArray() val request = HttpPut(url) diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/groupmanagement/GroupManagementControllerClient.kt b/backend/src/test/kotlin/org/loculus/backend/controller/groupmanagement/GroupManagementControllerClient.kt index d8d9f58a33..ff25e30469 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/groupmanagement/GroupManagementControllerClient.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/groupmanagement/GroupManagementControllerClient.kt @@ -1,6 +1,5 @@ package org.loculus.backend.controller.groupmanagement -import com.fasterxml.jackson.databind.ObjectMapper import com.jayway.jsonpath.JsonPath import org.loculus.backend.api.Address import org.loculus.backend.api.NewGroup @@ -16,6 +15,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import tools.jackson.databind.ObjectMapper const val NEW_GROUP_NAME = "newGroup" val NEW_GROUP = NewGroup( diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/seqsetcitations/SeqSetEndpointsTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/seqsetcitations/SeqSetEndpointsTest.kt index 30952a1372..f12e265979 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/seqsetcitations/SeqSetEndpointsTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/seqsetcitations/SeqSetEndpointsTest.kt @@ -166,7 +166,7 @@ class SeqSetEndpointsTest(@Autowired private val client: SeqSetCitationsControll .andExpect(status().isOk) client.deleteSeqSet(seqSetId, 1) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/seqsetcitations/SeqSetValidationEndpointsTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/seqsetcitations/SeqSetValidationEndpointsTest.kt index 89cf2165f3..7e0985cc20 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/seqsetcitations/SeqSetValidationEndpointsTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/seqsetcitations/SeqSetValidationEndpointsTest.kt @@ -36,7 +36,7 @@ class SeqSetValidationEndpointsTest( fun `WHEN calling validate seqSet records with non-existing accessions THEN returns unprocessable entity`() { val accessionJson = """[{"accession": "ABCD", "type": "loculus"}]""" client.validateSeqSetRecords(seqSetRecords = accessionJson) - .andExpect(status().isUnprocessableEntity()) + .andExpect(status().isUnprocessableContent()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -47,7 +47,7 @@ class SeqSetValidationEndpointsTest( val accessionVersionJson = """[{"accession": "ABCD.1", "type": "loculus"}]""" client.validateSeqSetRecords(seqSetRecords = accessionVersionJson) - .andExpect(status().isUnprocessableEntity()) + .andExpect(status().isUnprocessableContent()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -61,7 +61,7 @@ class SeqSetValidationEndpointsTest( fun `WHEN calling validate seqSet records with invalid status accessions THEN returns unprocessable entity`() { val accessionJson = """[{"accession": "ABCD.EF", "type": "loculus"}]""" client.validateSeqSetRecords(seqSetRecords = accessionJson) - .andExpect(status().isUnprocessableEntity()) + .andExpect(status().isUnprocessableContent()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -80,7 +80,7 @@ class SeqSetValidationEndpointsTest( val accessionJson = """[{"accession": "$invalidAccession", "type": "loculus"}]""" client.validateSeqSetRecords(seqSetRecords = accessionJson) - .andExpect(status().isUnprocessableEntity()) + .andExpect(status().isUnprocessableContent()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -101,7 +101,7 @@ class SeqSetValidationEndpointsTest( {"accession": "$validAccession", "type": "loculus"} ]""" client.validateSeqSetRecords(seqSetRecords = accessionJson) - .andExpect(status().isUnprocessableEntity()) + .andExpect(status().isUnprocessableContent()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -123,7 +123,7 @@ class SeqSetValidationEndpointsTest( @Test fun `WHEN writing seqSet with missing name THEN returns unprocessable entity`() { client.createSeqSet(seqSetName = "") - .andExpect(status().isUnprocessableEntity()) + .andExpect(status().isUnprocessableContent()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -132,7 +132,7 @@ class SeqSetValidationEndpointsTest( ), ) client.updateSeqSet(seqSetName = "") - .andExpect(status().isUnprocessableEntity()) + .andExpect(status().isUnprocessableContent()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -153,7 +153,7 @@ class SeqSetValidationEndpointsTest( val seqSetId = JsonPath.read(seqSetResult.response.contentAsString, "$.seqSetId") client.updateSeqSet(seqSetId = seqSetId, seqSetRecords = accessionJson) - .andExpect(status().isUnprocessableEntity()) + .andExpect(status().isUnprocessableContent()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -166,7 +166,7 @@ class SeqSetValidationEndpointsTest( @Test fun `WHEN writing seqSet with missing records THEN returns unprocessable entity`() { client.createSeqSet(seqSetRecords = "[]") - .andExpect(status().isUnprocessableEntity()) + .andExpect(status().isUnprocessableContent()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -175,7 +175,7 @@ class SeqSetValidationEndpointsTest( ), ) client.updateSeqSet(seqSetRecords = "[]") - .andExpect(status().isUnprocessableEntity()) + .andExpect(status().isUnprocessableContent()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -203,7 +203,7 @@ class SeqSetValidationEndpointsTest( createSeqSetWithDOI(accessionJson) } createSeqSetWithDOI(accessionJson) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/ApproveProcessedDataEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/ApproveProcessedDataEndpointTest.kt index 94575ba741..2f0a3111b2 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/ApproveProcessedDataEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/ApproveProcessedDataEndpointTest.kt @@ -1,6 +1,5 @@ package org.loculus.backend.controller.submission -import com.fasterxml.jackson.databind.ObjectMapper import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.containsString import org.hamcrest.Matchers.hasSize @@ -34,6 +33,7 @@ import org.springframework.http.MediaType import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import tools.jackson.databind.ObjectMapper import java.net.URI import java.net.http.HttpClient import java.net.http.HttpRequest @@ -138,7 +138,7 @@ class ApproveProcessedDataEndpointTest( AccessionVersion(nonExistentAccession, 1), ), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect(jsonPath("$.detail", containsString("Accession versions $nonExistentAccession.1 do not exist"))) @@ -158,7 +158,7 @@ class ApproveProcessedDataEndpointTest( nonExistingVersion, ), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -188,7 +188,7 @@ class ApproveProcessedDataEndpointTest( scope = ALL, accessionVersionsInCorrectState + accessionVersionNotInCorrectState, ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -219,7 +219,7 @@ class ApproveProcessedDataEndpointTest( defaultOrganismData.getAccessionVersions() + otherOrganismData.getAccessionVersions(), organism = OTHER_ORGANISM, ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("$.detail") @@ -349,7 +349,7 @@ class ApproveProcessedDataEndpointTest( scope = WITHOUT_WARNINGS, accessionVersionsFilter = listOf(AccessionVersion(accessionOfDataWithErrors, 1)), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) convenienceClient.getSequenceEntry(accession = accessionOfDataWithErrors, version = 1) .assertStatusIs(PROCESSED) @@ -437,9 +437,9 @@ class ApproveProcessedDataEndpointTest( client.approveProcessedSequenceEntries(ALL) val releasedData = convenienceClient.getReleasedData() - val tree = objectMapper.readTree(releasedData[0].metadata["myFileCategory"]!!.asText()) + val tree = objectMapper.readTree(releasedData[0].metadata["myFileCategory"]!!.asString()) - val fileUrl = tree.get(0).get("url").asText() + val fileUrl = tree.get(0).get("url").asString() val client = HttpClient.newHttpClient() val request = HttpRequest.newBuilder() diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/DeleteSequencesEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/DeleteSequencesEndpointTest.kt index 027df599a0..970f29b943 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/DeleteSequencesEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/DeleteSequencesEndpointTest.kt @@ -110,7 +110,7 @@ class DeleteSequencesEndpointTest( accessionVersionsToDelete.sortedWith(AccessionVersionComparator).joinToString(", ") { "${it.accession}.${it.version} - ${it.status}" } - deletionResult.andExpect(status().isUnprocessableEntity) + deletionResult.andExpect(status().isUnprocessableContent) .andExpect( content().contentType(MediaType.APPLICATION_PROBLEM_JSON), ) @@ -136,7 +136,7 @@ class DeleteSequencesEndpointTest( scope = ALL, accessionVersionsFilter = listOf(nonExistingAccession, nonExistingVersion), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -257,7 +257,7 @@ class DeleteSequencesEndpointTest( accessionVersionsFilter = listOf(accessionVersion.toAccessionVersion()), organism = OTHER_ORGANISM, ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail", containsString("accession versions are not of organism $OTHER_ORGANISM:")), diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetDataToEditEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetDataToEditEndpointTest.kt index 61e6d48244..104a8bd601 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetDataToEditEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetDataToEditEndpointTest.kt @@ -62,7 +62,7 @@ class GetDataToEditEndpointTest( val nonExistentAccession = "DefinitelyNotExisting" client.getSequenceEntryToEdit(nonExistentAccession, 1) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail").value( @@ -82,7 +82,7 @@ class GetDataToEditEndpointTest( client.getSequenceEntryToEdit(firstAccession, 1, organism = DEFAULT_ORGANISM) .andExpect(status().isOk) client.getSequenceEntryToEdit(firstAccession, 1, organism = OTHER_ORGANISM) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail").value( @@ -100,7 +100,7 @@ class GetDataToEditEndpointTest( convenienceClient.prepareDataTo(Status.PROCESSED, errors = true) client.getSequenceEntryToEdit("1", nonExistentAccessionVersion) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail").value( @@ -151,7 +151,7 @@ class GetDataToEditEndpointTest( .first() client.getSequenceEntryToEdit(accessionVersion.accession, accessionVersion.version) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(jsonPath("\$.detail", containsString("is a revocation"))) } } diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetOriginalMetadataEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetOriginalMetadataEndpointTest.kt index 7a17c147b2..500b46e5bb 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetOriginalMetadataEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetOriginalMetadataEndpointTest.kt @@ -1,6 +1,5 @@ package org.loculus.backend.controller.submission -import com.fasterxml.jackson.module.kotlin.readValue import com.github.luben.zstd.ZstdInputStream import io.mockk.every import io.mockk.mockk @@ -34,6 +33,7 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content import org.springframework.test.web.servlet.result.MockMvcResultMatchers.header import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import org.testcontainers.shaded.org.awaitility.Awaitility.await +import tools.jackson.module.kotlin.readValue @EndpointTest class GetOriginalMetadataEndpointTest( diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetReleasedDataDataUseTermsDisabledEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetReleasedDataDataUseTermsDisabledEndpointTest.kt index 3615f42a2b..240e86f876 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetReleasedDataDataUseTermsDisabledEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetReleasedDataDataUseTermsDisabledEndpointTest.kt @@ -1,8 +1,5 @@ package org.loculus.backend.controller.submission -import com.fasterxml.jackson.databind.node.BooleanNode -import com.fasterxml.jackson.databind.node.IntNode -import com.fasterxml.jackson.databind.node.TextNode import com.ninjasquad.springmockk.MockkBean import io.mockk.every import kotlinx.datetime.toLocalDateTime @@ -35,6 +32,9 @@ import org.loculus.backend.utils.DateProvider import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.web.servlet.result.MockMvcResultMatchers.header import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import tools.jackson.databind.node.BooleanNode +import tools.jackson.databind.node.IntNode +import tools.jackson.databind.node.StringNode import kotlin.time.Clock @EndpointTest( @@ -102,36 +102,36 @@ class GetReleasedDataDataUseTermsDisabledEndpointTest( response.andExpect(header().string("x-total-records", NUMBER_OF_SEQUENCES.toString())) responseBody.forEach { - val id = it.metadata["accession"]!!.asText() + val id = it.metadata["accession"]!!.asString() val version = it.metadata["version"]!!.asLong() assertThat(version, `is`(1)) val expectedMetadata = defaultProcessedData.metadata + mapOf( - "accession" to TextNode(id), + "accession" to StringNode(id), "version" to IntNode(version.toInt()), - "accessionVersion" to TextNode("$id.$version"), + "accessionVersion" to StringNode("$id.$version"), "isRevocation" to BooleanNode.FALSE, - "submitter" to TextNode(DEFAULT_USER_NAME), - "groupName" to TextNode(DEFAULT_GROUP_NAME_CHANGED), - "versionStatus" to TextNode("LATEST_VERSION"), - "releasedDate" to TextNode(currentDate), - "submittedDate" to TextNode(currentDate), + "submitter" to StringNode(DEFAULT_USER_NAME), + "groupName" to StringNode(DEFAULT_GROUP_NAME_CHANGED), + "versionStatus" to StringNode("LATEST_VERSION"), + "releasedDate" to StringNode(currentDate), + "submittedDate" to StringNode(currentDate), "pipelineVersion" to IntNode(DEFAULT_PIPELINE_VERSION.toInt()), ) for ((key, value) in it.metadata) { when (key) { - "submittedAtTimestamp" -> expectIsTimestampWithCurrentYear(value) + "submittedAtTimestamp" -> expectIsTimestampWithCurrentYear(value!!) - "releasedAtTimestamp" -> expectIsTimestampWithCurrentYear(value) + "releasedAtTimestamp" -> expectIsTimestampWithCurrentYear(value!!) - "submissionId" -> assertThat(value.textValue(), matchesPattern("^custom\\d$")) + "submissionId" -> assertThat(value!!.stringValue(), matchesPattern("^custom\\d$")) - "groupId" -> assertThat(value.intValue(), `is`(groupId)) + "groupId" -> assertThat(value!!.intValue(), `is`(groupId)) else -> { assertThat(expectedMetadata.keys, hasItem(key)) - assertThat(value, `is`(expectedMetadata[key])) + assertThat(value!!, `is`(expectedMetadata[key])) } } } diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetReleasedDataEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetReleasedDataEndpointTest.kt index 17a8f7ef2e..c06a7b6d18 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetReleasedDataEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetReleasedDataEndpointTest.kt @@ -1,12 +1,5 @@ package org.loculus.backend.controller.submission -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.node.BooleanNode -import com.fasterxml.jackson.databind.node.IntNode -import com.fasterxml.jackson.databind.node.NullNode -import com.fasterxml.jackson.databind.node.TextNode -import com.fasterxml.jackson.module.kotlin.readValue import com.github.luben.zstd.ZstdInputStream import com.ninjasquad.springmockk.MockkBean import io.mockk.every @@ -83,6 +76,13 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content import org.springframework.test.web.servlet.result.MockMvcResultMatchers.header import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import org.testcontainers.shaded.org.awaitility.Awaitility.await +import tools.jackson.databind.JsonNode +import tools.jackson.databind.ObjectMapper +import tools.jackson.databind.node.BooleanNode +import tools.jackson.databind.node.IntNode +import tools.jackson.databind.node.NullNode +import tools.jackson.databind.node.StringNode +import tools.jackson.module.kotlin.readValue import kotlin.time.Clock import kotlin.time.Instant @@ -159,32 +159,32 @@ class GetReleasedDataEndpointTest( response.andExpect(header().string("x-total-records", NUMBER_OF_SEQUENCES.toString())) responseBody.forEach { - val id = it.metadata["accession"]!!.asText() + val id = it.metadata["accession"]!!.asString() val version = it.metadata["version"]!!.asLong() assertThat(version, `is`(1)) val expectedMetadata = defaultProcessedData.metadata + mapOf( - "accession" to TextNode(id), + "accession" to StringNode(id), "version" to IntNode(version.toInt()), - "accessionVersion" to TextNode("$id.$version"), + "accessionVersion" to StringNode("$id.$version"), "isRevocation" to BooleanNode.FALSE, - "submitter" to TextNode(DEFAULT_USER_NAME), - "groupName" to TextNode(DEFAULT_GROUP_NAME_CHANGED), - "versionStatus" to TextNode("LATEST_VERSION"), - "dataUseTerms" to TextNode("OPEN"), - "releasedDate" to TextNode(currentDate), - "submittedDate" to TextNode(currentDate), + "submitter" to StringNode(DEFAULT_USER_NAME), + "groupName" to StringNode(DEFAULT_GROUP_NAME_CHANGED), + "versionStatus" to StringNode("LATEST_VERSION"), + "dataUseTerms" to StringNode("OPEN"), + "releasedDate" to StringNode(currentDate), + "submittedDate" to StringNode(currentDate), "dataUseTermsRestrictedUntil" to NullNode.getInstance(), "pipelineVersion" to IntNode(DEFAULT_PIPELINE_VERSION.toInt()), ) for ((key, value) in it.metadata) { when (key) { - "submittedAtTimestamp" -> expectIsTimestampWithCurrentYear(value) - "releasedAtTimestamp" -> expectIsTimestampWithCurrentYear(value) - "submissionId" -> assertThat(value.textValue(), matchesPattern("^custom\\d$")) - "groupId" -> assertThat(value.intValue(), `is`(groupId)) - else -> assertThat(value, `is`(expectedMetadata[key])) + "submittedAtTimestamp" -> expectIsTimestampWithCurrentYear(value!!) + "releasedAtTimestamp" -> expectIsTimestampWithCurrentYear(value!!) + "submissionId" -> assertThat(value!!.stringValue(), matchesPattern("^custom\\d$")) + "groupId" -> assertThat(value!!.intValue(), `is`(groupId)) + else -> assertThat(value!!, `is`(expectedMetadata[key])) } } assertThat(it.alignedNucleotideSequences, `is`(defaultProcessedData.alignedNucleotideSequences)) @@ -221,7 +221,7 @@ class GetReleasedDataEndpointTest( responseAfterMoreDataAdded.andExpect(status().isOk) .andExpect(header().string(ETAG, notNullValue())) - .andExpect(header().string(ETAG, greaterThan(initialEtag))) + .andExpect(header().string(ETAG, greaterThan(initialEtag!!))) val responseBodyMoreData = responseAfterMoreDataAdded .expectNdjsonAndGetContent() @@ -319,29 +319,29 @@ class GetReleasedDataEndpointTest( when (key) { "isRevocation" -> assertThat(value, `is`(BooleanNode.TRUE)) - "versionStatus" -> assertThat(value, `is`(TextNode("LATEST_VERSION"))) + "versionStatus" -> assertThat(value, `is`(StringNode("LATEST_VERSION"))) - "submittedAtTimestamp" -> expectIsTimestampWithCurrentYear(value) + "submittedAtTimestamp" -> expectIsTimestampWithCurrentYear(value!!) - "releasedAtTimestamp" -> expectIsTimestampWithCurrentYear(value) + "releasedAtTimestamp" -> expectIsTimestampWithCurrentYear(value!!) - "submitter" -> assertThat(value, `is`(TextNode(DEFAULT_USER_NAME))) + "submitter" -> assertThat(value, `is`(StringNode(DEFAULT_USER_NAME))) - "groupName" -> assertThat(value, `is`(TextNode(DEFAULT_GROUP_NAME))) + "groupName" -> assertThat(value, `is`(StringNode(DEFAULT_GROUP_NAME))) - "groupId" -> assertThat(value.intValue(), `is`(greaterThan(0))) + "groupId" -> assertThat(value!!.intValue(), `is`(greaterThan(0))) "accession", "version", "accessionVersion", "submissionId" -> {} - "dataUseTerms" -> assertThat(value, `is`(TextNode("OPEN"))) + "dataUseTerms" -> assertThat(value, `is`(StringNode("OPEN"))) - "submittedDate" -> assertThat(value, `is`(TextNode(currentDate))) + "submittedDate" -> assertThat(value, `is`(StringNode(currentDate))) - "releasedDate" -> assertThat(value, `is`(TextNode(currentDate))) + "releasedDate" -> assertThat(value, `is`(StringNode(currentDate))) "versionComment" -> assertThat( value, - `is`(TextNode("This is a test revocation")), + `is`(StringNode("This is a test revocation")), ) "pipelineVersion" -> assertThat(value, `is`(IntNode(DEFAULT_PIPELINE_VERSION.toInt()))) @@ -437,11 +437,11 @@ class GetReleasedDataEndpointTest( // assert that the accessions are sorted assertThat(data.size, Matchers.`is`(12)) - val actualAccessionOrder = data.map { it.metadata["accession"]!!.asText() } + val actualAccessionOrder = data.map { it.metadata["accession"]!!.asString() } assertThat(actualAccessionOrder, equalTo(actualAccessionOrder.sorted())) // assert that _within_ each accession block, it's sorted by version - val accessionChunks = data.groupBy { it.metadata["accession"]!!.asText() } + val accessionChunks = data.groupBy { it.metadata["accession"]!!.asString() } assertThat(accessionChunks.size, Matchers.`is`(accessions.size)) accessionChunks.values .map { chunk -> chunk.map { it.metadata["version"]!!.asLong() } } @@ -481,7 +481,6 @@ private const val RESTRICTED_DATA_USE_TERMS_URL = "restrictedUrl" @EndpointTest @Import(GetReleasedDataEndpointWithDataUseTermsUrlTestConfig::class) -@TestPropertySource(properties = ["spring.main.allow-bean-definition-overriding=true"]) class GetReleasedDataEndpointWithDataUseTermsUrlTest( @Autowired val convenienceClient: SubmissionConvenienceClient, @Autowired val dataUseTermsClient: DataUseTermsControllerClient, @@ -574,18 +573,18 @@ class GetReleasedDataEndpointWithDataUseTermsUrlTest( ) { val releasedData = submissionControllerClient.getReleasedData() .expectNdjsonAndGetContent() - .find { it.metadata["accessionVersion"]?.textValue() == accessionVersion.displayAccessionVersion() }!! + .find { it.metadata["accessionVersion"]?.stringValue() == accessionVersion.displayAccessionVersion() }!! - assertThat(releasedData.metadata["dataUseTerms"]?.textValue(), `is`(dataUseTerms)) + assertThat(releasedData.metadata["dataUseTerms"]!!.stringValue(), `is`(dataUseTerms)) when (restrictedUntilDate) { - null -> assertThat(releasedData.metadata["dataUseTermsRestrictedUntil"], `is`(NullNode.instance)) + null -> assertThat(releasedData.metadata["dataUseTermsRestrictedUntil"]!!, `is`(NullNode.instance)) else -> assertThat( - releasedData.metadata["dataUseTermsRestrictedUntil"]?.textValue(), + releasedData.metadata["dataUseTermsRestrictedUntil"]!!.stringValue(), `is`(restrictedUntilDate.toString()), ) } - assertThat(releasedData.metadata["dataUseTermsUrl"]?.textValue(), `is`(dataUseTermsUrl)) + assertThat(releasedData.metadata["dataUseTermsUrl"]!!.stringValue(), `is`(dataUseTermsUrl)) } @TestConfiguration @@ -620,10 +619,10 @@ class GetReleasedDataEndpointWithDataUseTermsUrlTest( private fun List.findAccessionVersionStatus(accession: Accession, version: Version): String { val processedData = - find { it.metadata["accession"]?.asText() == accession && it.metadata["version"]?.asLong() == version } + find { it.metadata["accession"]?.asString() == accession && it.metadata["version"]?.asLong() == version } ?: error("Could not find accession version $accession.$version") - return processedData.metadata["versionStatus"]!!.asText() + return processedData.metadata["versionStatus"]!!.asString() } data class PreparedVersions( diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetReleasedDataFileSharingEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetReleasedDataFileSharingEndpointTest.kt index d667f764e5..10dcf9b2d4 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetReleasedDataFileSharingEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/GetReleasedDataFileSharingEndpointTest.kt @@ -1,7 +1,5 @@ package org.loculus.backend.controller.submission -import com.fasterxml.jackson.databind.node.NullNode -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.containsString import org.hamcrest.Matchers.hasKey @@ -20,9 +18,11 @@ import org.loculus.backend.controller.files.FilesClient import org.loculus.backend.controller.files.andGetFileIdsAndUrls import org.loculus.backend.controller.groupmanagement.GroupManagementControllerClient import org.loculus.backend.controller.groupmanagement.andGetGroupId +import org.loculus.backend.controller.jacksonObjectMapper import org.loculus.backend.controller.jwtForDefaultUser import org.loculus.backend.service.submission.SubmissionDatabaseService import org.springframework.beans.factory.annotation.Autowired +import tools.jackson.databind.node.NullNode @EndpointTest( properties = ["${BackendSpringProperty.BACKEND_CONFIG_PATH}=$S3_CONFIG"], @@ -36,7 +36,7 @@ class GetReleasedDataFileSharingEndpointTest( @Autowired private val groupManagementClient: GroupManagementControllerClient, @Autowired private val filesClient: FilesClient, ) { - private val objectMapper = jacksonObjectMapper() + private val objectMapper = jacksonObjectMapper @Test fun `GIVEN processed data with files THEN return file information in metadata`() { @@ -73,13 +73,13 @@ class GetReleasedDataFileSharingEndpointTest( assertThat(responseBody, hasSize(accessionVersions.size)) for (entry in responseBody) { assertThat(entry.metadata, hasKey("myFileCategory")) - val myFileCategory = objectMapper.readTree(entry.metadata["myFileCategory"]!!.asText()).toList() + val myFileCategory = objectMapper.readTree(entry.metadata["myFileCategory"]!!.asString()).toList() assertThat(myFileCategory, hasSize(2)) fileIds.forEachIndexed { i, id -> val file = myFileCategory[i] - assertThat(file["fileId"].asText(), `is`(fileIds[i].toString())) - assertThat(file["name"].asText(), `is`("file$i.txt")) - assertThat(file["url"].asText(), containsString(fileIds[i].toString())) + assertThat(file["fileId"].asString(), `is`(fileIds[i].toString())) + assertThat(file["name"].asString(), `is`("file$i.txt")) + assertThat(file["url"].asString(), containsString(fileIds[i].toString())) } assertThat(entry.metadata, hasKey("myOtherFileCategory")) diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/PreparedExternalData.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/PreparedExternalData.kt index fd411d4704..41cc26e38c 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/PreparedExternalData.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/PreparedExternalData.kt @@ -1,15 +1,15 @@ package org.loculus.backend.controller.submission -import com.fasterxml.jackson.databind.node.TextNode import org.loculus.backend.api.ExternalSubmittedData import org.loculus.backend.utils.Accession +import tools.jackson.databind.node.StringNode val defaultExternalMetadata = ExternalSubmittedData( accession = "If a test result shows this, processed data was not prepared correctly.", version = 1, externalMetadata = mapOf( - "insdcAccessionFull" to TextNode("GENBANK1000.1"), + "insdcAccessionFull" to StringNode("GENBANK1000.1"), ), ) @@ -18,7 +18,7 @@ val otherExternalMetadata = accession = "If a test result shows this, processed data was not prepared correctly.", version = 1, externalMetadata = mapOf( - "other_db_accession" to TextNode("DB1.1"), + "other_db_accession" to StringNode("DB1.1"), ), ) diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/PreparedProcessedData.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/PreparedProcessedData.kt index 4eadafcf29..37eee0751a 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/PreparedProcessedData.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/PreparedProcessedData.kt @@ -1,10 +1,5 @@ package org.loculus.backend.controller.submission -import com.fasterxml.jackson.databind.node.BooleanNode -import com.fasterxml.jackson.databind.node.DoubleNode -import com.fasterxml.jackson.databind.node.IntNode -import com.fasterxml.jackson.databind.node.NullNode -import com.fasterxml.jackson.databind.node.TextNode import org.loculus.backend.api.FileCategoryFilesMap import org.loculus.backend.api.GeneName import org.loculus.backend.api.GeneticSequence @@ -18,6 +13,11 @@ import org.loculus.backend.api.SubmittedProcessedData import org.loculus.backend.controller.DUMMY_ORGANISM_MAIN_SEQUENCE import org.loculus.backend.utils.Accession import org.loculus.backend.utils.Version +import tools.jackson.databind.node.BooleanNode +import tools.jackson.databind.node.DoubleNode +import tools.jackson.databind.node.IntNode +import tools.jackson.databind.node.NullNode +import tools.jackson.databind.node.StringNode const val MAIN_SEGMENT = "main" const val SOME_LONG_GENE = "someLongGene" @@ -25,13 +25,13 @@ const val SOME_SHORT_GENE = "someShortGene" val defaultProcessedData = ProcessedData( metadata = mapOf( - "date" to TextNode("2002-12-15"), - "host" to TextNode("google.com"), - "region" to TextNode("Europe"), - "country" to TextNode("Spain"), + "date" to StringNode("2002-12-15"), + "host" to StringNode("google.com"), + "region" to StringNode("Europe"), + "country" to StringNode("Spain"), "age" to IntNode(42), "qc" to DoubleNode(0.987654321), - "pangoLineage" to TextNode("XBB.1.5"), + "pangoLineage" to StringNode("XBB.1.5"), "division" to NullNode.instance, "dateSubmitted" to NullNode.instance, "sex" to NullNode.instance, @@ -68,14 +68,14 @@ val defaultProcessedData = ProcessedData( val defaultProcessedDataMultiSegmented = ProcessedData( metadata = mapOf( - "date" to TextNode("2002-12-15"), - "host" to TextNode("google.com"), - "region" to TextNode("Europe"), - "country" to TextNode("Spain"), - "specialOtherField" to TextNode("specialOtherValue"), + "date" to StringNode("2002-12-15"), + "host" to StringNode("google.com"), + "region" to StringNode("Europe"), + "country" to StringNode("Spain"), + "specialOtherField" to StringNode("specialOtherValue"), "age" to IntNode(42), "qc" to DoubleNode(0.9), - "pangoLineage" to TextNode("XBB.1.5"), + "pangoLineage" to StringNode("XBB.1.5"), ), unalignedNucleotideSequences = mapOf( "notOnlySegment" to "NNACTGNN", @@ -108,10 +108,10 @@ val defaultProcessedDataMultiSegmented = ProcessedData( val defaultProcessedDataWithoutSequences = ProcessedData( metadata = mapOf( - "date" to TextNode("2002-12-15"), - "host" to TextNode("google.com"), - "region" to TextNode("Europe"), - "country" to TextNode("Spain"), + "date" to StringNode("2002-12-15"), + "host" to StringNode("google.com"), + "region" to StringNode("Europe"), + "country" to StringNode("Spain"), "division" to NullNode.instance, ), unalignedNucleotideSequences = emptyMap(), @@ -206,7 +206,7 @@ object PreparedProcessedData { fun withUnknownMetadataField(accession: Accession, fields: List) = defaultSuccessfulSubmittedData.copy( accession = accession, data = defaultProcessedData.copy( - metadata = defaultProcessedData.metadata + fields.map { it to TextNode("value for $it") }, + metadata = defaultProcessedData.metadata + fields.map { it to StringNode("value for $it") }, ), ) @@ -222,7 +222,7 @@ object PreparedProcessedData { data = defaultProcessedData.copy( metadata = defaultProcessedData.metadata + mapOf( "region" to IntNode(5), - "age" to TextNode("not a number"), + "age" to StringNode("not a number"), ), ), ) @@ -231,7 +231,7 @@ object PreparedProcessedData { accession = accession, data = defaultProcessedData.copy( metadata = defaultProcessedData.metadata + mapOf( - "date" to TextNode("1.2.2021"), + "date" to StringNode("1.2.2021"), ), ), ) @@ -240,7 +240,7 @@ object PreparedProcessedData { accession = accession, data = defaultProcessedData.copy( metadata = defaultProcessedData.metadata + mapOf( - "booleanColumn" to TextNode("not a boolean"), + "booleanColumn" to StringNode("not a boolean"), ), ), ) diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/ReviseEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/ReviseEndpointTest.kt index 61dbc1c8e5..ca644fa20e 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/ReviseEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/ReviseEndpointTest.kt @@ -181,7 +181,7 @@ class ReviseEndpointTest( """.trimIndent(), ), SubmitFiles.sequenceFileWith(), - ).andExpect(status().isUnprocessableEntity) + ).andExpect(status().isUnprocessableContent) .andExpect(content().contentType(APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail").value( @@ -206,7 +206,7 @@ class ReviseEndpointTest( """.trimIndent(), ), SubmitFiles.sequenceFileWith(), - ).andExpect(status().isUnprocessableEntity) + ).andExpect(status().isUnprocessableContent) .andExpect(content().contentType(APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail").value( @@ -226,7 +226,7 @@ class ReviseEndpointTest( DefaultFiles.sequencesFileMultiSegmented, organism = OTHER_ORGANISM, ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail").value( @@ -263,7 +263,7 @@ class ReviseEndpointTest( DefaultFiles.getRevisedMetadataFile(accessions), DefaultFiles.sequencesFile, ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -384,7 +384,7 @@ class ReviseEndpointTest( ), ), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -413,7 +413,7 @@ class ReviseEndpointTest( ), ), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -449,7 +449,7 @@ class ReviseEndpointTest( ), ), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -559,7 +559,7 @@ class ReviseEndpointTest( """.trimIndent(), ), SubmitFiles.sequenceFileWith(), - status().isUnprocessableEntity, + status().isUnprocessableContent, "Unprocessable Entity", "contains no value for 'id'", ), @@ -572,7 +572,7 @@ class ReviseEndpointTest( """.trimIndent(), ), SubmitFiles.sequenceFileWith(), - status().isUnprocessableEntity, + status().isUnprocessableContent, "Unprocessable Entity", "The metadata file does not contain either header 'id' or 'submissionId'", ), @@ -586,7 +586,7 @@ class ReviseEndpointTest( """.trimIndent(), ), SubmitFiles.sequenceFileWith(), - status().isUnprocessableEntity, + status().isUnprocessableContent, "Unprocessable Entity", "Duplicate submission_id found in metadata file: sameHeader", ), @@ -601,7 +601,7 @@ class ReviseEndpointTest( AC """.trimIndent(), ), - status().isUnprocessableEntity, + status().isUnprocessableContent, "Unprocessable Entity", "Sequence file contains at least one duplicate submissionId", ), @@ -623,7 +623,7 @@ class ReviseEndpointTest( AC """.trimIndent(), ), - status().isUnprocessableEntity, + status().isUnprocessableContent, "Unprocessable Entity", "Sequence file contains 2 FASTA ids that are not present in the metadata file: 'notInMetadata', 'notInMetadata2'", ), @@ -642,7 +642,7 @@ class ReviseEndpointTest( AC """.trimIndent(), ), - status().isUnprocessableEntity, + status().isUnprocessableContent, "Unprocessable Entity", "Metadata file contains 1 FASTA ids that are not present in the sequence file: 'notInSequences'", ), @@ -656,7 +656,7 @@ class ReviseEndpointTest( """.trimIndent(), ), SubmitFiles.sequenceFileWith(), - status().isUnprocessableEntity, + status().isUnprocessableContent, "Unprocessable Entity", "The revised metadata file does not contain the header 'accession'", ), @@ -670,7 +670,7 @@ class ReviseEndpointTest( """.trimIndent(), ), SubmitFiles.sequenceFileWith(), - status().isUnprocessableEntity, + status().isUnprocessableContent, "Unprocessable Entity", "contains no value for 'accession'", ), diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/RevokeEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/RevokeEndpointTest.kt index 117b86a4b3..b54011cb38 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/RevokeEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/RevokeEndpointTest.kt @@ -67,7 +67,7 @@ class RevokeEndpointTest( val nonExistingAccession = "123" client.revokeSequenceEntries(listOf(nonExistingAccession)) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail").value( @@ -82,7 +82,7 @@ class RevokeEndpointTest( .prepareDefaultSequenceEntriesToApprovedForRelease(organism = DEFAULT_ORGANISM).map { it.accession } client.revokeSequenceEntries(listOf(accessions.first()), organism = OTHER_ORGANISM) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail").value( @@ -132,7 +132,7 @@ class RevokeEndpointTest( val accessions = convenienceClient.prepareDefaultSequenceEntriesToHasErrors().map { it.accession } client.revokeSequenceEntries(accessions) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmissionControllerClient.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmissionControllerClient.kt index 3eb045f850..73cb8bd36d 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmissionControllerClient.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmissionControllerClient.kt @@ -1,6 +1,5 @@ package org.loculus.backend.controller.submission -import com.fasterxml.jackson.databind.ObjectMapper import org.loculus.backend.api.AccessionVersion import org.loculus.backend.api.AccessionVersionInterface import org.loculus.backend.api.ApproveDataScope @@ -30,6 +29,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delet import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post +import tools.jackson.databind.ObjectMapper class SubmissionControllerClient(private val mockMvc: MockMvc, private val objectMapper: ObjectMapper) { fun submit( @@ -60,13 +60,12 @@ class SubmissionControllerClient(private val mockMvc: MockMvc, private val objec } .param("groupId", groupId.toString()) .param("dataUseTermsType", dataUseTerm.type.name) - .param( - "restrictedUntil", + .apply { when (dataUseTerm) { - is DataUseTerms.Restricted -> dataUseTerm.restrictedUntil.toString() - else -> null - }, - ) + is DataUseTerms.Restricted -> param("restrictedUntil", dataUseTerm.restrictedUntil.toString()) + else -> this + } + } .withAuth(jwt), ) @@ -165,11 +164,11 @@ class SubmissionControllerClient(private val mockMvc: MockMvc, private val objec ): ResultActions = mockMvc.perform( get(addOrganismToPath("/get-sequences", organism = organism)) .withAuth(jwt) - .param("groupIdsFilter", groupIdsFilter?.joinToString(",") { it.toString() }) - .param("statusesFilter", statusesFilter?.joinToString(",") { it.name }) - .param("processingResultFilter", processingResultFilter?.joinToString(",") { it.name }) - .param("page", page?.toString()) - .param("size", size?.toString()), + .apply { groupIdsFilter?.let { param("groupIdsFilter", it.joinToString(",") { it.toString() }) } } + .apply { statusesFilter?.let { param("statusesFilter", it.joinToString(",") { it.name }) } } + .apply { processingResultFilter?.let { param("processingResultFilter", it.joinToString(",") { it.name }) } } + .apply { page?.let { param("page", it.toString()) } } + .apply { size?.let { param("size", it.toString()) } }, ) fun getSequenceEntryToEdit( @@ -318,9 +317,9 @@ class SubmissionControllerClient(private val mockMvc: MockMvc, private val objec else -> it.param("compression", compression) } } - .param("groupIdsFilter", groupIdsFilter?.joinToString(",") { it.toString() }) - .param("statusesFilter", statusesFilter?.joinToString(",") { it.name }) - .param("fields", fields?.joinToString(",")), + .apply { groupIdsFilter?.let { param("groupIdsFilter", it.joinToString(",") { it.toString() }) } } + .apply { statusesFilter?.let { param("statusesFilter", it.joinToString(",") { it.name }) } } + .apply { fields?.let { param("fields", it.joinToString(",")) } }, ) private fun serialize(listOfSequencesToApprove: List? = null): String = diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmissionConvenienceClient.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmissionConvenienceClient.kt index 9e090f3521..0e6ce5482a 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmissionConvenienceClient.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmissionConvenienceClient.kt @@ -1,7 +1,5 @@ package org.loculus.backend.controller.submission -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue import org.loculus.backend.api.AccessionVersion import org.loculus.backend.api.AccessionVersionInterface import org.loculus.backend.api.AccessionVersionOriginalMetadata @@ -44,6 +42,8 @@ import org.springframework.http.MediaType import org.springframework.test.web.servlet.ResultActions import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import tools.jackson.databind.ObjectMapper +import tools.jackson.module.kotlin.readValue import java.net.URI import java.net.http.HttpClient import java.net.http.HttpRequest diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmissionJourneyTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmissionJourneyTest.kt index 7ef673d7f2..3fd3c405e9 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmissionJourneyTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmissionJourneyTest.kt @@ -244,7 +244,7 @@ class SubmissionJourneyTest(@Autowired val convenienceClient: SubmissionConvenie private fun getAccessionVersionsOfProcessedData(processedData: List>) = processedData .map { it.metadata } - .map { it["accessionVersion"]!!.asText() } + .map { it["accessionVersion"]!!.asString() } private fun getAccessionVersions(sequenceEntryVersions: List) = sequenceEntryVersions.map { it.displayAccessionVersion() } diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmissionJourneyWithFilesTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmissionJourneyWithFilesTest.kt index 229ac291fb..ad606d0e50 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmissionJourneyWithFilesTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmissionJourneyWithFilesTest.kt @@ -1,6 +1,5 @@ package org.loculus.backend.controller.submission -import com.fasterxml.jackson.module.kotlin.readValue import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.hasItems import org.hamcrest.Matchers.`is` @@ -33,6 +32,7 @@ import org.loculus.backend.controller.jwtForProcessingPipeline import org.loculus.backend.controller.submission.SubmitFiles.DefaultFiles import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import tools.jackson.module.kotlin.readValue import java.net.URI import java.net.http.HttpClient import java.net.http.HttpRequest @@ -101,7 +101,7 @@ class SubmissionJourneyWithFilesTest( .assertStatusIs(APPROVED_FOR_RELEASE) val releasedData = convenienceClient.getReleasedData() - val releasedFileMappingString = releasedData.first().metadata["myFileCategory"]!!.asText() + val releasedFileMappingString = releasedData.first().metadata["myFileCategory"]!!.asString() val fileMapping: List> = jacksonObjectMapper.readValue(releasedFileMappingString) assertThat(fileMapping.size, `is`(2)) val contents = fileMapping.map { downloadFromUrl(it["url"]!!) } @@ -205,7 +205,7 @@ class SubmissionJourneyWithFilesTest( .assertStatusIs(APPROVED_FOR_RELEASE) val releasedData = convenienceClient.getReleasedData() - val releasedFileMappingString = releasedData.first().metadata["myFileCategory"]!!.asText() + val releasedFileMappingString = releasedData.first().metadata["myFileCategory"]!!.asString() val fileMapping: List> = jacksonObjectMapper.readValue(releasedFileMappingString) assertThat(fileMapping.size, `is`(2)) val contents = fileMapping.map { downloadFromUrl(it["url"]!!) } diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitEditedSequenceEntryVersionEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitEditedSequenceEntryVersionEndpointTest.kt index 2c34cd030d..d216d3e971 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitEditedSequenceEntryVersionEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitEditedSequenceEntryVersionEndpointTest.kt @@ -114,7 +114,7 @@ class SubmitEditedSequenceEntryVersionEndpointTest( val sequenceString = editedDataWithNonExistingVersion.displayAccessionVersion() client.submitEditedSequenceEntryVersion(editedDataWithNonExistingVersion) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect( jsonPath("\$.detail") .value("Accession versions $sequenceString do not exist"), @@ -134,7 +134,7 @@ class SubmitEditedSequenceEntryVersionEndpointTest( val editedDataWithNonExistingAccession = generateEditedData(nonExistingAccession) client.submitEditedSequenceEntryVersion(editedDataWithNonExistingAccession) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect( jsonPath("\$.detail").value( "Accession versions $nonExistingAccession.1 do not exist", @@ -157,7 +157,7 @@ class SubmitEditedSequenceEntryVersionEndpointTest( val editedData = generateEditedData(accessions.first()) client.submitEditedSequenceEntryVersion(editedData, organism = OTHER_ORGANISM) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect( jsonPath( "\$.detail", @@ -227,7 +227,7 @@ class SubmitEditedSequenceEntryVersionEndpointTest( ) client.submitEditedSequenceEntryVersion(editedData) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect( jsonPath("\$.detail", containsString("duplicate file names")), ) @@ -253,7 +253,7 @@ class SubmitEditedSequenceEntryVersionEndpointTest( ) client.submitEditedSequenceEntryVersion(editedData) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect( jsonPath( "\$.detail", @@ -283,7 +283,7 @@ class SubmitEditedSequenceEntryVersionEndpointTest( ) client.submitEditedSequenceEntryVersion(editedData) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect( jsonPath( "\$.detail", @@ -317,7 +317,7 @@ class SubmitEditedSequenceEntryVersionEndpointTest( ) client.submitEditedSequenceEntryVersion(editedData) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect( jsonPath("\$.detail", containsString("No file uploaded for file ID")), ) diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitEndpointFileSharingTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitEndpointFileSharingTest.kt index 0b80727d8a..9b96de682e 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitEndpointFileSharingTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitEndpointFileSharingTest.kt @@ -85,7 +85,7 @@ class SubmitEndpointFileSharingTest( ), ), ) - .andExpect(status().isUnprocessableEntity()) + .andExpect(status().isUnprocessableContent()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -114,7 +114,7 @@ class SubmitEndpointFileSharingTest( ), ), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -173,7 +173,7 @@ class SubmitEndpointFileSharingTest( ), ), ) - .andExpect(status().isUnprocessableEntity()) + .andExpect(status().isUnprocessableContent()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -199,7 +199,7 @@ class SubmitEndpointFileSharingTest( ), ), ) - .andExpect(status().isUnprocessableEntity()) + .andExpect(status().isUnprocessableContent()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( @@ -229,7 +229,7 @@ class SubmitEndpointFileSharingTest( ), ), ) - .andExpect(status().isUnprocessableEntity()) + .andExpect(status().isUnprocessableContent()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath( diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitEndpointTest.kt index 5a0d46d209..bdd2f5ba72 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitEndpointTest.kt @@ -365,7 +365,7 @@ class SubmitEndpointTest( """.trimIndent(), ), DefaultFiles.sequencesFile, - status().isUnprocessableEntity, + status().isUnprocessableContent, "Unprocessable Entity", "contains no value for 'id'", DEFAULT_ORGANISM, @@ -380,7 +380,7 @@ class SubmitEndpointTest( """.trimIndent(), ), DefaultFiles.sequencesFile, - status().isUnprocessableEntity, + status().isUnprocessableContent, "Unprocessable Entity", "The metadata file does not contain either header 'id' or 'submissionId'", DEFAULT_ORGANISM, @@ -396,7 +396,7 @@ class SubmitEndpointTest( """.trimIndent(), ), DefaultFiles.sequencesFile, - status().isUnprocessableEntity, + status().isUnprocessableContent, "Unprocessable Entity", "Metadata file contains at least one duplicate submissionId", DEFAULT_ORGANISM, @@ -413,7 +413,7 @@ class SubmitEndpointTest( AC """.trimIndent(), ), - status().isUnprocessableEntity, + status().isUnprocessableContent, "Unprocessable Entity", "Sequence file contains at least one duplicate submissionId", DEFAULT_ORGANISM, @@ -435,7 +435,7 @@ class SubmitEndpointTest( AC """.trimIndent(), ), - status().isUnprocessableEntity, + status().isUnprocessableContent, "Unprocessable Entity", "Sequence file contains 1 FASTA ids that are not present in the metadata file: 'notInMetadata'", DEFAULT_ORGANISM, @@ -456,7 +456,7 @@ class SubmitEndpointTest( AC """.trimIndent(), ), - status().isUnprocessableEntity, + status().isUnprocessableContent, "Unprocessable Entity", "Metadata file contains 1 FASTA ids that are not present in the sequence file: 'notInSequences'", DEFAULT_ORGANISM, @@ -539,7 +539,7 @@ class SubmitEndpointTest( sequencesFile, groupId = groupId, ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail").value( diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitExternalMetadataEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitExternalMetadataEndpointTest.kt index e518d4c9d4..b0201e9f01 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitExternalMetadataEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitExternalMetadataEndpointTest.kt @@ -1,6 +1,5 @@ package org.loculus.backend.controller.submission -import com.fasterxml.jackson.databind.node.TextNode import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.containsString import org.hamcrest.Matchers.equalTo @@ -20,6 +19,7 @@ import org.springframework.http.MediaType import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import tools.jackson.databind.node.StringNode @EndpointTest class SubmitExternalMetadataEndpointTest( @@ -62,7 +62,7 @@ class SubmitExternalMetadataEndpointTest( val releasedSequenceEntry = getReleasedSequenceEntry(accession) - assertThat(releasedSequenceEntry.metadata, hasEntry("insdcAccessionFull", TextNode("GENBANK1000.1"))) + assertThat(releasedSequenceEntry.metadata, hasEntry("insdcAccessionFull", StringNode("GENBANK1000.1"))) } @Test @@ -87,8 +87,8 @@ class SubmitExternalMetadataEndpointTest( val releasedSequenceEntry = getReleasedSequenceEntry(accession) - assertThat(releasedSequenceEntry.metadata, hasEntry("insdcAccessionFull", TextNode("GENBANK1000.1"))) - assertThat(releasedSequenceEntry.metadata, hasEntry("other_db_accession", TextNode("DB1.1"))) + assertThat(releasedSequenceEntry.metadata, hasEntry("insdcAccessionFull", StringNode("GENBANK1000.1"))) + assertThat(releasedSequenceEntry.metadata, hasEntry("other_db_accession", StringNode("DB1.1"))) } @Test @@ -104,7 +104,7 @@ class SubmitExternalMetadataEndpointTest( PreparedExternalMetadata.successfullySubmitted(accession = accession), externalMetadataUpdater = "other_db", ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail") @@ -124,7 +124,7 @@ class SubmitExternalMetadataEndpointTest( .submitExternalMetadata( PreparedExternalMetadata.successfullySubmitted(accession = accession), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail") @@ -147,7 +147,7 @@ class SubmitExternalMetadataEndpointTest( .submitExternalMetadata( PreparedExternalMetadata.successfullySubmitted(accession = accession), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail") @@ -161,7 +161,7 @@ class SubmitExternalMetadataEndpointTest( private fun getReleasedSequenceEntry(accession: Accession): ProcessedData { val releasedSequenceEntry = convenienceClient.getReleasedData() - .find { it.metadata["accession"]?.textValue() == accession } + .find { it.metadata["accession"]?.stringValue() == accession } assertThat(releasedSequenceEntry, notNullValue()) return releasedSequenceEntry!! diff --git a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitProcessedDataEndpointTest.kt b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitProcessedDataEndpointTest.kt index bfa72ea650..33c6640501 100644 --- a/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitProcessedDataEndpointTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/controller/submission/SubmitProcessedDataEndpointTest.kt @@ -1,11 +1,5 @@ package org.loculus.backend.controller.submission -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.node.BooleanNode -import com.fasterxml.jackson.databind.node.DoubleNode -import com.fasterxml.jackson.databind.node.IntNode -import com.fasterxml.jackson.databind.node.TextNode -import com.fasterxml.jackson.module.kotlin.readValue import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.allOf import org.hamcrest.Matchers.containsString @@ -52,6 +46,12 @@ import org.springframework.http.MediaType import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import tools.jackson.databind.ObjectMapper +import tools.jackson.databind.node.BooleanNode +import tools.jackson.databind.node.DoubleNode +import tools.jackson.databind.node.IntNode +import tools.jackson.databind.node.StringNode +import tools.jackson.module.kotlin.readValue import java.net.URI import java.net.http.HttpClient import java.net.http.HttpRequest @@ -108,8 +108,8 @@ class SubmitProcessedDataEndpointTest( val sequenceEntryToEdit = convenienceClient.getSequenceEntryToEdit(accession = accessions.first(), version = 1) assertThat(sequenceEntryToEdit.processedData.metadata, hasEntry("qc", DoubleNode(0.987654321))) assertThat(sequenceEntryToEdit.processedData.metadata, hasEntry("age", IntNode(42))) - assertThat(sequenceEntryToEdit.processedData.metadata, hasEntry("region", TextNode("Europe"))) - assertThat(sequenceEntryToEdit.processedData.metadata, hasEntry("pangoLineage", TextNode("XBB.1.5"))) + assertThat(sequenceEntryToEdit.processedData.metadata, hasEntry("region", StringNode("Europe"))) + assertThat(sequenceEntryToEdit.processedData.metadata, hasEntry("pangoLineage", StringNode("XBB.1.5"))) assertThat(sequenceEntryToEdit.processedData.metadata, hasEntry("booleanColumn", BooleanNode.TRUE)) } @@ -245,7 +245,7 @@ class SubmitProcessedDataEndpointTest( submissionControllerClient.submitProcessedData( invalidDataScenario.processedDataThatNeedsAValidAccession.copy(accession = accessions.first()), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect(jsonPath("\$.detail").value(invalidDataScenario.expectedErrorMessage)) @@ -266,7 +266,7 @@ class SubmitProcessedDataEndpointTest( PreparedProcessedData.successfullyProcessed(accession = accessions.first()), PreparedProcessedData.successfullyProcessed(accession = nonExistentAccession), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail") @@ -292,7 +292,7 @@ class SubmitProcessedDataEndpointTest( PreparedProcessedData.successfullyProcessed(accession = accessions.first()) .copy(version = nonExistentVersion), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail").value( @@ -317,7 +317,7 @@ class SubmitProcessedDataEndpointTest( PreparedProcessedData.successfullyProcessed(accession = accessionsInProcessing.first()), PreparedProcessedData.successfullyProcessed(accession = accessionsNotInProcessing.first()), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail").value( @@ -364,7 +364,7 @@ class SubmitProcessedDataEndpointTest( PreparedProcessedData.successfullyProcessed(accession = accession), organism = DEFAULT_ORGANISM, ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect( jsonPath("\$.detail") @@ -385,7 +385,7 @@ class SubmitProcessedDataEndpointTest( PreparedProcessedData.successfullyProcessedOtherOrganismData(accession = defaultOrganismAccession), organism = DEFAULT_ORGANISM, ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect( jsonPath("\$.detail").value("Unknown fields in metadata: specialOtherField."), ) @@ -446,7 +446,7 @@ class SubmitProcessedDataEndpointTest( ), ), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) } @Test @@ -467,7 +467,7 @@ class SubmitProcessedDataEndpointTest( ), ), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(jsonPath("$.detail", containsString("not part of the configured output categories"))) } @@ -490,7 +490,7 @@ class SubmitProcessedDataEndpointTest( ), ), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect(jsonPath("$.detail", containsString("duplicate file names"))) } @@ -512,7 +512,7 @@ class SubmitProcessedDataEndpointTest( ), ), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect( jsonPath( "$.detail", @@ -545,7 +545,7 @@ class SubmitProcessedDataEndpointTest( ), ), ) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) .andExpect( jsonPath( "$.detail", @@ -610,7 +610,7 @@ class SubmitProcessedDataEndpointTest( // Step 6: check file is publicly accessible val releasedData = convenienceClient.getReleasedData(organism = DEFAULT_ORGANISM) - val filesJson = releasedData.first().metadata["myFileCategory"]!!.asText() + val filesJson = releasedData.first().metadata["myFileCategory"]!!.asString() val fileList: List> = objectMapper.readValue(filesJson) val fileUrl = fileList.first()["url"]!! val client = HttpClient.newHttpClient() @@ -675,7 +675,7 @@ class SubmitProcessedDataEndpointTest( // Step 6: check file is publicly accessible val releasedData = convenienceClient.getReleasedData(organism = DEFAULT_ORGANISM) - val filesJson = releasedData.first().metadata["myFileCategory"]!!.asText() + val filesJson = releasedData.first().metadata["myFileCategory"]!!.asString() val fileList: List> = objectMapper.readValue(filesJson) val fileUrl = fileList.first()["url"]!! val client = HttpClient.newHttpClient() diff --git a/backend/src/test/kotlin/org/loculus/backend/service/ProcessedMetadataPostprocessorTest.kt b/backend/src/test/kotlin/org/loculus/backend/service/ProcessedMetadataPostprocessorTest.kt index 2213082e02..ef141e552b 100644 --- a/backend/src/test/kotlin/org/loculus/backend/service/ProcessedMetadataPostprocessorTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/service/ProcessedMetadataPostprocessorTest.kt @@ -1,7 +1,5 @@ package org.loculus.backend.service -import com.fasterxml.jackson.databind.node.NullNode -import com.fasterxml.jackson.databind.node.TextNode import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.hasKey import org.hamcrest.Matchers.not @@ -13,6 +11,8 @@ import org.loculus.backend.api.ProcessedData import org.loculus.backend.config.BackendConfig import org.loculus.backend.service.submission.ProcessedMetadataPostprocessor import org.springframework.beans.factory.annotation.Autowired +import tools.jackson.databind.node.NullNode +import tools.jackson.databind.node.StringNode @SpringBootTestWithoutDatabase class ProcessedMetadataPostprocessorTest( @@ -33,9 +33,9 @@ class ProcessedMetadataPostprocessorTest( val testData = ProcessedData( metadata = mapOf( - configuredPresent to TextNode("value1"), + configuredPresent to StringNode("value1"), configuredNull to NullNode.instance, - unconfiguredPresent to TextNode("value2"), + unconfiguredPresent to StringNode("value2"), unconfiguredNull to NullNode.instance, ), unalignedNucleotideSequences = emptyMap(), diff --git a/backend/src/test/kotlin/org/loculus/backend/service/submission/EmptyProcessedDataProviderTest.kt b/backend/src/test/kotlin/org/loculus/backend/service/submission/EmptyProcessedDataProviderTest.kt index 3785f3af8f..3b8f220f01 100644 --- a/backend/src/test/kotlin/org/loculus/backend/service/submission/EmptyProcessedDataProviderTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/service/submission/EmptyProcessedDataProviderTest.kt @@ -1,6 +1,5 @@ package org.loculus.backend.service.submission -import com.fasterxml.jackson.databind.node.NullNode import org.hamcrest.CoreMatchers.`is` import org.hamcrest.MatcherAssert.assertThat import org.junit.jupiter.api.Test @@ -14,6 +13,7 @@ import org.loculus.backend.config.ReferenceGenome import org.loculus.backend.config.ReferenceSequence import org.loculus.backend.config.Schema import org.loculus.backend.controller.DEFAULT_ORGANISM +import tools.jackson.databind.node.NullNode private const val FIRST_METADATA_FIELD = "required" private const val SECOND_METADATA_FIELD = "notRequired" diff --git a/backend/src/test/kotlin/org/loculus/backend/service/submission/UseNewerProcessingPipelineVersionTaskTest.kt b/backend/src/test/kotlin/org/loculus/backend/service/submission/UseNewerProcessingPipelineVersionTaskTest.kt index d04e23ba03..62ef7e7644 100644 --- a/backend/src/test/kotlin/org/loculus/backend/service/submission/UseNewerProcessingPipelineVersionTaskTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/service/submission/UseNewerProcessingPipelineVersionTaskTest.kt @@ -56,7 +56,7 @@ class UseNewerProcessingPipelineVersionTaskTest( assertThat(submissionDatabaseService.getCurrentProcessingPipelineVersion(Organism(DEFAULT_ORGANISM)), `is`(3L)) submissionControllerClient.extractUnprocessedData(numberOfSequenceEntries = 10, pipelineVersion = 2) - .andExpect(status().isUnprocessableEntity) + .andExpect(status().isUnprocessableContent) } @Suppress("ktlint:standard:max-line-length") diff --git a/backend/src/test/kotlin/org/loculus/backend/testutil/docker/DockerPostgres.kt b/backend/src/test/kotlin/org/loculus/backend/testutil/docker/DockerPostgres.kt index 1edb840837..7debc01527 100644 --- a/backend/src/test/kotlin/org/loculus/backend/testutil/docker/DockerPostgres.kt +++ b/backend/src/test/kotlin/org/loculus/backend/testutil/docker/DockerPostgres.kt @@ -1,11 +1,12 @@ package org.loculus.backend.testutil.docker import org.loculus.backend.testutil.PostgresProvider -import org.testcontainers.containers.PostgreSQLContainer +import org.testcontainers.postgresql.PostgreSQLContainer import java.io.File class DockerPostgres : PostgresProvider { - private val container = PostgreSQLContainer("postgres:latest") + // Keep version in sync with dev db (in helm) and prod db + private val container = PostgreSQLContainer("postgres:15.12") override val jdbcUrl: String get() = container.jdbcUrl diff --git a/backend/src/test/kotlin/org/loculus/backend/utils/EarliestReleaseDateFinderTest.kt b/backend/src/test/kotlin/org/loculus/backend/utils/EarliestReleaseDateFinderTest.kt index 342bfc1bd7..5cf50ab07f 100644 --- a/backend/src/test/kotlin/org/loculus/backend/utils/EarliestReleaseDateFinderTest.kt +++ b/backend/src/test/kotlin/org/loculus/backend/utils/EarliestReleaseDateFinderTest.kt @@ -1,7 +1,5 @@ package org.loculus.backend.utils -import com.fasterxml.jackson.databind.node.NullNode -import com.fasterxml.jackson.databind.node.TextNode import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDateTime import kotlinx.datetime.format @@ -11,6 +9,8 @@ import org.junit.jupiter.api.Test import org.loculus.backend.api.DataUseTerms import org.loculus.backend.api.ProcessedData import org.loculus.backend.service.submission.RawProcessedData +import tools.jackson.databind.node.NullNode +import tools.jackson.databind.node.StringNode class EarliestReleaseDateFinderTest { @@ -55,7 +55,7 @@ fun row( processedData = ProcessedData( metadata = fieldValues.map { (field, date) -> field to - if (date != null) TextNode(date.date.format(LocalDate.Formats.ISO)) else NullNode.getInstance() + if (date != null) StringNode(date.date.format(LocalDate.Formats.ISO)) else NullNode.getInstance() }.toMap(), unalignedNucleotideSequences = emptyMap(), alignedNucleotideSequences = emptyMap(), diff --git a/backend/src/test/resources/application.properties b/backend/src/test/resources/application.properties index 4961ec5b3e..90569c33cf 100644 --- a/backend/src/test/resources/application.properties +++ b/backend/src/test/resources/application.properties @@ -18,3 +18,5 @@ keycloak.client=dummy-cli keycloak.url=dummy:420 spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://some.value + + diff --git a/backend/src/test/resources/logback-test.xml b/backend/src/test/resources/logback-test.xml index 5b60a899a9..9326720723 100644 --- a/backend/src/test/resources/logback-test.xml +++ b/backend/src/test/resources/logback-test.xml @@ -9,7 +9,9 @@ - + + +