package nsdadapter import ( "context" "errors" "fmt" "time" "git.zetit.ru/zuevav/Bridge-and-Join-s/internal/m2m" "git.zetit.ru/zuevav/Bridge-and-Join-s/internal/nsdadapter/igw" "git.zetit.ru/zuevav/Bridge-and-Join-s/internal/nsdxml" ) // IGWClient — узкий интерфейс из igw.Client, нужный Sender'у. Введён // ради тестируемости (mock в тестах) и независимости от ИШ-реализации. type IGWClient interface { SendPackage(ctx context.Context, channel, packageType string, body []byte) (string, error) ListIncoming(ctx context.Context, channel string, since time.Time, packageType string) ([]igw.Package, error) } // Sender — реализация m2mcore.NSDSender поверх REST ИШ НРД. type Sender struct { profile Profile client IGWClient } // NewSender собирает Sender для указанного профиля. func NewSender(profile Profile, client IGWClient) *Sender { return &Sender{profile: profile, client: client} } // Send сериализует M2MTransferRequest в windows-1251, маршрутизирует к // типу пакета #M2MTR и отправляет в ИШ. M2MTransferResponse в этом // канале возвращается асинхронно через ListIncoming, поэтому Send // возвращает nil-response — реальный ответ забирает поллер. func (s *Sender) Send(ctx context.Context, req *m2m.M2MTransferRequest) (*m2m.M2MTransferResponse, error) { if req == nil { return nil, errors.New("nsdadapter: Send: req=nil") } 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) if err != nil { return nil, fmt.Errorf("nsdadapter: SendPackage: %w", err) } // Возвращаем псевдо-Response с GUID-ом для трассировки. Реальный // M2MTransferResponse от НРД придёт через входящие пакеты, его // обработает поллер cmd/nsd-adapter. _ = pkgID return nil, nil } // SendDecision сериализует и отправляет M2MTransferDecision. func (s *Sender) SendDecision(ctx context.Context, decision *m2m.M2MTransferDecision) error { if decision == nil { return errors.New("nsdadapter: SendDecision: decision=nil") } if err := decision.Validate(); err != nil { return fmt.Errorf("nsdadapter: decision.Validate: %w", err) } body, err := nsdxml.Marshal(decision) if err != nil { return fmt.Errorf("nsdadapter: marshal Decision: %w", err) } pkgType, err := RouteToPackageType(KindTransferDecision) if err != nil { return err } if _, err := s.client.SendPackage(ctx, s.profile.Channel, string(pkgType), body); err != nil { return fmt.Errorf("nsdadapter: SendPackage: %w", err) } return nil }