Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package dk.cachet.carp.webservices.common.audit

import dk.cachet.carp.webservices.common.converter.InstantConverter
import jakarta.persistence.Convert
import jakarta.persistence.EntityListeners
import jakarta.persistence.MappedSuperclass
import kotlinx.datetime.Instant
import org.springframework.data.annotation.CreatedBy
import org.springframework.data.annotation.CreatedDate
import org.springframework.data.annotation.LastModifiedBy
import org.springframework.data.annotation.LastModifiedDate
import org.springframework.data.jpa.domain.support.AuditingEntityListener
import java.time.Instant

/**
* The Class [Auditable].
Expand All @@ -22,6 +24,7 @@ abstract class Auditable {

/** The [createdAt] time of creation. */
@CreatedDate
@Convert(converter = InstantConverter::class)
var createdAt: Instant? = null

/** The [updatedBy] the ID of the user the entity was updated by. */
Expand All @@ -30,5 +33,6 @@ abstract class Auditable {

/** The [updatedAt] last time the entity was updated. */
@LastModifiedDate
@Convert(converter = InstantConverter::class)
var updatedAt: Instant? = null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package dk.cachet.carp.webservices.common.audit

import org.springframework.data.auditing.DateTimeProvider
import java.time.temporal.TemporalAccessor
import java.util.*
import java.time.Instant as JavaInstant

/**
* Overrides the default behaviour: java.time.LocalDateTime -> java.time.Instant
*/

class EntityDateTimeProvider : DateTimeProvider {
override fun getNow(): Optional<TemporalAccessor> {
return Optional.of(JavaInstant.now())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@ import org.springframework.data.jpa.repository.config.EnableJpaAuditing
* The [JpaAuditConfiguration] implements the configuration logic for the [EntityAuditorAware].
*/
@Configuration
@EnableJpaAuditing(auditorAwareRef = "auditorAware")
@EnableJpaAuditing(auditorAwareRef = "auditorAware", dateTimeProviderRef = "dateTimeProvider")
class JpaAuditConfiguration(private val authenticationService: AuthenticationService) {
/**
* The function [auditorAware] returns the current auditor of the application.
*/
@Bean("auditorAware")
fun auditorAware(): AuditorAware<String> = EntityAuditorAware(authenticationService)

/**
* The function [dateTimeProvider] returns the current date and time.
*/
@Bean("dateTimeProvider")
fun dateTimeProvider(): EntityDateTimeProvider = EntityDateTimeProvider()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package dk.cachet.carp.webservices.common.converter

import jakarta.persistence.AttributeConverter
import jakarta.persistence.Converter
import kotlinx.datetime.toJavaInstant
import kotlinx.datetime.toKotlinInstant
import java.time.Instant
import java.time.Instant as JavaInstant
import kotlinx.datetime.Instant as KotlinInstant

@Converter
class InstantConverter : AttributeConverter<KotlinInstant, JavaInstant> {
override fun convertToDatabaseColumn(p0: kotlinx.datetime.Instant?): Instant? {
if (p0 == null) return null

return p0.toJavaInstant()
}

override fun convertToEntityAttribute(p0: Instant?): kotlinx.datetime.Instant? {
if (p0 == null) return null

return p0.toKotlinInstant()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import dk.cachet.carp.webservices.common.input.WS_JSON
import dk.cachet.carp.webservices.protocol.domain.Protocol
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.datetime.Instant
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
import org.springframework.stereotype.Service
Expand Down Expand Up @@ -129,7 +128,7 @@ class CoreProtocolRepository(
validationMessages.get("protocol.version_history.not_found", id.stringRepresentation)
}
protocols.map {
ProtocolVersion(it.versionTag, Instant.fromEpochMilliseconds(it.createdAt!!.toEpochMilli()))
ProtocolVersion(it.versionTag, it.createdAt!!)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import dk.cachet.carp.webservices.protocol.service.ProtocolService
import dk.cachet.carp.webservices.security.authentication.domain.Account
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.datetime.toKotlinInstant
import org.springframework.stereotype.Service

@Service
Expand Down Expand Up @@ -61,8 +60,8 @@ class ProtocolServiceWrapper(

return ProtocolOverview(
owner?.fullName,
versions.first().createdAt?.toKotlinInstant(),
versions.last().createdAt?.toKotlinInstant(),
versions.first().createdAt,
versions.last().createdAt,
versions.last().versionTag,
snapshot,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.test.runTest
import kotlinx.datetime.Clock
import kotlinx.datetime.toJavaInstant
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Nested
import kotlin.test.Test
Expand Down Expand Up @@ -62,12 +61,12 @@ class ProtocolServiceTest {
mockk<Protocol> {
every { versionTag } returns "version 1"
every { snapshot } returns mockk<JsonNode>()
every { createdAt } returns yesterday.toJavaInstant()
every { createdAt } returns yesterday
},
mockk<Protocol> {
every { versionTag } returns "version 2"
every { snapshot } returns mockk<JsonNode>()
every { createdAt } returns now.toJavaInstant()
every { createdAt } returns now
},
)

Expand Down