Формат времени в 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,41 @@
package space.nstart.pcp.tle_monitoring_service.configuration
import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.JsonSerializer
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import space.nstart.pcp.pcp_types_lib.utils.UtcDateTimes
import java.time.LocalDateTime
@Configuration
class Jackson2UtcConfiguration {
@Bean
fun jackson2ObjectMapper(): ObjectMapper = jacksonObjectMapper()
.findAndRegisterModules()
.registerModule(utcLocalDateTimeModule())
}
private fun utcLocalDateTimeModule(): SimpleModule = SimpleModule("tle-monitoring-service-jackson2-utc-local-date-time")
.addSerializer(LocalDateTime::class.java, Jackson2UtcLocalDateTimeSerializer())
.addDeserializer(LocalDateTime::class.java, Jackson2UtcLocalDateTimeDeserializer())
private class Jackson2UtcLocalDateTimeSerializer : JsonSerializer<LocalDateTime>() {
override fun serialize(value: LocalDateTime, gen: JsonGenerator, serializers: SerializerProvider) {
gen.writeString(UtcDateTimes.format(value))
}
}
private class Jackson2UtcLocalDateTimeDeserializer : JsonDeserializer<LocalDateTime>() {
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)
}
}
@@ -0,0 +1,55 @@
package space.nstart.pcp.tle_monitoring_service.configuration
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 tleMonitoringUtcLocalDateTimeCustomizer(): JsonMapperBuilderCustomizer = JsonMapperBuilderCustomizer { builder ->
builder.addModule(
SimpleModule("tle-monitoring-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)
}
}
@@ -27,6 +27,11 @@ class TLEController {
@Autowired
private lateinit var celestrakService: CelesTrakService
@PostMapping("/satellite/{satelliteId}")
fun sendTLE(@PathVariable satelliteId: Long, @RequestBody tle : TLEDTO) =
celestrakService.sendTLE(satelliteId, tle)
@GetMapping()
fun all(): List<TLEExtensionDTO> {
logger.info("TLE API all records request started")
@@ -1,6 +1,7 @@
package space.nstart.pcp.tle_monitoring_service.entity
import jakarta.persistence.*
import space.nstart.pcp.pcp_types_lib.utils.UtcDateTimes
import java.time.LocalDateTime
@@ -22,5 +23,5 @@ class TLEEntity (
val tle : String = "",
var timeTle : LocalDateTime? = null,
@Column(name = "time_rec", nullable = false)
val timeRec : LocalDateTime = LocalDateTime.now()
val timeRec : LocalDateTime = UtcDateTimes.now()
)
@@ -17,11 +17,13 @@ import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import space.nstart.pcp.pcp_types_lib.dto.ballistics.TLEDTO
import space.nstart.pcp.pcp_types_lib.message.KafkaMessage
import space.nstart.pcp.pcp_types_lib.utils.UtcDateTimes
import space.nstart.pcp.pcp_types_lib.message.PcpKafkaEvent
import space.nstart.pcp.tle_monitoring_service.configuration.CustomErrorException
import space.nstart.pcp.tle_monitoring_service.entity.TLEEntity
import space.nstart.pcp.tle_monitoring_service.message.KafkaProducer
import space.nstart.pcp.tle_monitoring_service.repository.TLERepository
import java.time.Clock
import java.time.Duration
import java.time.LocalDateTime
import java.util.UUID
@@ -34,6 +36,7 @@ import kotlin.text.split
class CelesTrakService(
private val webClient: WebClient,
private val pollingSettingsService: TlePollingSettingsService,
private val clock: Clock = Clock.systemUTC(),
) {
private val logger = LoggerFactory.getLogger(this::class.java)
private val objectMapper = jacksonObjectMapper()
@@ -130,6 +133,10 @@ class CelesTrakService(
}
fun sendTLE(satelliteId : Long, tle : TLEDTO){
mkTle(tle, satelliteId, true, true)
}
/**
* Получение TLE в сыром текстовом формате
@@ -303,7 +310,7 @@ class CelesTrakService(
.sortedBy { tle -> tle.timeTle }
var first = true
var vit = 0
var tVuz = LocalDateTime.now()
var tVuz = UtcDateTimes.now(clock)
var lVuz = 0.0
for(t in tles){
var s = t.tle.split("\r\n")
@@ -4,6 +4,7 @@ import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import space.nstart.pcp.tle_monitoring_service.configuration.CustomValidationException
import space.nstart.pcp.tle_monitoring_service.configuration.TlePollingProperties
import java.time.Clock
import java.time.Duration
import java.time.Instant
import java.util.concurrent.atomic.AtomicBoolean
@@ -21,7 +22,10 @@ data class UpdateTlePollingSettingsRequest(
)
@Service
class TlePollingSettingsService(properties: TlePollingProperties) {
class TlePollingSettingsService(
properties: TlePollingProperties,
private val clock: Clock = Clock.systemUTC(),
) {
private val logger = LoggerFactory.getLogger(this::class.java)
private val enabled = AtomicBoolean(properties.enabled)
private val timeoutSeconds = AtomicLong(validateTimeout(properties.timeoutSeconds))
@@ -55,7 +59,7 @@ class TlePollingSettingsService(properties: TlePollingProperties) {
return settings
}
fun shouldStartPolling(now: Instant = Instant.now()): Boolean {
fun shouldStartPolling(now: Instant = clock.instant()): Boolean {
if (!enabled.get()) {
return false
}
@@ -64,7 +68,7 @@ class TlePollingSettingsService(properties: TlePollingProperties) {
return Duration.between(lastStartedAt, now).seconds >= timeoutSeconds.get()
}
fun markPollingStarted(now: Instant = Instant.now()) {
fun markPollingStarted(now: Instant = clock.instant()) {
lastPollStartedAt.set(now)
}