-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(website,backend): adapt endpoint, and frontend, add tests, add c…
…ontrains
- Loading branch information
1 parent
53c5701
commit 4f72903
Showing
27 changed files
with
555 additions
and
85 deletions.
There are no files selected for viewing
109 changes: 109 additions & 0 deletions
109
backend/src/main/kotlin/org/loculus/backend/api/DataUseTerms.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package org.loculus.backend.api | ||
|
||
import com.fasterxml.jackson.annotation.JsonIgnore | ||
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 kotlinx.datetime.Clock | ||
import kotlinx.datetime.DateTimeUnit.Companion.YEAR | ||
import kotlinx.datetime.LocalDate | ||
import kotlinx.datetime.LocalDateTime | ||
import kotlinx.datetime.TimeZone | ||
import kotlinx.datetime.plus | ||
import kotlinx.datetime.toLocalDateTime | ||
import mu.KotlinLogging | ||
import org.loculus.backend.config.logger | ||
import org.loculus.backend.controller.BadRequestException | ||
|
||
enum class DataUseTermsType { | ||
OPEN, | ||
RESTRICTED, | ||
} | ||
|
||
val logger = KotlinLogging.logger { } | ||
|
||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") | ||
@JsonSubTypes( | ||
JsonSubTypes.Type(value = DataUseTerms.Open::class, name = "OPEN"), | ||
JsonSubTypes.Type(value = DataUseTerms.Restricted::class, name = "RESTRICTED"), | ||
) | ||
@JsonPropertyOrder(value = ["type", "restrictedUntil", "changeDateTime"]) | ||
sealed interface DataUseTerms { | ||
val type: DataUseTermsType | ||
|
||
@JsonTypeName("OPEN") | ||
data class Open(private val dummy: String = "") : | ||
DataUseTerms { | ||
@JsonIgnore | ||
override val type = DataUseTermsType.OPEN | ||
} | ||
|
||
@JsonTypeName("RESTRICTED") | ||
data class Restricted( | ||
@JsonSerialize(using = LocalDateSerializer::class) | ||
val restrictedUntil: LocalDate, | ||
) : DataUseTerms { | ||
@JsonIgnore | ||
override val type = DataUseTermsType.RESTRICTED | ||
} | ||
|
||
companion object { | ||
fun fromParameters(type: DataUseTermsType, restrictedUntilString: String?): DataUseTerms { | ||
logger.info { "Creating DataUseTerms from parameters: type=$type, restrictedUntil=$restrictedUntilString" } | ||
return when (type) { | ||
DataUseTermsType.OPEN -> Open() | ||
DataUseTermsType.RESTRICTED -> { | ||
val restrictedUntil = parseRestrictedUntil(restrictedUntilString) | ||
validateRestrictedUntil(restrictedUntil) | ||
Restricted(restrictedUntil) | ||
} | ||
} | ||
} | ||
|
||
private fun parseRestrictedUntil(restrictedUntilString: String?): LocalDate { | ||
if (restrictedUntilString == null) { | ||
throw BadRequestException("The date 'restrictedUntil' must be set if 'dataUseTermsType' is RESTRICTED.") | ||
} | ||
return try { | ||
LocalDate.parse(restrictedUntilString) | ||
} catch (e: Exception) { | ||
throw BadRequestException( | ||
"The date 'restrictedUntil' must be a valid date in the format YYYY-MM-DD: $restrictedUntilString.", | ||
) | ||
} | ||
} | ||
|
||
private fun validateRestrictedUntil(restrictedUntil: LocalDate) { | ||
val now = Clock.System.now().toLocalDateTime(TimeZone.UTC).date | ||
val oneYearFromNow = now.plus(1, YEAR) | ||
|
||
if (restrictedUntil < now) { | ||
throw BadRequestException( | ||
"The date 'restrictedUntil' must be in the future, up to a maximum of 1 year from now.", | ||
) | ||
} | ||
if (restrictedUntil > oneYearFromNow) { | ||
throw BadRequestException( | ||
"The date 'restrictedUntil' must not exceed 1 year from today.", | ||
) | ||
} | ||
} | ||
} | ||
} | ||
|
||
class LocalDateSerializer : StdSerializer<LocalDate>(LocalDate::class.java) { | ||
override fun serialize(value: LocalDate, gen: JsonGenerator, provider: SerializerProvider) { | ||
gen.writeString(value.toString()) | ||
} | ||
} | ||
|
||
class LocalDateTimeSerializer : StdSerializer<LocalDateTime>(LocalDateTime::class.java) { | ||
override fun serialize(value: LocalDateTime, gen: JsonGenerator, provider: SerializerProvider) { | ||
gen.writeString(value.toString()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 18 additions & 26 deletions
44
...d/src/main/kotlin/org/loculus/backend/service/datauseterms/DataUseTermsDatabaseService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,42 @@ | ||
package org.loculus.backend.service.datauseterms | ||
|
||
import kotlinx.datetime.Clock | ||
import kotlinx.datetime.LocalDateTime | ||
import kotlinx.datetime.TimeZone | ||
import kotlinx.datetime.toLocalDateTime | ||
import mu.KotlinLogging | ||
import org.jetbrains.exposed.exceptions.ExposedSQLException | ||
import org.jetbrains.exposed.sql.insert | ||
import org.jetbrains.exposed.sql.batchInsert | ||
import org.loculus.backend.api.DataUseTerms | ||
import org.springframework.stereotype.Service | ||
import org.springframework.transaction.annotation.Transactional | ||
|
||
enum class DataUseTermsType { | ||
RESTRICTED, | ||
OPEN, | ||
} | ||
|
||
data class DataUseTerms( | ||
val restrictedUntil: LocalDateTime? = null, | ||
val changeDateTime: LocalDateTime = Clock.System.now().toLocalDateTime(TimeZone.UTC), | ||
val dataUseTermsType: DataUseTermsType = DataUseTermsType.OPEN, | ||
) | ||
|
||
private val log = KotlinLogging.logger { } | ||
|
||
@Service | ||
@Transactional | ||
class DataUseTermsDatabaseService { | ||
|
||
fun setNewDataUseTerms(accession: String, username: String, newDataUseTerms: DataUseTerms) { | ||
fun setNewDataUseTerms(accessions: List<String>, username: String, newDataUseTerms: DataUseTerms) { | ||
log.info { | ||
"Setting new data use terms for accession $accession. " + | ||
"Setting new data use terms for accessions $accessions. " + | ||
"Just an entry in the new Table. " + | ||
"Will be filled with real juicy logic in the next tickets. See #760 ff. " | ||
} | ||
val now = Clock.System.now().toLocalDateTime(TimeZone.UTC) | ||
try { | ||
DataUseTermsTable.insert { | ||
it[accessionColumn] = accession | ||
it[changeDateColumn] = now | ||
it[dataUseTermsTypeColumn] = newDataUseTerms.dataUseTermsType | ||
it[restrictedUntilColumn] = newDataUseTerms.restrictedUntil | ||
it[userNameColumn] = username | ||
|
||
DataUseTermsTable.batchInsert(accessions) { | ||
this[DataUseTermsTable.accessionColumn] = it | ||
this[DataUseTermsTable.changeDateColumn] = now | ||
this[DataUseTermsTable.dataUseTermsTypeColumn] = newDataUseTerms.type | ||
this[DataUseTermsTable.restrictedUntilColumn] = when (newDataUseTerms) { | ||
is DataUseTerms.Restricted -> { | ||
newDataUseTerms.restrictedUntil | ||
} | ||
|
||
else -> { | ||
null | ||
} | ||
} | ||
} catch (e: ExposedSQLException) { | ||
log.info("Error: ${e.sqlState}") | ||
throw e | ||
this[DataUseTermsTable.userNameColumn] = username | ||
} | ||
} | ||
} |
4 changes: 3 additions & 1 deletion
4
backend/src/main/kotlin/org/loculus/backend/service/datauseterms/DataUseTermsTables.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,16 @@ | ||
package org.loculus.backend.service.datauseterms | ||
|
||
import org.jetbrains.exposed.sql.Table | ||
import org.jetbrains.exposed.sql.kotlin.datetime.date | ||
import org.jetbrains.exposed.sql.kotlin.datetime.datetime | ||
import org.loculus.backend.api.DataUseTermsType | ||
|
||
const val DATA_USE_TERMS_TABLE_NAME = "data_use_terms_table" | ||
|
||
object DataUseTermsTable : Table(DATA_USE_TERMS_TABLE_NAME) { | ||
val accessionColumn = text("accession") | ||
val changeDateColumn = datetime("change_date") | ||
val dataUseTermsTypeColumn = enumeration("data_use_terms_type", DataUseTermsType::class) | ||
val restrictedUntilColumn = datetime("restricted_until").nullable() | ||
val restrictedUntilColumn = date("restricted_until").nullable() | ||
val userNameColumn = text("user_name") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.