45 lines
4.5 KiB
Markdown
45 lines
4.5 KiB
Markdown
## ADDED Requirements
|
||
|
||
### Requirement: Реле через общую папку
|
||
`jira-hub serve` SHALL запускать поток реле вместе с HTTP-сервером. Пока настройка `relay_dir` пуста (`null`), реле
|
||
бездействует; настройку оно SHALL перечитывать не реже раза в 5 с, включение и выключение не требуют перезапуска. Если
|
||
каталог `relay_dir` существует, реле SHALL создать в нём подкаталоги `req/`, `resp/`, `work/`; если не существует —
|
||
записать одно предупреждение в лог и проверять снова.
|
||
|
||
Обмен:
|
||
- запрос агента — файл `req/<id>.json`: `{id, method, path, body, authorization, deadline}`, где `deadline` — момент UTC
|
||
(ISO 8601), после которого ответ не нужен; файлы, имя которых начинается с точки, реле MUST NOT читать;
|
||
- реле SHALL брать запрос переименованием в `work/<id>.json` и обрабатывать каждый взятый запрос в отдельном потоке;
|
||
- запрос с истёкшим `deadline` SHALL выбрасываться без ответа; `POST /agent/claim` SHALL пересылаться, только если до
|
||
`deadline` осталось не меньше 35 с, иначе выбрасываться без ответа;
|
||
- остальные запросы реле SHALL пересылать в свой HTTP на `127.0.0.1:<port>` тем же методом, путём и телом, с заголовком
|
||
`Authorization` из файла, и записывать ответ `resp/<id>.json` = `{id, status, body}` (тело — строка ответа HTTP) через
|
||
временный файл с именем на точку и переименование; затем удалять `work/<id>.json`;
|
||
- если соединение с `127.0.0.1:<port>` не удалось, ответ SHALL иметь `status = 502` и текст ошибки в `body`;
|
||
- нечитаемый JSON запроса SHALL перечитываться до 2 с, затем запрос выбрасывается с записью в лог.
|
||
|
||
При старте реле SHALL удалить файлы из `work/` с записью в лог. Раз в минуту реле SHALL удалять ответы в `resp/` старше
|
||
10 мин, запросы в `req/` с `deadline` старше 60 с и файлы с именем на точку старше 10 мин. На каждый обработанный запрос
|
||
реле SHALL писать в лог хаба строку `relay <METHOD> <path> <status> <секунды>`. HTTP API, обработчики и проверка токенов
|
||
при этом не меняются.
|
||
|
||
#### Scenario: Запрос через папку
|
||
- **WHEN** в `req/` появился `a1.json` с `GET /agent/settings`, агентским токеном и `deadline` через 60 с
|
||
- **THEN** в `resp/` появляется `a1.json` со `status = 200` и телом настроек; `work/a1.json` удалён
|
||
|
||
#### Scenario: Чужой токен через папку
|
||
- **WHEN** в файле запроса `GET /issues` с агентским токеном
|
||
- **THEN** ответ со `status = 401`, как по HTTP
|
||
|
||
#### Scenario: Просроченный claim
|
||
- **WHEN** реле взяло `POST /agent/claim`, до `deadline` которого осталось 20 с
|
||
- **THEN** запрос выброшен без ответа и без обращения к хабу; команда в очереди осталась `queued`
|
||
|
||
#### Scenario: Долгий claim не задерживает другие запросы
|
||
- **WHEN** реле пересылает `claim`, который ждёт команду 30 с, и в это время в `req/` появляется `GET /agent/settings`
|
||
- **THEN** ответ на `settings` пишется, не дожидаясь `claim`
|
||
|
||
#### Scenario: Папка не подключена
|
||
- **WHEN** `relay_dir` задан, но каталога нет; через минуту каталог появился
|
||
- **THEN** в логе одно предупреждение; после появления каталога реле создаёт подкаталоги и обрабатывает запросы
|