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:
@@ -40,15 +40,21 @@ func (s *Sender) Send(ctx context.Context, req *m2m.M2MTransferRequest) (*m2m.M2
|
||||
if err := req.Validate(); err != nil {
|
||||
return nil, fmt.Errorf("nsdadapter: req.Validate: %w", err)
|
||||
}
|
||||
body, err := nsdxml.Marshal(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("nsdadapter: marshal Request: %w", err)
|
||||
}
|
||||
pkgType, err := RouteToPackageType(KindTransferRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pkgID, err := s.client.SendPackage(ctx, s.profile.Channel, string(pkgType), body)
|
||||
// ИШ ждёт ZIP-архив (Type=ARCHIVE): doc.xml + config.xml с типом пакета.
|
||||
// Сырой XML ИШ отвергает ("Bad signature" при распаковке). PackRequest
|
||||
// собирает корректный ZIP с config.xml (#M2MTR).
|
||||
body, err := igw.PackRequest(req, "M2MTransferRequest.xml")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("nsdadapter: PackRequest: %w", err)
|
||||
}
|
||||
// ИШ резолвит канал по СОСТАВНОМУ коду: <код канала>+<код депонента>
|
||||
// (так его формирует ИШ при создании канала: напр. TEST3+MC0413600000).
|
||||
channel := s.profile.Channel + string(req.Header.SenderCode)
|
||||
pkgID, err := s.client.SendPackage(ctx, channel, string(pkgType), body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("nsdadapter: SendPackage: %w", err)
|
||||
}
|
||||
@@ -67,7 +73,7 @@ func (s *Sender) SendDecision(ctx context.Context, decision *m2m.M2MTransferDeci
|
||||
if err := decision.Validate(); err != nil {
|
||||
return fmt.Errorf("nsdadapter: decision.Validate: %w", err)
|
||||
}
|
||||
body, err := nsdxml.Marshal(decision)
|
||||
xmlBytes, err := nsdxml.Marshal(decision)
|
||||
if err != nil {
|
||||
return fmt.Errorf("nsdadapter: marshal Decision: %w", err)
|
||||
}
|
||||
@@ -75,7 +81,12 @@ func (s *Sender) SendDecision(ctx context.Context, decision *m2m.M2MTransferDeci
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := s.client.SendPackage(ctx, s.profile.Channel, string(pkgType), body); err != nil {
|
||||
body, err := igw.PackXML(xmlBytes, "M2MTransferDecision.xml", string(pkgType))
|
||||
if err != nil {
|
||||
return fmt.Errorf("nsdadapter: PackXML: %w", err)
|
||||
}
|
||||
channel := s.profile.Channel + string(decision.Header.SenderCode)
|
||||
if _, err := s.client.SendPackage(ctx, channel, string(pkgType), body); err != nil {
|
||||
return fmt.Errorf("nsdadapter: SendPackage: %w", err)
|
||||
}
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user