Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2.0.0-RC4 #458

Merged
merged 7 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/src/main/kotlin/dev/dres/DRES.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import kotlin.system.exitProcess
*/
object DRES {
/** Version of DRES. */
const val VERSION = "2.0.0-RC3"
const val VERSION = "2.0.0-RC4"

/** Application root; should be relative to JAR file or classes path. */
val APPLICATION_ROOT: Path =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package dev.dres.api.rest

import com.fasterxml.jackson.core.type.TypeReference

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import io.javalin.json.JsonMapper
import kotlinx.serialization.KSerializer
Expand All @@ -12,13 +12,16 @@ import java.lang.reflect.Type
object KotlinxJsonMapper : JsonMapper {

private val fallbackMapper = jacksonObjectMapper()
private val mapper = Json{
ignoreUnknownKeys = true
}

override fun <T : Any> fromJsonString(json: String, targetType: Type): T {

return try {
@Suppress("UNCHECKED_CAST")
val serializer = serializer(targetType) as KSerializer<T>
Json.decodeFromString(serializer, json)
mapper.decodeFromString(serializer, json)
} catch (e: SerializationException) {
null
} catch (e: IllegalStateException) {
Expand All @@ -31,7 +34,7 @@ object KotlinxJsonMapper : JsonMapper {

return try {
val serializer = serializer(type)
Json.encodeToString(serializer, obj)
mapper.encodeToString(serializer, obj)
} catch (e: SerializationException) {
null
} catch (e: IllegalStateException) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.dres.api.rest.handler.evaluation.client

import dev.dres.api.rest.handler.GetRestHandler
import dev.dres.api.rest.types.evaluation.ApiClientTaskTemplateInfo
import dev.dres.utilities.extensions.eligibleManagerForId
import dev.dres.api.rest.types.evaluation.ApiTaskTemplateInfo
import dev.dres.api.rest.types.status.ErrorStatus
Expand All @@ -21,7 +22,7 @@ import jetbrains.exodus.database.TransientEntityStore
* @version 2.0.0
*/
class ClientTaskInfoHandler : AbstractEvaluationClientHandler(),
GetRestHandler<ApiTaskTemplateInfo> {
GetRestHandler<ApiClientTaskTemplateInfo> {
override val route = "client/evaluation/currentTask/{evaluationId}"

@OpenApi(
Expand All @@ -36,13 +37,13 @@ class ClientTaskInfoHandler : AbstractEvaluationClientHandler(),
OpenApiParam("session", String::class, "Session Token")
],
responses = [
OpenApiResponse("200", [OpenApiContent(ApiTaskTemplateInfo::class)]),
OpenApiResponse("200", [OpenApiContent(ApiClientTaskTemplateInfo::class)]),
OpenApiResponse("401", [OpenApiContent(ErrorStatus::class)]),
OpenApiResponse("404", [OpenApiContent(ErrorStatus::class)])
],
methods = [HttpMethod.GET]
)
override fun doGet(ctx: Context): ApiTaskTemplateInfo {
override fun doGet(ctx: Context): ApiClientTaskTemplateInfo {
val run = ctx.eligibleManagerForId<RunManager>()
val rac = ctx.runActionContext()
if (run !is InteractiveRunManager) throw ErrorStatusException(
Expand All @@ -52,6 +53,6 @@ class ClientTaskInfoHandler : AbstractEvaluationClientHandler(),
)
val task =
run.currentTask(rac) ?: throw ErrorStatusException(404, "Specified evaluation has no active task.", ctx)
return ApiTaskTemplateInfo(task.template)
return ApiClientTaskTemplateInfo(task.template)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import dev.dres.api.rest.types.status.ErrorStatus
import dev.dres.api.rest.types.status.ErrorStatusException
import dev.dres.api.rest.types.status.SuccessStatus
import dev.dres.data.model.log.QueryEventLog
import dev.dres.run.RunManager
import dev.dres.run.eventstream.EventStreamProcessor
import dev.dres.run.eventstream.InvalidRequestEvent
import dev.dres.run.eventstream.QueryEventLogEvent
import dev.dres.utilities.extensions.activeManagerForUser
import dev.dres.utilities.extensions.eligibleManagerForId
import dev.dres.utilities.extensions.sessionToken
import io.javalin.http.BadRequestResponse
import io.javalin.http.Context
Expand All @@ -22,14 +24,17 @@ import io.javalin.openapi.*
* @version 2.0.0
*/
class QueryLogHandler : AbstractLogHandler() {
override val route = "log/query"
override val route = "log/query/{evaluationId}"

@OpenApi(summary = "Accepts query logs from participants",
path = "/api/v2/log/query",
@OpenApi(summary = "Accepts query logs from participants for the specified evaluation.",
path = "/api/v2/log/query/{evaluationId}",
operationId = OpenApiOperation.AUTO_GENERATE,
methods = [HttpMethod.POST],
requestBody = OpenApiRequestBody([OpenApiContent(QueryEventLog::class)]),
tags = ["Log"],
pathParams = [
OpenApiParam("evaluationId", String::class, "The evaluation ID.", required = true, allowEmptyValue = false)
],
queryParams = [
OpenApiParam("session", String::class, "Session Token", required = true, allowEmptyValue = false)
],
Expand All @@ -39,7 +44,8 @@ class QueryLogHandler : AbstractLogHandler() {
OpenApiResponse("401", [OpenApiContent(ErrorStatus::class)])]
)
override fun doPost(ctx: Context): SuccessStatus {
val evaluationManager = ctx.activeManagerForUser()
val evaluationManager = ctx.eligibleManagerForId<RunManager>()
// val evaluationManager = ctx.activeManagerForUser()
val queryEventLog = try {
ctx.bodyAsClass<QueryEventLog>()
} catch (e: BadRequestResponse){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import dev.dres.api.rest.types.status.ErrorStatus
import dev.dres.api.rest.types.status.ErrorStatusException
import dev.dres.api.rest.types.status.SuccessStatus
import dev.dres.data.model.log.QueryResultLog
import dev.dres.run.RunManager
import dev.dres.run.eventstream.EventStreamProcessor
import dev.dres.run.eventstream.InvalidRequestEvent
import dev.dres.run.eventstream.QueryResultLogEvent
import dev.dres.utilities.extensions.activeManagerForUser
import dev.dres.utilities.extensions.eligibleManagerForId
import dev.dres.utilities.extensions.sessionToken
import io.javalin.http.BadRequestResponse
import io.javalin.http.Context
Expand All @@ -22,14 +24,17 @@ import io.javalin.openapi.*
* @version 2.0.0
*/
class ResultLogHandler: AbstractLogHandler() {
override val route = "log/result"
override val route = "log/result/{evaluationId}"

@OpenApi(summary = "Accepts result logs from participants.",
path = "/api/v2/log/result",
@OpenApi(summary = "Accepts result logs from participants for the specified evaluation.",
path = "/api/v2/log/result/{evaluationId}",
operationId = OpenApiOperation.AUTO_GENERATE,
methods = [HttpMethod.POST],
requestBody = OpenApiRequestBody([OpenApiContent(QueryResultLog::class)]),
tags = ["Log"],
pathParams = [
OpenApiParam("evaluationId", String::class, "The evaluation ID.", required = true, allowEmptyValue = false)
],
queryParams = [
OpenApiParam("session", String::class, "Session Token", required = true, allowEmptyValue = false)
],
Expand All @@ -39,7 +44,8 @@ class ResultLogHandler: AbstractLogHandler() {
OpenApiResponse("401", [OpenApiContent(ErrorStatus::class)])]
)
override fun doPost(ctx: Context): SuccessStatus {
val evaluationManager = ctx.activeManagerForUser()
// val evaluationManager = ctx.activeManagerForUser()
val evaluationManager = ctx.eligibleManagerForId<RunManager>()
val queryResultLog = try {
ctx.bodyAsClass(QueryResultLog::class.java)
} catch (e: BadRequestResponse){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ data class ApiAnswerSet(

@get:JsonIgnore
@get:OpenApiIgnore
@kotlinx.serialization.Transient
override lateinit var submission: Submission
@JsonIgnore
@OpenApiIgnore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ data class ApiClientAnswerSet(var taskId: String? = null, val taskName: String?
/** The [AnswerSetId] of this [ApiClientAnswerSet]. Typically generated by the receiving endpoint. */
@JsonIgnore
@get:OpenApiIgnore
@kotlinx.serialization.Transient
val answerSetId: AnswerSetId = UUID.randomUUID().toString()

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,26 @@ data class ApiClientSubmission(
@JsonIgnore
@get:OpenApiIgnore
@set:OpenApiIgnore
@kotlinx.serialization.Transient
var userId: UserId? = null,

/** The [TeamId] associated with the submission. Is usually added as contextual information by the receiving endpoint. */
@JsonIgnore
@get:OpenApiIgnore
@set:OpenApiIgnore
@kotlinx.serialization.Transient
var teamId: TeamId? = null,

/** The [SubmissionId] of this [ApiClientSubmission]. Typically generated by the receiving endpoint. */
@JsonIgnore
@get:OpenApiIgnore
@kotlinx.serialization.Transient
val submissionId: SubmissionId = UUID.randomUUID().toString(),

/** The timestamp at which this [ApiClientSubmission] was received. Typically generated by the receiving endpoint.*/
@JsonIgnore
@get:OpenApiIgnore
@kotlinx.serialization.Transient
val timestamp: Long = System.currentTimeMillis()
) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ data class ApiEvaluationTemplate(
@get:JsonIgnore
@delegate:JsonIgnore
@get:OpenApiIgnore
//@kotlinx.serialization.Transient not needed due to delegation
private val allParticipantIds by lazy { teams.flatMap { team -> team.users.mapNotNull { it.id } }.toSet() }

@JsonIgnore
Expand Down
17 changes: 11 additions & 6 deletions backend/src/main/kotlin/dev/dres/data/model/log/ParticipantLog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonSetter
import com.fasterxml.jackson.annotation.Nulls
import dev.dres.api.rest.types.evaluation.submission.ApiClientAnswer
import io.javalin.openapi.OpenApiIgnore
import kotlinx.serialization.Serializable

enum class QueryEventCategory {
TEXT, IMAGE, SKETCH, FILTER, BROWSING, COOPERATION, OTHER
}

@JsonIgnoreProperties(ignoreUnknown = true)
@Serializable
data class QueryEvent(
val timestamp: Long = -1,
val category: QueryEventCategory = QueryEventCategory.OTHER,
Expand All @@ -19,36 +22,38 @@ data class QueryEvent(
)

@JsonIgnoreProperties(ignoreUnknown = true)
@Serializable
data class QueryEventLog internal constructor(
val timestamp: Long = -1,
@field:JsonSetter(contentNulls = Nulls.FAIL)
val events: List<QueryEvent> = emptyList(),
@field:JsonIgnore
@get:JsonIgnore
@get:OpenApiIgnore
@kotlinx.serialization.Transient
internal val serverTimeStamp: Long = System.currentTimeMillis()
)

@JsonIgnoreProperties(ignoreUnknown = true)
data class QueryResult(
val item: String = "",
val segment: Int? = null,
val frame: Int? = null,
val score: Double? = null,
@Serializable
data class RankedAnswer(
val answer: ApiClientAnswer,
val rank: Int? = null
)

@JsonIgnoreProperties(ignoreUnknown = true)
@Serializable
data class QueryResultLog internal constructor(
val timestamp: Long = -1,
val sortType: String = "",
val resultSetAvailability: String = "",
@field:JsonSetter(contentNulls = Nulls.FAIL)
val results: List<QueryResult> = emptyList(),
val results: List<RankedAnswer> = emptyList(),
@field:JsonSetter(contentNulls = Nulls.FAIL)
val events: List<QueryEvent> = emptyList(),
@field:JsonIgnore
@get:JsonIgnore
@get:OpenApiIgnore
@kotlinx.serialization.Transient
internal val serverTimeStamp: Long = System.currentTimeMillis()
)
Loading
Loading