Merge branch 'dev' into route-processing
Conflict resolution: - build.gradle.kts: dev version (keep nstart.cloud repo + jacoco/asm mavenCentral) - settings.gradle.kts: project name from route-processing (observatio-terrae), rest from dev - config addresses (application-local, pcp-mission-planing-service, pcp-dynamic-plan application.yaml): dev versions - menu.html: merged both branches (TGU planning + bookings items) - CatalogControllerTest.kt: merged both mocks (TguPlanningService + BallisticsService) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+20
@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.Operation
|
||||
import io.swagger.v3.oas.annotations.Parameter
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
@@ -11,9 +12,11 @@ import org.springframework.web.bind.annotation.RequestBody
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RequestParam
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import space.nstart.pcp.pcp_request_service.service.SatelliteIcEventService
|
||||
import space.nstart.pcp.pcp_request_service.service.SatelliteService
|
||||
import space.nstart.pcp.pcp_types_lib.configuration.CustomValidationException
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.ExactTimePositionRequestDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.SatelliteICDTO
|
||||
import java.time.LocalDateTime
|
||||
|
||||
|
||||
@@ -23,6 +26,9 @@ class SatelliteController {
|
||||
@Autowired
|
||||
private lateinit var satelliteService: SatelliteService
|
||||
|
||||
@Autowired
|
||||
private lateinit var satelliteIcEventService: SatelliteIcEventService
|
||||
|
||||
@PostMapping("/{satellite_id}/extract-time")
|
||||
fun extractTime(
|
||||
@PathVariable("satellite_id") satelliteId : Long,
|
||||
@@ -30,6 +36,20 @@ class SatelliteController {
|
||||
) =
|
||||
satelliteService.exactTime(satelliteId, body)
|
||||
|
||||
@PostMapping("/receive-rv")
|
||||
fun receiveRv(@RequestBody body: SatelliteICDTO): ResponseEntity<Void> {
|
||||
satelliteIcEventService.handlePlacedIcRv(body)
|
||||
return ResponseEntity.accepted().build()
|
||||
}
|
||||
|
||||
@GetMapping("/{satellite_id}/initial-conditions/current")
|
||||
fun currentInitialConditions(
|
||||
@PathVariable("satellite_id") satelliteId: Long
|
||||
): ResponseEntity<SatelliteICDTO> =
|
||||
satelliteService.currentInitialConditions(satelliteId)
|
||||
?.let { ResponseEntity.ok(it) }
|
||||
?: ResponseEntity.noContent().build()
|
||||
|
||||
|
||||
|
||||
@Operation(
|
||||
|
||||
+4
-3
@@ -1,15 +1,13 @@
|
||||
package space.nstart.pcp.pcp_request_service.controller
|
||||
|
||||
import ballistics.types.OrbitalPoint
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RequestBody
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import space.nstart.pcp.pcp_request_service.service.TLEService
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.OrbPointDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.TLEDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.TlePointRequestDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.TleRvaRequestDTO
|
||||
|
||||
@RestController
|
||||
@@ -23,6 +21,9 @@ class TLEController {
|
||||
@PostMapping("/parse")
|
||||
fun orbit(@RequestBody tle : TLEDTO) = tleService.parseTLE(tle)
|
||||
|
||||
@PostMapping("/point")
|
||||
fun point(@RequestBody req: TlePointRequestDTO) = tleService.point(req)
|
||||
|
||||
|
||||
@PostMapping("/rva")
|
||||
fun rva(@RequestBody req : TleRvaRequestDTO) = tleService.rva(req)
|
||||
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
package space.nstart.pcp.pcp_request_service.entity
|
||||
|
||||
import jakarta.persistence.Column
|
||||
import jakarta.persistence.Entity
|
||||
import jakarta.persistence.EnumType
|
||||
import jakarta.persistence.Enumerated
|
||||
import jakarta.persistence.GeneratedValue
|
||||
import jakarta.persistence.GenerationType
|
||||
import jakarta.persistence.Id
|
||||
import jakarta.persistence.Table
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.InitialConditionsDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.MovementModel
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.OrbPointDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.SatelliteICDTO
|
||||
import java.time.LocalDateTime
|
||||
|
||||
@Entity
|
||||
@Table(name = "satellite_initial_conditions")
|
||||
class SatelliteInitialConditionEntity(
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "satellite_initial_condition_id")
|
||||
val id: Long? = null,
|
||||
@Column(name = "satellite_id", nullable = false)
|
||||
val satelliteId: Long = 0,
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "movement_model", nullable = false)
|
||||
val movementModel: MovementModel = MovementModel.FOTO,
|
||||
@Column(name = "orb_time", nullable = false)
|
||||
val orbTime: LocalDateTime = LocalDateTime.now(),
|
||||
@Column(name = "orb_revolution", nullable = false)
|
||||
val orbRevolution: Long = 0,
|
||||
@Column(nullable = false)
|
||||
val x: Double = 0.0,
|
||||
@Column(nullable = false)
|
||||
val y: Double = 0.0,
|
||||
@Column(nullable = false)
|
||||
val z: Double = 0.0,
|
||||
@Column(nullable = false)
|
||||
val vx: Double = 0.0,
|
||||
@Column(nullable = false)
|
||||
val vy: Double = 0.0,
|
||||
@Column(nullable = false)
|
||||
val vz: Double = 0.0,
|
||||
@Column(name = "s_ball", nullable = false)
|
||||
val sBall: Double = 0.0,
|
||||
@Column(nullable = false)
|
||||
val f81: Double = 147.8,
|
||||
@Column(name = "received_at", nullable = false)
|
||||
val receivedAt: LocalDateTime = LocalDateTime.now(),
|
||||
@Column(name = "calculated_at")
|
||||
var calculatedAt: LocalDateTime? = null,
|
||||
@Column(name = "last_calculated", nullable = false)
|
||||
var lastCalculated: Boolean = false
|
||||
) {
|
||||
constructor(request: SatelliteICDTO) : this(
|
||||
satelliteId = request.satelliteId,
|
||||
movementModel = request.movementModel,
|
||||
orbTime = request.ic.orbPoint.time,
|
||||
orbRevolution = request.ic.orbPoint.revolution,
|
||||
x = request.ic.orbPoint.x,
|
||||
y = request.ic.orbPoint.y,
|
||||
z = request.ic.orbPoint.z,
|
||||
vx = request.ic.orbPoint.vx,
|
||||
vy = request.ic.orbPoint.vy,
|
||||
vz = request.ic.orbPoint.vz,
|
||||
sBall = request.ic.sBall,
|
||||
f81 = request.ic.f81
|
||||
)
|
||||
|
||||
fun markLastCalculated(calculatedAt: LocalDateTime = LocalDateTime.now()) {
|
||||
this.calculatedAt = calculatedAt
|
||||
this.lastCalculated = true
|
||||
}
|
||||
|
||||
fun toDto() = SatelliteICDTO(
|
||||
satelliteId = satelliteId,
|
||||
movementModel = movementModel,
|
||||
ic = InitialConditionsDTO(
|
||||
orbPoint = OrbPointDTO(
|
||||
time = orbTime,
|
||||
revolution = orbRevolution,
|
||||
vx = vx,
|
||||
vy = vy,
|
||||
vz = vz,
|
||||
x = x,
|
||||
y = y,
|
||||
z = z
|
||||
),
|
||||
sBall = sBall,
|
||||
f81 = f81
|
||||
)
|
||||
)
|
||||
}
|
||||
+7
@@ -6,6 +6,7 @@ import org.springframework.kafka.annotation.KafkaListener
|
||||
import org.springframework.stereotype.Component
|
||||
import space.nstart.pcp.pcp_request_service.service.SatelliteIcEventService
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.InitialConditionsDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.MovementModel
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.SatelliteICDTO
|
||||
import tools.jackson.databind.ObjectMapper
|
||||
import tools.jackson.databind.node.ObjectNode
|
||||
@@ -52,6 +53,11 @@ class SatelliteIcRvKafkaListener(
|
||||
*/
|
||||
private fun normalizePayload(payloadNode: tools.jackson.databind.JsonNode): tools.jackson.databind.JsonNode {
|
||||
val normalizedPayload = payloadNode.deepCopy()
|
||||
if (normalizedPayload is ObjectNode &&
|
||||
(normalizedPayload["movementModel"] == null || normalizedPayload["movementModel"].isNull)
|
||||
) {
|
||||
normalizedPayload.put("movementModel", DEFAULT_MOVEMENT_MODEL.name)
|
||||
}
|
||||
val initialConditionsNode = normalizedPayload["ic"]
|
||||
if (initialConditionsNode is ObjectNode) {
|
||||
if (initialConditionsNode["sBall"] == null || initialConditionsNode["sBall"].isNull) {
|
||||
@@ -66,5 +72,6 @@ class SatelliteIcRvKafkaListener(
|
||||
|
||||
companion object {
|
||||
private val DEFAULT_INITIAL_CONDITIONS = InitialConditionsDTO()
|
||||
private val DEFAULT_MOVEMENT_MODEL = MovementModel.FOTO
|
||||
}
|
||||
}
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package space.nstart.pcp.pcp_request_service.repository
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
import org.springframework.data.jpa.repository.Modifying
|
||||
import org.springframework.data.jpa.repository.Query
|
||||
import org.springframework.data.repository.query.Param
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import space.nstart.pcp.pcp_request_service.entity.SatelliteInitialConditionEntity
|
||||
|
||||
interface SatelliteInitialConditionRepository : JpaRepository<SatelliteInitialConditionEntity, Long> {
|
||||
fun findFirstBySatelliteIdAndLastCalculatedTrueOrderByCalculatedAtDescIdDesc(
|
||||
satelliteId: Long
|
||||
): SatelliteInitialConditionEntity?
|
||||
|
||||
@Modifying
|
||||
@Transactional
|
||||
@Query(
|
||||
"""
|
||||
update SatelliteInitialConditionEntity entity
|
||||
set entity.lastCalculated = false
|
||||
where entity.satelliteId = :satelliteId
|
||||
and entity.lastCalculated = true
|
||||
"""
|
||||
)
|
||||
fun clearLastCalculated(@Param("satelliteId") satelliteId: Long): Int
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package space.nstart.pcp.pcp_request_service.service
|
||||
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import space.nstart.pcp.pcp_request_service.entity.SatelliteInitialConditionEntity
|
||||
import space.nstart.pcp.pcp_request_service.repository.SatelliteInitialConditionRepository
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.SatelliteICDTO
|
||||
|
||||
@Service
|
||||
class SatelliteInitialConditionService(
|
||||
private val satelliteInitialConditionRepository: SatelliteInitialConditionRepository
|
||||
) {
|
||||
|
||||
@Transactional
|
||||
fun saveReceived(request: SatelliteICDTO): SatelliteInitialConditionEntity =
|
||||
satelliteInitialConditionRepository.save(SatelliteInitialConditionEntity(request))
|
||||
|
||||
@Transactional
|
||||
fun markLastCalculated(initialCondition: SatelliteInitialConditionEntity) {
|
||||
satelliteInitialConditionRepository.clearLastCalculated(initialCondition.satelliteId)
|
||||
initialCondition.markLastCalculated()
|
||||
satelliteInitialConditionRepository.save(initialCondition)
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
fun current(satelliteId: Long): SatelliteICDTO? =
|
||||
satelliteInitialConditionRepository
|
||||
.findFirstBySatelliteIdAndLastCalculatedTrueOrderByCalculatedAtDescIdDesc(satelliteId)
|
||||
?.toDto()
|
||||
}
|
||||
+28
-3
@@ -7,6 +7,7 @@ import ballistics.types.EarthType
|
||||
import ballistics.types.FleghtLineSector
|
||||
import ballistics.types.InitialConditions
|
||||
import ballistics.types.KeplerParams
|
||||
import ballistics.types.ModDVType
|
||||
import ballistics.types.OPKatObj
|
||||
import ballistics.types.OrbitalPoint
|
||||
import ballistics.types.PPI
|
||||
@@ -46,6 +47,7 @@ import space.nstart.pcp.pcp_request_service.utils.ContourClipService
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.AscNodeDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.ExactTimePositionRequestDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.InitialConditionsDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.MovementModel
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.ObjDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.OrbPointDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.PointViewParamDTO
|
||||
@@ -87,6 +89,10 @@ class SatelliteService {
|
||||
|
||||
@Autowired
|
||||
private lateinit var pdcmRepository: PDCMRepository
|
||||
|
||||
@Autowired
|
||||
private lateinit var satelliteInitialConditionService: SatelliteInitialConditionService
|
||||
|
||||
@Autowired
|
||||
private lateinit var ascNodeRepository: AscNodeRepository
|
||||
@Autowired
|
||||
@@ -183,9 +189,11 @@ class SatelliteService {
|
||||
)
|
||||
|
||||
suspend fun resieveRV(rv: SatelliteICDTO) {
|
||||
val savedInitialCondition = satelliteInitialConditionService.saveReceived(rv)
|
||||
val bal = Ballistics()
|
||||
bal.modDVType = rv.movementModel.toModDVType()
|
||||
|
||||
logger.info("Начало расчета баллистики по RV id = ${rv.satelliteId}")
|
||||
logger.info("Начало расчета баллистики по RV id = ${rv.satelliteId}, model = ${rv.movementModel}")
|
||||
|
||||
bal.rollMax = (45.0 * PI / 180.0)
|
||||
bal.rollMin = (20.0 * PI / 180.0)
|
||||
@@ -227,10 +235,25 @@ class SatelliteService {
|
||||
|
||||
prepareEarthCovering(bal, rv.satelliteId)
|
||||
|
||||
satelliteInitialConditionService.markLastCalculated(savedInitialCondition)
|
||||
|
||||
bal.clear()
|
||||
logger.info("Расчет для КА ${rv.satelliteId} завершился успешно")
|
||||
}
|
||||
|
||||
fun currentInitialConditions(satelliteId: Long): SatelliteICDTO? =
|
||||
satelliteInitialConditionService.current(satelliteId)
|
||||
|
||||
private fun MovementModel.toModDVType(): ModDVType =
|
||||
when (this) {
|
||||
MovementModel.FOTO -> ModDVType.FOTO
|
||||
MovementModel.KONDOR -> ModDVType.KONDOR
|
||||
MovementModel.METEORM1 -> ModDVType.METEORM1
|
||||
MovementModel.METEORM2 -> ModDVType.METEORM2
|
||||
MovementModel.BARS -> ModDVType.BARS
|
||||
MovementModel.KONDOR_PROGNOZ -> ModDVType.KONDOR_PROGNOZ
|
||||
}
|
||||
|
||||
|
||||
fun mergeSectors(sectors: List<FleghtLineSector>): List<FleghtLineSector> {
|
||||
if (sectors.isEmpty()) return emptyList()
|
||||
@@ -851,8 +874,6 @@ class SatelliteService {
|
||||
return res
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun getAscNodes(id : Long, tn : LocalDateTime?, tk : LocalDateTime?) : List<AscNodeDTO> {
|
||||
|
||||
return ascNodeRepository.findBySatelliteIdAndTimeBetween(
|
||||
@@ -881,3 +902,7 @@ data class SatelliteBallisticsDeletionSummary(
|
||||
val earthCoverageDeleted: Int,
|
||||
val earthCellViewsDeleted: Int
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+34
@@ -1,7 +1,9 @@
|
||||
package space.nstart.pcp.pcp_request_service.service
|
||||
|
||||
import ballistics.Ballistics
|
||||
import ballistics.orbitalPoints.timeStepper.TLEStepper
|
||||
import ballistics.types.BallisticsError
|
||||
import ballistics.types.EarthType
|
||||
import ballistics.types.PPI
|
||||
import ballistics.types.TLE
|
||||
import ballistics.types.TLEParams
|
||||
@@ -15,6 +17,7 @@ import space.nstart.pcp.pcp_request_service.configuration.CustomValidationExcept
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.OrbPointDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.RadioVisibilityAreaDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.TLEDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.TlePointRequestDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.TargetPositionDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.TleRvaRequestDTO
|
||||
import kotlin.math.PI
|
||||
@@ -47,6 +50,37 @@ class TLEService() {
|
||||
|
||||
|
||||
|
||||
|
||||
fun point(req: TlePointRequestDTO): OrbPointDTO {
|
||||
val bal = Ballistics()
|
||||
val tleParams = try {
|
||||
bal.getTLEParams(TLE(req.tle.first, req.tle.second), req.tle.header ?: "empty")
|
||||
} catch (ex: Exception) {
|
||||
throw CustomValidationException("Ошибка формата TLE : ${ex.message}")
|
||||
}
|
||||
if (req.time < tleParams.time) {
|
||||
throw CustomValidationException("Время расчета должно быть не раньше эпохи TLE ${tleParams.time}")
|
||||
}
|
||||
|
||||
val point = try {
|
||||
val stepper = TLEStepper(req.tle.first, req.tle.second, EarthType.PZ90d02)
|
||||
stepper.calculate(fromDateTime(req.time))
|
||||
} catch (ex: Exception) {
|
||||
throw CustomErrorException("Ошибка расчета положения по TLE : ${ex.message}")
|
||||
}
|
||||
|
||||
return OrbPointDTO(
|
||||
toDateTime(point.t),
|
||||
point.vit.toLong(),
|
||||
point.v.x,
|
||||
point.v.y,
|
||||
point.v.z,
|
||||
point.r.x,
|
||||
point.r.y,
|
||||
point.r.z
|
||||
)
|
||||
}
|
||||
|
||||
fun rva(req : TleRvaRequestDTO) : Iterable<RadioVisibilityAreaDTO> {
|
||||
|
||||
val bal = Ballistics()
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
CREATE TABLE IF NOT EXISTS satellite_initial_conditions (
|
||||
satellite_initial_condition_id BIGSERIAL PRIMARY KEY,
|
||||
satellite_id BIGINT NOT NULL,
|
||||
movement_model VARCHAR(32) NOT NULL DEFAULT 'FOTO',
|
||||
orb_time TIMESTAMP NOT NULL,
|
||||
orb_revolution BIGINT NOT NULL,
|
||||
x DOUBLE PRECISION NOT NULL,
|
||||
y DOUBLE PRECISION NOT NULL,
|
||||
z DOUBLE PRECISION NOT NULL,
|
||||
vx DOUBLE PRECISION NOT NULL,
|
||||
vy DOUBLE PRECISION NOT NULL,
|
||||
vz DOUBLE PRECISION NOT NULL,
|
||||
s_ball DOUBLE PRECISION NOT NULL,
|
||||
f81 DOUBLE PRECISION NOT NULL,
|
||||
received_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
calculated_at TIMESTAMP,
|
||||
last_calculated BOOLEAN NOT NULL DEFAULT FALSE
|
||||
);
|
||||
|
||||
CREATE INDEX idx_satellite_initial_conditions_satellite_id ON satellite_initial_conditions(satellite_id);
|
||||
CREATE INDEX idx_satellite_initial_conditions_last_calculated ON satellite_initial_conditions(satellite_id, last_calculated);
|
||||
+5
-1
@@ -4,6 +4,7 @@ import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.beans.factory.ObjectProvider
|
||||
import space.nstart.pcp.pcp_request_service.service.SatelliteIcEventService
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.MovementModel
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.SatelliteICDTO
|
||||
import tools.jackson.databind.ObjectMapper
|
||||
|
||||
@@ -46,6 +47,7 @@ class SatelliteIcRvKafkaListenerTest {
|
||||
assertEquals(56756L, satelliteIcEventService.lastMessage?.satelliteId)
|
||||
assertEquals(42L, satelliteIcEventService.lastMessage?.ic?.orbPoint?.revolution)
|
||||
assertEquals(140.0, satelliteIcEventService.lastMessage?.ic?.f81)
|
||||
assertEquals(MovementModel.FOTO, satelliteIcEventService.lastMessage?.movementModel)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -54,8 +56,9 @@ class SatelliteIcRvKafkaListenerTest {
|
||||
"""
|
||||
{
|
||||
"type": "ICRVPlacedEvent",
|
||||
"data": {
|
||||
"data": {
|
||||
"satelliteId": 56756,
|
||||
"movementModel": null,
|
||||
"ic": {
|
||||
"orbPoint": {
|
||||
"time": "2026-04-16T12:00:00",
|
||||
@@ -77,6 +80,7 @@ class SatelliteIcRvKafkaListenerTest {
|
||||
|
||||
assertEquals(0.0, satelliteIcEventService.lastMessage?.ic?.sBall)
|
||||
assertEquals(147.8, satelliteIcEventService.lastMessage?.ic?.f81)
|
||||
assertEquals(MovementModel.FOTO, satelliteIcEventService.lastMessage?.movementModel)
|
||||
}
|
||||
|
||||
private class RecordingSatelliteIcEventService : SatelliteIcEventService() {
|
||||
|
||||
+58
@@ -14,6 +14,11 @@ import org.springframework.kafka.core.DefaultKafkaConsumerFactory
|
||||
import org.springframework.kafka.listener.adapter.RecordFilterStrategy
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import space.nstart.pcp.pcp_request_service.entity.PDCMEntity
|
||||
import space.nstart.pcp.pcp_request_service.entity.SatelliteInitialConditionEntity
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.InitialConditionsDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.MovementModel
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.OrbPointDTO
|
||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.SatelliteICDTO
|
||||
import java.time.LocalDateTime
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -41,6 +46,9 @@ class PDCMRepositoryTest {
|
||||
@Autowired
|
||||
private lateinit var repository: PDCMRepository
|
||||
|
||||
@Autowired
|
||||
private lateinit var satelliteInitialConditionRepository: SatelliteInitialConditionRepository
|
||||
|
||||
@Test
|
||||
fun `find satellite orbit availability returns all satellites with points when time is null`() {
|
||||
persistPoint(11L, LocalDateTime.of(2026, 4, 14, 10, 0))
|
||||
@@ -74,6 +82,34 @@ class PDCMRepositoryTest {
|
||||
assertEquals(LocalDateTime.of(2026, 4, 14, 12, 0), actual.single().timeStop)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `satellite initial conditions repository returns last calculated condition`() {
|
||||
val oldCondition = satelliteInitialConditionRepository.save(sampleInitialCondition(11L, 1L))
|
||||
oldCondition.markLastCalculated(LocalDateTime.of(2026, 4, 14, 10, 0))
|
||||
satelliteInitialConditionRepository.save(oldCondition)
|
||||
|
||||
val newCondition = satelliteInitialConditionRepository.save(sampleInitialCondition(11L, 2L))
|
||||
satelliteInitialConditionRepository.clearLastCalculated(11L)
|
||||
newCondition.markLastCalculated(LocalDateTime.of(2026, 4, 14, 12, 0))
|
||||
satelliteInitialConditionRepository.save(newCondition)
|
||||
satelliteInitialConditionRepository.save(sampleInitialCondition(11L, 3L))
|
||||
|
||||
entityManager.flush()
|
||||
entityManager.clear()
|
||||
|
||||
val actual = satelliteInitialConditionRepository
|
||||
.findFirstBySatelliteIdAndLastCalculatedTrueOrderByCalculatedAtDescIdDesc(11L)
|
||||
|
||||
assertEquals(2L, actual?.toDto()?.ic?.orbPoint?.revolution)
|
||||
assertEquals(MovementModel.KONDOR, actual?.movementModel)
|
||||
assertEquals(
|
||||
1,
|
||||
satelliteInitialConditionRepository.findAll().count { entity ->
|
||||
entity.satelliteId == 11L && entity.lastCalculated
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun persistPoint(satelliteId: Long, time: LocalDateTime) {
|
||||
entityManager.persist(
|
||||
PDCMEntity(
|
||||
@@ -91,6 +127,28 @@ class PDCMRepositoryTest {
|
||||
entityManager.flush()
|
||||
}
|
||||
|
||||
private fun sampleInitialCondition(satelliteId: Long, revolution: Long) =
|
||||
SatelliteInitialConditionEntity(
|
||||
SatelliteICDTO(
|
||||
satelliteId = satelliteId,
|
||||
movementModel = MovementModel.KONDOR,
|
||||
ic = InitialConditionsDTO(
|
||||
orbPoint = OrbPointDTO(
|
||||
time = LocalDateTime.of(2026, 4, 14, 10, 0).plusHours(revolution),
|
||||
revolution = revolution,
|
||||
vx = 1.0,
|
||||
vy = 2.0,
|
||||
vz = 3.0,
|
||||
x = 4.0,
|
||||
y = 5.0,
|
||||
z = 6.0
|
||||
),
|
||||
sBall = 0.2,
|
||||
f81 = 141.0
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@TestConfiguration
|
||||
class KafkaFilterStubConfiguration {
|
||||
@Bean("kafkaListenerContainerFactory")
|
||||
|
||||
Reference in New Issue
Block a user