From a06dfcac4eb3d3b1c82baaf8539d828afc300024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=A1=D0=BE?= =?UTF-8?q?=D0=BB=D0=BE=D0=B2=D1=8C=D0=B5=D0=B2?= Date: Sat, 6 Jun 2026 00:12:27 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=BA=D0=B0=D1=80=D1=82=D0=B0=20kafka/?= =?UTF-8?q?http/camunda=20=D0=B2=D0=B7=D0=B0=D0=B8=D0=BC=D0=BE=D0=B4=D0=B5?= =?UTF-8?q?=D0=B9=D1=81=D1=82=D0=B2=D0=B8=D0=B9=20=D1=81=D0=B5=D1=80=D0=B2?= =?UTF-8?q?=D0=B8=D1=81=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/architect/PCP_SERVICE_INTERACTIONS.md | 224 +++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 docs/architect/PCP_SERVICE_INTERACTIONS.md diff --git a/docs/architect/PCP_SERVICE_INTERACTIONS.md b/docs/architect/PCP_SERVICE_INTERACTIONS.md new file mode 100644 index 0000000..9e1dd06 --- /dev/null +++ b/docs/architect/PCP_SERVICE_INTERACTIONS.md @@ -0,0 +1,224 @@ +# Карта взаимодействий сервисов PCP + +> Составлено по исходникам (`services/*/src/main`) и конфигам (`config-repo/`). +> Три канала интеграции: **Kafka** (события), **HTTP/REST** (синхронные запросы), **Camunda 8 / Zeebe** (оркестрация процессов). +> Имена топиков и адреса сервисов берутся из Spring Cloud Config (`config-repo/*.yaml`, +> общая карта адресов — `application-dev.yaml` / `application-local.yaml`, ключи `pcp.services.*`). + +## Содержание +1. [Перечень сервисов и порты](#1-перечень-сервисов-и-порты) +2. [Kafka — карта топиков и событий](#2-kafka--карта-топиков-и-событий) +3. [HTTP/REST — карта вызовов между сервисами](#3-httprest--карта-вызовов-между-сервисами) +4. [Camunda — процессы и воркеры](#4-camunda--процессы-и-воркеры) + +--- + +## 1. Перечень сервисов и порты + +Локальные порты — из `config-repo/application-local.yaml` (`pcp.ports.*`). В dev/docker все слушают `8080`. + +| Сервис | Локальный порт | Роль | +|---|---|---| +| `spring-cloud-config-server` | 8888 | раздача конфигов | +| `pcp-srpring-boot-admin-server` | (admin) | мониторинг Spring Boot Admin | +| `tle-monitoring-service` | 7001 | загрузка/раздача TLE (CelesTrak) | +| `pcp-complex-mission-service` | 7002 | комплексные планы/миссии, режимы съёмки КА | +| `pcp-ballistics-service` | 7003 | баллистика, расчёт НУ/витков/трасс (он же `ic-service`) | +| `pcp-request-service` | 7005 | заявки, маршруты-привязки, outbox | +| `slots-service` | 7006 | слоты, бронирования, расчёт покрытия | +| `pcp-ui-service` | 7008 | BFF/агрегатор для старого UI | +| `pcp-stations-service` | 7009 | каталог наземных станций | +| `pcp-mission-planing-service` | 7010 | планирование миссий + **Camunda job-воркеры** | +| `pcp-tgu-service` | 7011 | ТГУ: выдача планов, **запуск Camunda-процессов** | +| `pcp-coverage-scheme-service` | 7012 | расчёт схем покрытия | +| `pcp-satellite-catalog-service` | 7013 | каталог КА | +| `pcp-dynamic-plan-service` | 7014 | динамические/комплексные планы (calcPlan) | +| `pcp-route-processing-service` | — | обработка маршрутных паспортов | + +`pcp-tgu-ops-ui` — фронтенд (Vite), ходит в микросервисы напрямую через прокси, в этой карте не участвует как backend. + +--- + +## 2. Kafka — карта топиков и событий + +Событие — JSON-конверт `KafkaMessage` с заголовком `type` (значения из `PcpKafkaEvent`). +Консьюмеры фильтруют по этому заголовку. + +### Топики + +| Топик | Продюсер(ы) | Консьюмер(ы) | Событие / назначение | +|---|---|---|---| +| `pcp.tle` *(default-topic)* | `tle-monitoring-service` (TLE); `slots-service` (`ICRVPlacedEvent`) | `pcp-ballistics-service` (фильтры `placedIcFilter`, `updatedIcFilter`, `placedIcRvFilter`) | общий «шина TLE / НУ-РВ»: новые TLE и заложенные начальные условия | +| `pcp.satellites` | `pcp-satellite-catalog-service` (`SatelliteDeletedEvent`) | `tle-monitoring`, `slots-service`, `pcp-complex-mission-service`, `pcp-dynamic-plan-service`, `pcp-ballistics-service`, `pcp-mission-planing-service` | удаление КА (fan-out для очистки производных данных) | +| `pcp.slots.status.v1` | `pcp-mission-planing-service` (`BookedSlotsStatusChangedEvent`) | `slots-service` (`BookedSlotsKafkaListener`) | смена статуса забронированных слотов (lifecycle Kafka-first) | +| `pcp.route.in.v1` | `pcp-route-processing-service` (`processed-route`) | `pcp-mission-planing-service` (`ModeStatusChangedKafkaListener`, `ModeStatusChangedEvent`) | обработанный маршрут → смена статуса режима съёмки | +| `pcp.route.georeference.v1` | `pcp-route-processing-service` (`route-georeference`) | `pcp-request-service` (`RequestKafkaListener.consumeRoute`) | геопривязка маршрута к заявке | +| `pcp.request.survey-georeference.v1` | (инжект `RouteProcessingTestController` / внешний источник) | `pcp-route-processing-service` (`RoutePassportMessageListener`, вход) | входной маршрутный паспорт на обработку | +| `pcp.request.survey-georeference-dlq.v1` | `pcp-route-processing-service` (DLQ) | — | dead-letter для входных паспортов | +| `pcp.request.completed.v1` | `pcp-request-service` (`OutboxPublisherService`, outbox) | *(в репозитории нет консьюмера)* | заявка завершена (REQUEST_COMPLETED) | +| `pcp.request.in.v1` | — | *(объявлен в конфиге `pcp-request-service`, активного слушателя нет)* | входящие заявки (legacy/зарезервировано) | + +### Поток данных (упрощённо) + +``` +CelesTrak ──HTTP──> tle-monitoring ──pcp.tle(TLE)──────────────> ballistics +slots-service ─────pcp.tle(ICRVPlacedEvent)───────────────────> ballistics + +satellite-catalog ──pcp.satellites(SatelliteDeletedEvent)──┬──> tle-monitoring + ├──> slots-service + ├──> complex-mission + ├──> dynamic-plan + ├──> ballistics + └──> mission-planing + +route-processing ──pcp.route.in.v1──────> mission-planing (ModeStatusChanged) +route-processing ──pcp.route.georeference.v1──> request-service + (вход) pcp.request.survey-georeference.v1 ──> route-processing + +mission-planing ──pcp.slots.status.v1(BookedSlots)──────> slots-service +request-service ──pcp.request.completed.v1 (outbox)─────> (нет консьюмера в репо) +``` + +### ТГУ-топики (`pcp.tgu.*`) + +`pcp-tgu-service` объявляет консьюмеры на свои топики (`config-repo/pcp-tgu-service.yaml`, блок `topics:`). +Продюсеры этих событий — внешняя система СПО УОГ / тестовые эндпоинты; внутри репозитория стабильных продюсеров нет. + +| Топик | Консьюмер в tgu | Событие | +|---|---|---| +| `pcp.tgu.visibility-windows-changed.v1` | `VisibilityWindowsChangedConsumer` | изменение окон видимости | +| `pcp.tgu.satellite-plan-decision.v1` | `PlanDecisionConsumer` | решение по плану (принят/отклонён) | +| `pcp.tgu.layin-confirmed.v1` | `LayinConfirmedConsumer` | подтверждение закладки | +| `pcp.tgu.layin-failed.v1` | `LayinFailedConsumer` | ошибка закладки | +| `pcp.tgu.plan-not-accepted.v1` | `PlanNotAcceptedConsumer` | план не принят | +| `pcp.tgu.station-params-changed.v1` | `StationParamsChangedConsumer` | смена параметров станции | + +--- + +## 3. HTTP/REST — карта вызовов между сервисами + +Адреса берутся из `settings.*` → `pcp.services.*` (Spring Cloud Config). Клиенты — `WebClient`. + +| Вызывающий сервис | Целевой сервис | Эндпоинты (примеры) | Назначение | +|---|---|---|---| +| `pcp-ui-service` (BFF) | `tle-monitoring` | `/v1/api/tle`, `/v1/api/tle/satellite/{id}` | TLE | +| | `pcp-satellite-catalog` | `/api/satellites`, `/api/satellites/{id}/observation-profile`, `/slot-profile`, `/api/satellite-groups` | каталог КА | +| | `pcp-complex-mission` | `/api/missions`, `/api/missions/{id}/drops/calculate`, `/api/com-plan/runs`, `/api/com-plan/process` | миссии и комплексные планы | +| | `pcp-dynamic-plan` | `/v1/main/calcPlan`, `/{runId}/result`, `/routes`, `/intervals` | динамические планы | +| | `pcp-request` (request / earth-grid) | `/v1/requests`, `/v1/requests/{id}/cells` | заявки и ячейки | +| | `pcp-stations` | `/api/stations`, `/api/stations/{id}` | станции | +| | `slots-service` | `/api/slots/...`, `/api/slots/booking[...]` | слоты и бронирования | +| | `pcp-ballistics` | `/api/satellites/{id}/asc-node`, `/flight-line`, `/orbit`, `/extract-time`, `/initial-conditions/current`, `/receive-rv`, `/api/tle/parse`, `/api/tle/point` | баллистика | +| | `pcp-coverage-scheme` | `/api/coverage-schemes/calculate` | схемы покрытия | +| | `pcp-tgu` | `/api/platforms`, `/api/plans[...]`, `/api/plans/{id}/dismiss`, `/restore`, `/test/tgu/plans/{id}/decision`, `/confirm-layin` | планы ТГУ | +| `pcp-tgu-service` | `pcp-mission-planing` (`mission-planing.base-url`) | `/api/missions/{id}/clone`, `/api/missions/blank`, `/api/missions/{id}` | управление миссиями плана | +| | `pcp-ballistics` (`ballistics.base-url`) | расчёт точек/баллистики (`ExternalPointsClient`) | внешние точки | +| | `ordinis.nstart.cloud` (внешний) | `/api/v1/spacecraft/records` (`platforms-url`) | классификатор платформ КА | +| `pcp-mission-planing` | `pcp-ballistics` | `/api/obj-view/mpl-square`, `/mpl-point`, `/cell-coverage/{cell}`, `/api/satellites/{id}/rva`, `/extract-time` | баллистика для планирования | +| | `pcp-complex-mission` | `/api/satellites/snapshots/{id}`, режимы КА | данные комплексной миссии | +| | `pcp-satellite-catalog` | `/api/satellites/{id}` | каталог КА | +| `pcp-complex-mission` | `pcp-ballistics` (`ic-service`) | расчёты НУ/баллистики | баллистика | +| | `pcp-satellite-catalog` | `/api/satellites`, `/api/satellites/batch` | каталог КА | +| | `slots-service` | покрытие/слоты (`CoverageBatchClient`, `SlotService`) | слоты | +| | `pcp-request` (`earth-grid`) | сетка Земли/ячейки (`EarthGridService`) | заявки/ячейки | +| | `pcp-coverage-scheme` | расчёт схемы покрытия | покрытие | +| `pcp-dynamic-plan` | `pcp-request` | `/v1/requests` (выборка заявок) | заявки | +| | `pcp-ballistics` | `/api/satellites/orbit/availability/{norad}`, `/extract-time`, `/api/obj-view/mpl-square` | баллистика | +| | `pcp-satellite-catalog` | `/api/satellites` | каталог КА | +| `pcp-coverage-scheme` | `pcp-ballistics` | `/api/obj-view/mpl-square`, `/mpl-point`, `/extract-time` | баллистика | +| | `pcp-complex-mission` | `/api/satellites/{id}` | данные КА/миссии | +| `pcp-ballistics` | `pcp-stations` | `/api/stations` | станции (для расчётов видимости) | +| `slots-service` | `pcp-satellite-catalog` | `/api/satellites`, `/batch`, `/slot-profile` | каталог КА | +| | `pcp-request` (`earth-grid`) | `/v1/requests`, `/cells` | заявки/ячейки | +| `tle-monitoring` | `pcp-satellite-catalog` | `/api/satellites` | каталог КА | + +Все сервисы дополнительно ходят в `spring-cloud-config-server` (8888) за конфигом и регистрируются в `spring-boot-admin-server`. + +### Граф зависимостей (кто кого зовёт по HTTP) + +``` +ui-service ──> почти все (BFF-агрегатор) +tgu ─────────> mission-planing, ballistics, (ordinis ext) +mission-planing ─> ballistics, complex-mission, satellite-catalog +complex-mission ─> ballistics, satellite-catalog, slots, request, coverage-scheme +dynamic-plan ───> request, ballistics, satellite-catalog +coverage-scheme ─> ballistics, complex-mission +ballistics ─────> stations +slots ──────────> satellite-catalog, request +tle-monitoring ─> satellite-catalog (+ CelesTrak внешний) +``` + +`pcp-ballistics` и `pcp-satellite-catalog` — наиболее востребованные «нижние» сервисы. + +--- + +## 4. Camunda — процессы и воркеры + +Используется **Camunda 8 (Zeebe)**, `io.camunda:camunda-spring-boot-4-starter:8.8.10`. +Брокер внешний: gRPC `camunda.k8s.265.nstart.cloud:30901` (dev) / `localhost:26500` (локально), +ключ `camunda.client.grpc-address`. + +- **`pcp-tgu-service`** — *оркестратор*: содержит BPMN-определения, разворачивает их и запускает экземпляры процессов (`CamundaClient.newCreateInstanceCommand()`). +- **`pcp-mission-planing-service`** — *исполнитель*: реализует все job-воркеры (`@JobWorker` в `FlowService`). + +### Процесс `createSatelliteMission` + +BPMN: [createSatelliteMission.bpmn](../../services/pcp-tgu-service/src/main/resources/BPMN/createSatelliteMission.bpmn). +Запуск: `BpmnPlanIssueProcessStarter` ← `IssueDuePlanWorker.issuePlanNow()` ← `PlanController` `POST /api/plans/{planId}/issue`. + +``` +startSatelliteMission + → [calculateSatelliteSurveyMissions] «Сформировать план съёмки» + → [calculateSatelliteDropMissions] «Сформировать план сбросов» + → [sendSatellitePlan] «Отправка плана в СПО УОГ» + → endSatelliteMission +``` + +### Процесс `updateAcceptedPlanSlots` + +BPMN: [updateAcceptedPlanSlots.bpmn](../../services/pcp-tgu-service/src/main/resources/BPMN/updateAcceptedPlanSlots.bpmn). +Запуск: `AcceptedPlanSlotsUpdateProcessStarter` ← `AcceptedPlanSlotsUpdateWorker`. + +``` +start → [updateSlotsStatus] «Обновление статуса слотов» → end +``` + +### Соответствие job-type → воркер + +Все воркеры — в `pcp-mission-planing-service`, [FlowService.kt](../../services/pcp-mission-planing-service/src/main/kotlin/space/nstart/pcp/pcp_mission_planing_service/service/FlowService.kt), `autoComplete = false` (ручной `newCompleteCommand`). + +| Job type (BPMN) | Метод воркера | Процесс | +|---|---|---| +| `calculateSatelliteSurveyMissions` | `FlowService.surveyPlan` | createSatelliteMission | +| `calculateSatelliteDropMissions` | `FlowService.surveyDrop` | createSatelliteMission | +| `sendSatellitePlan` | `FlowService.sendPlan` | createSatelliteMission | +| `updateSlotsStatus` | `FlowService.confirmPlan` | updateAcceptedPlanSlots | + +### Схема + +``` + pcp-tgu-service pcp-mission-planing-service + (оркестратор) (job-воркеры, FlowService) + PlanController POST /api/plans/{id}/issue + │ + ▼ + BpmnPlanIssueProcessStarter + │ newCreateInstanceCommand("createSatelliteMission") + ▼ + ┌─────────────── Zeebe / Camunda 8 broker (gRPC) ───────────────┐ + │ calculateSatelliteSurveyMissions ─────────────────────────► surveyPlan + │ calculateSatelliteDropMissions ─────────────────────────► surveyDrop + │ sendSatellitePlan ─────────────────────────► sendPlan + └───────────────────────────────────────────────────────────────┘ + + AcceptedPlanSlotsUpdateProcessStarter + │ newCreateInstanceCommand("updateAcceptedPlanSlots") + ▼ + ┌─────────────── Zeebe broker ───────────────┐ + │ updateSlotsStatus ───────────────────────► confirmPlan + └─────────────────────────────────────────────┘ +``` + +> Связь между HTTP и Camunda: воркеры `pcp-mission-planing-service` в ходе выполнения задач +> сами ходят по HTTP в `pcp-ballistics`, `pcp-complex-mission`, `pcp-satellite-catalog` +> и публикуют Kafka-событие `pcp.slots.status.v1` (см. разделы 2–3).