Формат времени в UTC

This commit is contained in:
emelianov
2026-06-25 16:21:17 +03:00
parent d0ec0ef754
commit fe54c095ab
164 changed files with 1847 additions and 634 deletions
@@ -0,0 +1,55 @@
package space.nstart.pcp.routepassportconsumer.config
import org.springframework.boot.jackson.autoconfigure.JsonMapperBuilderCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.core.convert.converter.Converter
import org.springframework.format.FormatterRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
import space.nstart.pcp.pcp_types_lib.utils.UtcDateTimes
import tools.jackson.core.JsonGenerator
import tools.jackson.core.JsonParser
import tools.jackson.databind.DeserializationContext
import tools.jackson.databind.SerializationContext
import tools.jackson.databind.deser.std.StdDeserializer
import tools.jackson.databind.module.SimpleModule
import tools.jackson.databind.ser.std.StdSerializer
import java.time.Clock
import java.time.LocalDateTime
@Configuration
class UtcTimeConfiguration : WebMvcConfigurer {
@Bean
fun clock(): Clock = Clock.systemUTC()
@Bean
fun routeProcessingUtcLocalDateTimeCustomizer(): JsonMapperBuilderCustomizer = JsonMapperBuilderCustomizer { builder ->
builder.addModule(
SimpleModule("pcp-route-processing-service-utc-local-date-time")
.addSerializer(LocalDateTime::class.java, UtcLocalDateTimeSerializer())
.addDeserializer(LocalDateTime::class.java, UtcLocalDateTimeDeserializer())
)
}
override fun addFormatters(registry: FormatterRegistry) {
registry.addConverter(UtcLocalDateTimeQueryParamConverter())
}
}
private class UtcLocalDateTimeQueryParamConverter : Converter<String, LocalDateTime> {
override fun convert(source: String): LocalDateTime = UtcDateTimes.parse(source)
}
private class UtcLocalDateTimeSerializer : StdSerializer<LocalDateTime>(LocalDateTime::class.java) {
override fun serialize(value: LocalDateTime, gen: JsonGenerator, ctxt: SerializationContext) {
gen.writeString(UtcDateTimes.format(value))
}
}
private class UtcLocalDateTimeDeserializer : StdDeserializer<LocalDateTime>(LocalDateTime::class.java) {
override fun deserialize(p: JsonParser, ctxt: DeserializationContext): LocalDateTime {
val value = p.valueAsString ?: throw IllegalArgumentException("Expected ISO-8601 UTC date-time string")
return UtcDateTimes.parse(value)
}
}
@@ -18,6 +18,7 @@ import com.fasterxml.jackson.databind.ObjectMapper as JpaJsonObjectMapper
import tools.jackson.databind.ObjectMapper
import java.time.LocalDateTime
import java.util.UUID
import space.nstart.pcp.pcp_types_lib.utils.UtcDateTimes
/**
* Сохраняет разобранный route passport и outbox-события в одной DB transaction.
@@ -38,7 +39,7 @@ class RoutePassportIngestionService(
rawPayload: String,
sourceRecord: RoutePassportSourceRecordMetadata,
) {
val now = LocalDateTime.now()
val now = UtcDateTimes.now()
val routePassportDto = parsedMessage.routePassportDto
val existingRoutePassport = routePassportRepository.findById(routePassportDto.routeId)
val routeCreated = existingRoutePassport.isEmpty
@@ -8,11 +8,11 @@ import space.nstart.pcp.pcp_types_lib.dto.routes.RawPassportEnvelopeDto
import space.nstart.pcp.pcp_types_lib.dto.routes.RoutePassportDto
import space.nstart.pcp.pcp_types_lib.dto.routes.RoutePassportMessageMetadata
import space.nstart.pcp.routepassportconsumer.exception.RoutePassportContractException
import space.nstart.pcp.pcp_types_lib.utils.UtcDateTimes
import tools.jackson.core.JacksonException
import tools.jackson.databind.ObjectMapper
import java.math.BigDecimal
import java.nio.charset.StandardCharsets
import java.time.LocalDateTime
import java.util.UUID
/**
@@ -63,8 +63,8 @@ class RoutePassportJsonParserService(
routeNameShort = collection,
orbitNumber = properties.orbitNumber.toLong(),
orbitState = properties.orbitState,
intervalBegin = LocalDateTime.parse(properties.intervalBegin),
intervalEnd = LocalDateTime.parse(properties.intervalEnd),
intervalBegin = UtcDateTimes.parse(properties.intervalBegin),
intervalEnd = UtcDateTimes.parse(properties.intervalEnd),
rollAngle = properties.rollAngle.toAngleRangeDto(fieldName = "rollAngle"),
visirAngle = properties.visirAngle.toAngleRangeDto(fieldName = "visirAngle"),
resolutionRange = properties.resolutionRange.toBigDecimal(),
@@ -10,6 +10,7 @@ import space.nstart.pcp.routepassportconsumer.repository.RoutePassportOutboxRepo
import java.time.Duration
import java.time.LocalDateTime
import java.util.UUID
import space.nstart.pcp.pcp_types_lib.utils.UtcDateTimes
/**
* Owns transactional claim and status transitions for route passport outbox rows.
@@ -32,7 +33,7 @@ class RoutePassportOutboxService(
return emptyList()
}
val now = LocalDateTime.now()
val now = UtcDateTimes.now()
val lockedUntil = now.plus(Duration.ofMillis(outboxProperties.lockTimeoutMs))
val claimedRows = routePassportOutboxRepository.findDueForUpdateSkipLocked(outboxProperties.batchSize)
@@ -70,7 +71,7 @@ class RoutePassportOutboxService(
*/
@Transactional
fun markPublished(outboxId: UUID) {
val now = LocalDateTime.now()
val now = UtcDateTimes.now()
val outbox = findOutbox(outboxId)
outbox.status = RoutePassportOutboxStatus.PUBLISHED
@@ -99,7 +100,7 @@ class RoutePassportOutboxService(
*/
@Transactional
fun markRetryOrFailed(outboxId: UUID, exception: Exception) {
val now = LocalDateTime.now()
val now = UtcDateTimes.now()
val outbox = findOutbox(outboxId)
outbox.attempts += 1