pcp-tgu-service: миграция с WebFlux на servlet/MVC

WebFlux в tgu был фиктивным: блокирующая JPA, контроллеры оборачивали
блокирующие вызовы в Mono.fromCallable{}.subscribeOn(boundedElastic()),
WebClient .block()-ался сразу. Единственный WebFlux-only сервис флота.

- build: подключён pcp-types-lib (тянет starter-web → servlet), springdoc
  webflux-ui → webmvc-ui; starter-webflux оставлен только ради WebClient
- контроллеры возвращают значения напрямую (без Mono-обёрток)
- удалено локальное Jackson-2 зеркало PcpTimeModule.kt → модуль из либы
  в CamundaJacksonConfig; Jackson-3 зеркало остаётся (Boot 4 держит
  Jackson 3 на HTTP-границе и для MVC), WebFluxJacksonConfig → RestJacksonConfig
This commit is contained in:
Дмитрий Соловьев
2026-06-02 23:14:12 +03:00
parent cde4ffa9b6
commit e68c17e792
9 changed files with 78 additions and 182 deletions
+27 -19
View File
@@ -65,17 +65,16 @@
`findAndRegisterModules()` (напр. `pcp-request-service`).
- Точечная регистрация в мапперах, что обходят оба: `pcp-dynamic-plan-service/JacksonConfig`.
**Особый случай — pcp-tgu-service.** Он не зависит от pcp-types-lib и работает на WebFlux
(подключение либы притянуло бы `spring-boot-starter-web`/MVC и переключило тип приложения на
сервлетный). Поэтому в tgu лежат **два локальных зеркала** (поведение обязано совпадать с
библиотечным, правки синхронизировать), покрывающих обе Jackson-среды сервиса:
- `config/PcpTimeModule.kt` (Jackson 2) — зарегистрирован в `CamundaJacksonConfig`, покрывает
Camunda/внутренний парсинг;
- `config/PcpTimeModuleV3.kt` (**Jackson 3**, `tools.jackson.*`) — REST-кодеки WebFlux, которые
Boot 4 авто-конфигурирует на Jackson 3 `JsonMapper`. Регистрируется бином
`tools.jackson.databind.JacksonModule` (`WebFluxJacksonConfig`); `JacksonAutoConfiguration`
собирает все такие бины в общий `JsonMapper` (`builder.addModules(...)`). Тем самым входящий
REST-JSON tgu тоже читается толерантно к обоим форматам.
**Особый случай — pcp-tgu-service.** Сервис мигрирован с WebFlux на **servlet/MVC** (см. ниже
«Миграция tgu на MVC») и теперь зависит от pcp-types-lib, как остальной флот. Но из-за Boot 4 на
HTTP-границе всё равно работает **Jackson 3**, поэтому время покрывается двумя путями:
- Jackson-2 модуль **из либы** (`pcp_types_lib.utils.json.PcpTimeModule`) — явно зарегистрирован в
ручном маппере `CamundaJacksonConfig` (Camunda/внутренний парсинг); своего зеркала больше нет.
- `config/PcpTimeModuleV3.kt` (**Jackson 3**, `tools.jackson.*`) — REST HTTP message converters (MVC),
которые Boot 4 авто-конфигурирует на Jackson 3 `JsonMapper`. Регистрируется бином
`tools.jackson.databind.JacksonModule` (`RestJacksonConfig`); `JacksonAutoConfiguration` собирает
все такие бины в общий `JsonMapper` (`builder.addModules(...)`). Лежит локально, т.к. либа даёт
только Jackson-2 модуль; поведение обязано совпадать с библиотечным, правки синхронизировать.
Контракт слоя закреплён `PcpTimeModuleTest` (pcp-types-lib): оба формата → один и тот же UTC-момент,
плюс проверка авто-подхвата через SPI.
@@ -139,8 +138,8 @@ mission-planing) используют тот же дефолтный Jackson-к
синхронно; фронт `parseUtc` совместим. Контракт закреплён тестами выше.
- **Слой толерантности (`PcpTimeModule`) — раскатан по флоту.** 12 сервисов на pcp-types-lib
получают его авто-конфигурацией/SPI; dynamic-plan — точечно; tgu — двумя локальными зеркалами
(Jackson-2 для Camunda и Jackson-3 для REST-кодеков WebFlux). Это включатель: дальнейший флип
получают его авто-конфигурацией/SPI; dynamic-plan — точечно; tgu — модулем из либы (Camunda,
Jackson 2) плюс локальное Jackson-3 зеркало для REST-границы MVC. Это включатель: дальнейший флип
продюсеров на `Z` больше не требует синхронного деплоя.
После толерантности продюсеров можно флипать **в любом порядке**. Кандидаты: остальные naive-DTO
@@ -155,16 +154,25 @@ ui-service, ballistics, complex-mission, dynamic-plan, slots, coverage-scheme.
`…+00:00`. **Инстант не изменился** (тот же момент), но стенные часы теперь совпадают с UTC, поэтому
потребитель, дропающий зону, получает корректное время. Закреплено `LocalDateTimeTimeZoneSerializerTest`.
### Исправленные баги формата
- **pcp-tgu-service REST-codec на Jackson 3** — теперь толерантен (см. 2bis). Добавлен Jackson-3
- **pcp-tgu-service REST-граница на Jackson 3** — теперь толерантна (см. 2bis). Добавлен Jackson-3
вариант модуля `config/PcpTimeModuleV3.kt` и его регистрация бином `JacksonModule`
(`config/WebFluxJacksonConfig.kt`); входящий REST-JSON WebFlux читается в обоих форматах
(naive=UTC и `Z`). Закреплено `PcpTimeModuleV3Test`.
(`config/RestJacksonConfig.kt`); входящий REST-JSON читается в обоих форматах (naive=UTC и `Z`).
Закреплено `PcpTimeModuleV3Test`.
### Миграция tgu на MVC
- **pcp-tgu-service: WebFlux → servlet/MVC.** Сервис не имел реального реактивного кода — JPA
блокирующая, контроллеры оборачивали блокирующие вызовы в `Mono.fromCallable{}.subscribeOn(
boundedElastic())`, WebClient-вызовы `.block()`-ались сразу. Это был единственный WebFlux-only
сервис флота. Переведён на MVC: подключён pcp-types-lib (тянет `starter-web` → тип приложения
servlet), `springdoc``webmvc-ui`, контроллеры возвращают значения напрямую (без `Mono`).
`starter-webflux` оставлен только ради WebClient. Побочный эффект для времени: убрано локальное
Jackson-2 зеркало (`config/PcpTimeModule.kt`) в пользу модуля из либы; Jackson-3 зеркало остаётся
(Boot 4 держит Jackson 3 на HTTP-границе и для MVC).
### Остаток (под-задачи)
- Обе Jackson-среды tgu теперь толерантны; отдельных остатков по чтению времени нет. При миграции
- Обе Jackson-среды tgu толерантны; отдельных остатков по чтению времени нет. При миграции
оставшихся продьюсеров на `Z` (раздел 4) добавлять сериализационные тесты контракта.
## 5. Правило для нового кода