feat(igw): REST-клиент ИШ НРД по DOC/instr-ish-rest-api.pdf + упаковщик ZIP
Полный клиент Интеграционного шлюза НРД в internal/nsdadapter/igw/:
client.go — REST endpoint'ы по свежей спецификации НРД:
- POST /api/package/{channel}/file — отправка ZIP (Type=archive, File=base64)
возвращает id пакета (поддерживаются варианты id|package_id|ID)
- GET /api/package/status/{id} — статус NEW|SENT|ERROR (с error-полем)
- GET /api/package?channel=&type=M2MTD|M2MER&date=&id=&count=&excludeErrors=
— список входящих от НРД, с files[] и signs[] (ИШ сам проверяет ЭП и
выдаёт VALID|INVALID)
- GET /api/package/{id} — скачать ZIP (raw или base64-в-JSON, авто-детект
по сигнатуре PK\x03\x04)
- Ретраи только на 5xx/сетевые ошибки (4xx — сразу ошибка)
- HTTP-клиент через options, кастомный таймаут, ретраи
pack.go — упаковщик/распаковщик ZIP по разделу 2.3 инструкции:
- PackRequest(req, docName) — M2MTransferRequest→ZIP с config.xml
- PackXML(xml, docName, packageType) — для эталонных сообщений
- UnpackPackage(zip) → {DocXML, WinfXML, Signature, Filenames}
- ParseDecision / ParseResponse через nsdxml.Unmarshal
Покрыто тестами (10/10 PASS):
- send happy path с проверкой формата JSON-body
- retry на 5xx, без ретраев на 4xx
- GetStatus с числовым id
- ListIncoming как массив (новый формат) и как {items:[]} (старый)
- GetPackage raw ZIP + GetPackage с base64-в-JSON
- упаковка/распаковка: 2 файла в ZIP, имена, содержимое config.xml
- распаковка с .sgn и winf.xml
cmd/bj-server/main.go — NSD-poller адаптирован под новый API
(client.ListIncoming(ctx, ListFilter{}) вместо позиционных параметров;
поля Package.ID/Name/Type/State вместо PackageID/PackageType).
Скачана и положена в DOC/ свежая спецификация (798 KB, 15 стр):
DOC/instr-ish-rest-api.pdf — это исходный документ для нашей реализации.
REPORT.md обновлён:
- общая готовность 65% → 70%
- готовность к роботу 80% → 85%
- добавлен раздел про REST-клиент ИШ
- блокер #6 — отсутствие «Руководства по установке ИШ»
This commit is contained in:
@@ -110,15 +110,20 @@ func runNSDPoller(ctx context.Context, profileName string) {
|
||||
return
|
||||
case <-t.C:
|
||||
for _, kind := range nsdadapter.IncomingPackageKinds() {
|
||||
pkgs, err := client.ListIncoming(ctx, profile.Channel, since, string(kind))
|
||||
pkgs, err := client.ListIncoming(ctx, igw.ListFilter{
|
||||
Channel: profile.Channel,
|
||||
Date: since,
|
||||
Type: string(kind),
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("%s: NSD poller ListIncoming(%s, %s): %v", serviceName, profile.Channel, kind, err)
|
||||
continue
|
||||
}
|
||||
for _, p := range pkgs {
|
||||
log.Printf("%s: NSD входящий пакет %s типа %s (канал %s, получен %s)",
|
||||
serviceName, p.PackageID, p.PackageType, p.Channel, p.ReceivedAt.Format(time.RFC3339))
|
||||
// TODO(M3): парсить тело пакета, передавать в lkgateway.Service.ApplyDecision
|
||||
log.Printf("%s: NSD входящий пакет id=%d (%s) типа %s, канал %s, state %s",
|
||||
serviceName, p.ID, p.Name, p.Type, p.Channel, p.State)
|
||||
// TODO(M3): GetPackage(p.ID) → unpack ZIP → парсить XML →
|
||||
// передавать в lkgateway.Service.ApplyDecision
|
||||
}
|
||||
}
|
||||
since = time.Now().UTC()
|
||||
|
||||
Reference in New Issue
Block a user