diff --git a/.gitignore b/.gitignore index 0ff38219..21898684 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ playground/ docker-compose.override.yml -log +log/ +logs/ diff --git a/lapis2/.gitignore b/lapis2/.gitignore index 6c264962..eccc267c 100644 --- a/lapis2/.gitignore +++ b/lapis2/.gitignore @@ -5,4 +5,5 @@ build/ !**/src/test/**/build/ /lapis-v2-openapi.json /lapis-v2-openapi-protected.json -log +log/ +logs/ diff --git a/lapis2/build.gradle b/lapis2/build.gradle index 3ae90942..385ca809 100644 --- a/lapis2/build.gradle +++ b/lapis2/build.gradle @@ -42,6 +42,7 @@ dependencies { implementation 'org.apache.commons:commons-csv:1.10.0' implementation 'com.github.luben:zstd-jni:1.5.6-1' implementation 'com.github.ben-manes.caffeine:caffeine:3.1.8' + implementation "org.jetbrains.kotlinx:kotlinx-datetime:0.5.0" testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: "org.mockito" diff --git a/lapis2/src/main/kotlin/org/genspectrum/lapis/request/LapisInfo.kt b/lapis2/src/main/kotlin/org/genspectrum/lapis/request/LapisInfo.kt index 39e73eb4..1a7ba57e 100644 --- a/lapis2/src/main/kotlin/org/genspectrum/lapis/request/LapisInfo.kt +++ b/lapis2/src/main/kotlin/org/genspectrum/lapis/request/LapisInfo.kt @@ -1,6 +1,10 @@ package org.genspectrum.lapis.request import io.swagger.v3.oas.annotations.media.Schema +import kotlinx.datetime.Clock +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toLocalDateTime +import org.genspectrum.lapis.config.DatabaseConfig import org.genspectrum.lapis.controller.LapisErrorResponse import org.genspectrum.lapis.controller.LapisHeaders.LAPIS_DATA_VERSION import org.genspectrum.lapis.controller.LapisResponse @@ -19,20 +23,36 @@ import org.springframework.http.server.ServerHttpResponse import org.springframework.web.bind.annotation.ControllerAdvice import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice +private const val REPORT_TO = + "Please report to https://github.com/GenSpectrum/LAPIS/issues in case you encounter any unexpected issues. " + + "Please include the request ID and the requestInfo in your report." + @Schema(description = LAPIS_INFO_DESCRIPTION) data class LapisInfo( @Schema( description = LAPIS_DATA_VERSION_RESPONSE_DESCRIPTION, example = LAPIS_DATA_VERSION_EXAMPLE, - ) var dataVersion: String? = null, - @Schema(description = REQUEST_ID_HEADER_DESCRIPTION) + ) + var dataVersion: String? = null, + @Schema( + description = REQUEST_ID_HEADER_DESCRIPTION, + example = "dfb342ea-3607-4caf-b35e-9aba75d06f81", + ) var requestId: String? = null, + @Schema( + description = "Some information about the request in human readable form. Intended for debugging.", + example = "my_instance on my.server.com at 2024-01-01T12:00:00.0000", + ) + var requestInfo: String? = null, + @Schema(example = REPORT_TO) + val reportTo: String = REPORT_TO, ) @ControllerAdvice class ResponseBodyAdviceDataVersion( private val dataVersion: DataVersion, private val requestIdContext: RequestIdContext, + private val databaseConfig: DatabaseConfig, ) : ResponseBodyAdvice { override fun beforeBodyWrite( body: Any?, @@ -46,15 +66,26 @@ class ResponseBodyAdviceDataVersion( val isDownload = response.headers.getFirst(HttpHeaders.CONTENT_DISPOSITION)?.startsWith("attachment") ?: false + request.uri.host + return when { body is LapisResponse<*> && isDownload -> body.data - body is LapisResponse<*> -> LapisResponse(body.data, getLapisInfo()) - body is LapisErrorResponse -> LapisErrorResponse(body.error, getLapisInfo()) + body is LapisResponse<*> -> LapisResponse(body.data, getLapisInfo(request)) + body is LapisErrorResponse -> LapisErrorResponse(body.error, getLapisInfo(request)) else -> body } } - private fun getLapisInfo() = LapisInfo(dataVersion.dataVersion, requestIdContext.requestId) + private fun getLapisInfo(request: ServerHttpRequest) = + LapisInfo( + dataVersion = dataVersion.dataVersion, + requestId = requestIdContext.requestId, + requestInfo = "${databaseConfig.schema.instanceName} on ${request.uri.host} at ${now()}", + ) + + private fun now(): String { + return Clock.System.now().toLocalDateTime(TimeZone.UTC).toString() + } override fun supports( returnType: MethodParameter,