Структура проекта
Эта страница — карта кодовой базы для разработчика, который только что получил доступ к репозиторию. Если ещё нет — запросите доступ и сначала пройдите Сборку из исходников.
Стек
- Spring Boot 3.2 — основной фреймворк (web, security, jdbc, cache, scheduling).
- Java 21 (LTS) — язык. Использует records, pattern matching, virtual threads (где применимо).
- Thymeleaf — серверный рендеринг страниц веб-интерфейса. Никакого SPA — операторам не нужна вёрстка нового поколения, нужна скорость.
- MySQL 8 — хранение OLT, ONU, истории сигналов, конфигов, аудита.
- Caffeine — in-memory кэш (биллинг-лукапы, MAC-таблицы, общие справочники).
- Maven — сборка и зависимости.
- JJWT 0.11 — проверка лицензионных JWT, выдаваемых license-server.
- Bootstrap 5 — фронтенд-разметка.
Модули (логические)
src/main/java/ru/getOnu/├── config/ — конфигурация Spring и feature-flags├── controller/ — Thymeleaf-контроллеры и REST API├── service/ — бизнес-логика (OltService, OltRefreshService, ONU-сервисы)├── domain/ + model/ — доменные сущности (OLT, ONU, Port, SignalLevel)├── vendor/ — vendor-адаптеры (GateRay, BdCom, CData)├── telnet/ — Telnet-клиент и OLT-session pool├── billing/ — интеграция с биллингом├── license/ — LicenseGuard: bootstrap, heartbeat, enforcement├── mcp/ — MCP-сервер для LLM-агентов├── llm/ — встроенный AI-ассистент├── api/external/ — публичный REST API└── scheduler/ — фоновые задачи (опрос OLT, снятие конфигов)Ключевые сервисы
Эти классы — точки входа для большинства задач разработки:
| Класс | Что делает | Когда трогать |
|---|---|---|
OltService | Фасад над операциями с OLT — создание, чтение, обновление, статусы. | Изменение поведения CRUD-операций над OLT. |
OltRefreshService | Координатор фонового опроса: ставит OLT в очередь, гарантирует «одна Telnet-сессия на устройство». | Изменение логики опроса, throttle, retry. |
Vendor-адаптеры (GateRay, BdCom, CData) | Парсинг CLI-вывода конкретного вендора в общую доменную модель. | Добавление новой команды на существующий вендор. |
DatabaseInitializer | Идемпотентные DDL-миграции при старте приложения. | Любое изменение схемы БД — см. ниже. |
LicenseGuard (по модулям bootstrap / heartbeat) | Проверка JWT-лицензии и фон-pinger к license.getolt.online. | Изменение модели лицензирования. |
Миграции БД — только через DatabaseInitializer
Категорический запрет на Flyway / Liquibase / любой migration-tool со SQL-файлами. Любая новая таблица / индекс / колонка добавляется методом в DatabaseInitializer:
private void createXxxIfNotExist() { try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) { stmt.execute(""" CREATE TABLE IF NOT EXISTS xxx ( id BIGINT AUTO_INCREMENT PRIMARY KEY, ... ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 """); }}Один источник правды (этот файл), линейная читаемость, никаких flyway.repair().
OLT-session pool
Оптическое оборудование (OLT) поддерживает обычно одну Telnet-сессию на устройство в момент времени. Все операции по конкретному OLT идут через OltSessionPool — он держит очередь per-OLT и сериализует операции.
Не пытайтесь распараллелить операции по одному OLT — он закроет лишние сессии или вернёт мусор. Параллелизм — только между OLT.
Vendor-адаптеры
Каждый вендор — отдельный класс с интерфейсом OltVendor:
public interface OltVendor { String detect(String banner); // распознать вендор по баннеру входа Map<String, Onu> parseOnuList(String cliOutput); SignalLevel parseSignal(String cliOutput); String runningConfig(TelnetSession s); ...}Сейчас в продакшне работают GateRay, BdCom, CData. Добавление нового вендора — отдельная задача с тест-стендом доступа к железу клиента, описана в Добавление вендора OLT.
Кэш
Caffeine используется в нескольких местах с разными TTL:
| Что кэшируется | TTL | Почему |
|---|---|---|
| Биллинг-лукапы (MAC → договор) | 60 минут | Не дёргать биллинг на каждом показе абонента. |
| ONU-таблицы по OLT | в памяти процесса, инвалидация по опросу | Быстрый рендер карточки OLT. |
| Справочники вендоров и моделей | сутки | Меняются редко. |
Фронтенд
Thymeleaf-шаблоны лежат в src/main/resources/templates/. Никакой логики в шаблонах — только th: атрибуты. Bootstrap 5 для разметки, минимум кастомного CSS. JavaScript — точечно на jQuery (legacy, постепенно убирается) и Vanilla JS.
Тесты
src/test/java— unit-тесты, mock’и внешних клиентов (LicenseServerClient,BillingClient).- Интеграционные тесты —
mvn verify -P integration, поднимают тестовый MySQL. - Внешние HTTP-вызовы (license-server, биллинг) мокаются через
Mockito.mock()клиента, не через WireMock — есть инциденты с глобальным HTTP-прокси на dev-машинах.
С чем не лезть без обсуждения
Эти куски кода и решения обсуждались, и переписывание «как красивее» обычно ломает несколько неочевидных сценариев:
- Любые миграции через Flyway / Liquibase.
- Параллельный Telnet к одному OLT.
- Замена Thymeleaf на SPA-фронт.
- Снятие LicenseGuard под предлогом «упрощения dev-режима».
Если у вас идея, как улучшить любую из этих областей — сначала обсудите в @getolt_pub или на support@getolt.online.
Нашли ошибку или нужно что-то дополнить? Напишите нам или в Telegram @getolt_pub.
Разработка: gmasich.ru