feat: живой цикл M2M с НРД + мастер установки ключа на флешку

Инфраструктура M2M (живой обмен с НРД через ИШ):
- обработка M2MTransferResponse: ERROR(M2Mxx) → заявка Отклонена, сохранение
  ответа; INFO → ждём Decision; идемпотентность поллера
- fallback-корреляция ответов с нулевым GUID (M2M14/M2M17) по FIFO
- сырой XML ответа НРД в карточке заявки (для пересылки в ТП)
- тестовый пакет роботу приведён к эталону m2m_robot_samples (CostInfo=Yes,
  4 бумаги, IsolationStatus, DocumentSeries=сценарий); override паспорта
- редирект из теста сразу в карточку заявки

Мастер установки ключа Валидаты на флешку (admin/setup/keywizard):
- пошаговый: загрузка .7z+пароль → выбор флешки → запись → справочник
  сертификатов (CRL) → перезапуск+проверка ИШ → готово
- привилегированный воркер (bj-keymedia) в host-namespace через файл-обмен,
  bj-server остаётся в песочнице
- сохранение структуры профиля архива (spr<N>), перечисление съёмных USB

Прочее:
- пакет-доказательство для ТП НРД + форма регистрации участника M2M
- эталонные образцы робота (DOC/m2m_robot_samples)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
zuevav
2026-06-19 00:03:21 +03:00
parent 6e503433d4
commit 9737c787f9
110 changed files with 10771 additions and 1690 deletions
+1
View File
@@ -0,0 +1 @@
TEST3 GOST|TEST3GOST|WSL|t
+132
View File
@@ -0,0 +1,132 @@
-- configure-ish.sql — автонастройка ИШ НРД без GUI.
--
-- Снято как эталон с рабочей GUI-конфигурации (deploy/ish/params-reference.txt)
-- и параметризовано. Воспроизводит то, что оператор делал бы мышкой в
-- igate.exe (Avalonia): PostgreSQL + Web API + WSL-канал TEST3-GOST.
--
-- Применяется к свежей БД ИШ ПОСЛЕ того как схема создана через
-- `igate-cli --data <dir>` (он накатывает EF-миграции при первом подключении).
--
-- Подстановки (заменяются установщиком через psql -v):
-- :channel_name — отображаемое имя канала, напр. 'TEST3 GOST'
-- :channel_code — локальный код канала, напр. 'TEST3GOST'
-- :wsl_endpoint — URL службы WSL НРД (TEST3-GOST)
-- :crypto_profile — имя профиля Валидаты ('moex')
-- :repository_code— код депонента из письма НРД ('MC0079200000')
-- :exchange_dir — рабочая папка обмена ('/var/lib/igate/exchange')
-- :web_port — порт Web API ('8090')
--
-- Пример:
-- psql -h 127.0.0.1 -U igate -d igate \
-- -v channel_name="'TEST3 GOST'" -v channel_code="'TEST3GOST'" \
-- -v wsl_endpoint="'https://gost-t3.nsd.ru/onyx-ms/OnyxEdoWSService/OnyxEdo'" \
-- -v crypto_profile="'moex'" -v repository_code="'MC0079200000'" \
-- -v exchange_dir="'/var/lib/igate/exchange'" -v web_port="'8090'" \
-- -f configure-ish.sql
BEGIN;
-- Чистим прежнюю конфигурацию (идемпотентность)
DELETE FROM parameters;
DELETE FROM channels;
-- --- Глобальные параметры: Web API (КРИТИЧНО — runEngineOnStartApp=True,
-- иначе движок не стартует в headless-режиме и Kestrel не поднимается) ---
INSERT INTO parameters(name, value, chanel_id) VALUES
('runEngineOnStartApp', 'True', NULL),
('server.useServer', 'True', NULL),
('server.host', 'localhost', NULL),
('server.port', :web_port, NULL),
('server.scheme', 'Http', NULL),
('server.authentication.enable', 'False', NULL),
('server.authentication.userName', '', NULL),
('server.authentication.password', '', NULL),
('server.certificate.storage', 'File', NULL),
('server.certificate.store.location', 'CurrentUser', NULL),
('server.certificate.store.name', 'My', NULL),
('server.certificate.file.path', '', NULL),
('server.certificate.file.password', '', NULL),
('wsl.httpsMode', 'Auto', NULL),
('wsl.maxConnsPerServer', '4', NULL),
('wsl.proxy.mode', 'None', NULL),
('wsl.proxy.address', '', NULL),
('wsl.proxy.port', '0', NULL),
('wsl.proxy.username', '', NULL),
('wsl.proxy.password', '', NULL),
('enableDbLogging', 'False', NULL),
('cleanAutomatically', 'False', NULL),
('cleanAtTime', '00:30:00', NULL),
('cleanWhenLarger', '1024', NULL),
('cleanVacuum', 'False', NULL),
('storePeriod', '15', NULL),
('archiveAutomatically', 'False', NULL);
-- --- WSL-канал ---
-- ВАЖНО: ИШ резолвит канал по СОСТАВНОМУ коду = <код канала> + <код депонента>
-- (так формирует ИШ-GUI: TEST3 + MC0413600000 = TEST3MC0413600000). С коротким
-- кодом ИШ падает 'more than one Channel' и admin API не видит канал.
INSERT INTO channels(name, code, type, enable)
VALUES (:channel_name, :channel_code || :repository_code, 'WSL', true);
-- Параметры канала привязываем к его id (находим по составному коду)
INSERT INTO parameters(name, value, chanel_id)
SELECT n, v, c.id FROM channels c, (VALUES
('enable', 'True'),
('wslEndpoint', :wsl_endpoint),
('cryptography.type', 'GOST'),
('cryptography.profile', :crypto_profile),
('cryptography.pincode', ''),
('cryptography.clientCertificateSerialNumber', ''),
('repositoryCode', :repository_code),
('fetchInterval', '00:01:00'),
('attemptInterval', '30000'),
('sendAttempts', '3'),
('maxPartSize', '500'),
('loadOldMessagesDepth', '3'),
('isIncomingEnabled', 'True'),
('isOutgoingEnabled', 'True'),
('isTransitTerminalChannel', 'False'),
('useDirectories', 'True'),
('dir', :exchange_dir),
('inboxDirName', 'INBOX'),
('outboxDirName', 'OUTBOX'),
('sentDirName', 'SENT'),
('errorDirName', 'ERRORS'),
('archive1042sDirName', :exchange_dir || '/Archives1042S'),
('enableLockFile', 'True'),
('enableAutoResponse', 'True'),
('enable1042ReportProcessing', 'True'),
('RenameOutgoingFiles', 'True'),
('generateReceivedPackageInfo', 'True'),
('generateSentPackageInfo', 'False'),
('moveReceiptsToSentFolder', 'False'),
('applyAddHashOfPackageToFolder', 'False'),
('ignorePackageDirectoryStructure', 'False'),
('checkReceivedPackageNsdSign', 'False'),
('checkReceivedPackageSenderSign', 'False'),
('autoUpdateTransitMember', 'False'),
('automaticcalyLoadCrls', 'False'),
('autoInPkgReportOffload', 'False'),
('monitoringThreshold', '00:00:10'),
-- Пустые параметры для полного соответствия эталону GUI (движок ожидает
-- их наличие; отсутствие части может дать «Invalid value» при старте).
('autoLoadCrlsTime', ''),
('fetchThreadCount', ''),
('forceCryPackageEncryption', ''),
('inPkgReportDirectory', ''),
('inPkgReportOffloadInterval', ''),
('maxPackagesPerJob', ''),
('nsdCertificateSerialNumbers', ''),
('pkiDecryptMode', ''),
('pkiEncryptMode', ''),
('pkiSignMode', ''),
('pkiVerifyMode', ''),
('receiveProcThreadCount', ''),
('sendProcThreadCount', ''),
('updateTransitMemberListTime', '')
) AS p(n, v)
WHERE c.code = :channel_code || :repository_code;
COMMIT;
\echo 'ИШ настроен. Перезапустите igate-svc: systemctl restart igate'
+83
View File
@@ -0,0 +1,83 @@
archiveAtTime||NULL
archiveAutomatically|False|NULL
archiveRecordsOlderThan||NULL
archiveWhenLarger||NULL
cleanAtTime|00:30:00|NULL
cleanAutomatically|False|NULL
cleanVacuum|False|NULL
cleanWhenLarger|1024|NULL
enableDbLogging|False|NULL
httpTimeout||NULL
packageBackupFolder||NULL
runEngineOnStartApp|False|NULL
server.authentication.enable|False|NULL
server.authentication.password||NULL
server.authentication.userName||NULL
server.certificate.file.password||NULL
server.certificate.file.path||NULL
server.certificate.storage|File|NULL
server.certificate.store.location|CurrentUser|NULL
server.certificate.store.name|My|NULL
server.host|localhost|NULL
server.port|8090|NULL
server.scheme|Http|NULL
server.useServer|True|NULL
storePeriod|15|NULL
wsl.httpsMode|Auto|NULL
wsl.maxConnsPerServer|4|NULL
wsl.proxy.address||NULL
wsl.proxy.mode|None|NULL
wsl.proxy.password||NULL
wsl.proxy.port|0|NULL
wsl.proxy.username||NULL
applyAddHashOfPackageToFolder|False|33
archive1042sDirName|/var/lib/igate/exchange/Archives1042S|33
attemptInterval|30000|33
autoInPkgReportOffload|False|33
autoLoadCrlsTime||33
automaticcalyLoadCrls|False|33
autoUpdateTransitMember|False|33
checkReceivedPackageNsdSign|False|33
checkReceivedPackageSenderSign|False|33
cryptography.clientCertificateSerialNumber||33
cryptography.pincode||33
cryptography.profile|My|33
cryptography.type|GOST|33
dir|/var/lib/igate/exchange|33
enable|True|33
enable1042ReportProcessing|True|33
enableAutoResponse|True|33
enableLockFile|True|33
errorDirName|ERRORS|33
fetchInterval|00:01:00|33
fetchThreadCount||33
forceCryPackageEncryption||33
generateReceivedPackageInfo|True|33
generateSentPackageInfo|False|33
ignorePackageDirectoryStructure|False|33
inboxDirName|INBOX|33
inPkgReportDirectory||33
inPkgReportOffloadInterval||33
isIncomingEnabled|True|33
isOutgoingEnabled|True|33
isTransitTerminalChannel|False|33
loadOldMessagesDepth|3|33
maxPackagesPerJob||33
maxPartSize|500|33
monitoringThreshold|00:00:10|33
moveReceiptsToSentFolder|False|33
nsdCertificateSerialNumbers||33
outboxDirName|OUTBOX|33
pkiDecryptMode||33
pkiEncryptMode||33
pkiSignMode||33
pkiVerifyMode||33
receiveProcThreadCount||33
RenameOutgoingFiles|True|33
repositoryCode|MC0079200000|33
sendAttempts|3|33
sendProcThreadCount||33
sentDirName|SENT|33
updateTransitMemberListTime||33
useDirectories|True|33
wslEndpoint|https://gost-t3.nsd.ru/onyx-ms/OnyxEdoWSService/OnyxEdo|33