refactored orchestrator and callbacks service to use pkg messsaging + envelope factory / handler

This commit is contained in:
Stephan D
2026-02-28 20:56:26 +01:00
parent 363d6474f2
commit 12c67361dd
14 changed files with 316 additions and 311 deletions

View File

@@ -128,7 +128,7 @@ func TestExecutePayment_PublishesStatusUpdates(t *testing.T) {
if strings.TrimSpace(outer.EventID) == "" {
t.Fatalf("expected non-empty event_id at %d", i)
}
if got, want := outer.Type, paymentStatusEventType; got != want {
if got, want := outer.Type, pm.PaymentStatusUpdatedType; got != want {
t.Fatalf("event type mismatch at %d: got=%q want=%q", i, got, want)
}
@@ -423,9 +423,16 @@ func (p *capturingProducer) SendMessage(envelope menv.Envelope) error {
if envelope == nil {
return nil
}
data, err := envelope.Serialize()
if err != nil {
return err
data := envelope.GetData()
if len(data) == 0 {
serialized, err := envelope.Serialize()
if err != nil {
return err
}
data = envelope.GetData()
if len(data) == 0 {
data = serialized
}
}
p.mu.Lock()
p.items = append(p.items, capturedMessage{

View File

@@ -2,25 +2,19 @@ package psvc
import (
"context"
"encoding/json"
"strconv"
"strings"
"time"
"github.com/google/uuid"
"github.com/tech/sendico/payments/orchestrator/internal/service/orchestrationv2/agg"
"github.com/tech/sendico/pkg/merrors"
msg "github.com/tech/sendico/pkg/messaging"
me "github.com/tech/sendico/pkg/messaging/envelope"
pon "github.com/tech/sendico/pkg/messaging/notifications/paymentorchestrator"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
nm "github.com/tech/sendico/pkg/model/notification"
"github.com/tech/sendico/pkg/mservice"
"go.uber.org/zap"
)
const (
paymentStatusEventType = "payment.status.updated"
paymentStatusEventSender = "payments.orchestrator.v2"
)
@@ -47,36 +41,6 @@ type brokerPaymentStatusPublisher struct {
producer msg.Producer
}
type callbackEventEnvelope struct {
EventID string `json:"event_id"`
Type string `json:"type"`
ClientID string `json:"client_id"`
OccurredAt time.Time `json:"occurred_at"`
PublishedAt time.Time `json:"published_at,omitempty"`
Data json.RawMessage `json:"data"`
}
type paymentStatusEventData struct {
OrganizationRef string `json:"organization_ref"`
PaymentRef string `json:"payment_ref"`
QuotationRef string `json:"quotation_ref"`
ClientPaymentRef string `json:"client_payment_ref,omitempty"`
IdempotencyKey string `json:"idempotency_key,omitempty"`
State string `json:"state"`
PreviousState string `json:"previous_state,omitempty"`
Version uint64 `json:"version"`
IsTerminal bool `json:"is_terminal"`
Event string `json:"event"`
}
type rawEnvelope struct {
timestamp time.Time
messageID uuid.UUID
data []byte
sender string
signature model.NotificationEvent
}
func newPaymentStatusPublisher(logger mlogger.Logger, producer msg.Producer) paymentStatusPublisher {
if producer == nil {
return noopPaymentStatusPublisher{}
@@ -114,42 +78,27 @@ func (p *brokerPaymentStatusPublisher) Publish(_ context.Context, in paymentStat
eventName = "state_changed"
}
body, err := json.Marshal(paymentStatusEventData{
OrganizationRef: payment.OrganizationRef.Hex(),
PaymentRef: paymentRef,
QuotationRef: strings.TrimSpace(payment.QuotationRef),
ClientPaymentRef: strings.TrimSpace(payment.ClientPaymentRef),
IdempotencyKey: strings.TrimSpace(payment.IdempotencyKey),
State: string(in.CurrentState),
PreviousState: normalizePreviousState(in.PreviousState, in.CurrentState),
Version: payment.Version,
IsTerminal: isTerminalState(in.CurrentState),
Event: eventName,
})
if err != nil {
return merrors.InternalWrap(err, "payment status publish: marshal body failed")
}
message, err := json.Marshal(callbackEventEnvelope{
message := &model.PaymentStatusUpdated{
EventID: buildPaymentStatusEventID(paymentRef, payment.Version, in.CurrentState),
Type: paymentStatusEventType,
Type: model.PaymentStatusUpdatedType,
ClientID: payment.OrganizationRef.Hex(),
OccurredAt: occurredAt,
PublishedAt: time.Now().UTC(),
Data: body,
})
if err != nil {
return merrors.InternalWrap(err, "payment status publish: marshal envelope failed")
Data: model.PaymentStatusUpdatedData{
OrganizationRef: payment.OrganizationRef.Hex(),
PaymentRef: paymentRef,
QuotationRef: strings.TrimSpace(payment.QuotationRef),
ClientPaymentRef: strings.TrimSpace(payment.ClientPaymentRef),
IdempotencyKey: strings.TrimSpace(payment.IdempotencyKey),
State: string(in.CurrentState),
PreviousState: normalizePreviousState(in.PreviousState, in.CurrentState),
Version: payment.Version,
IsTerminal: isTerminalState(in.CurrentState),
Event: eventName,
},
}
signature := model.NewNotification(mservice.PaymentOrchestrator, nm.NAUpdated)
envelope := &rawEnvelope{
timestamp: occurredAt,
messageID: uuid.New(),
data: message,
sender: paymentStatusEventSender,
signature: signature,
}
envelope := pon.PaymentStatusUpdated(paymentStatusEventSender, message)
if err := p.producer.SendMessage(envelope); err != nil {
return err
@@ -176,34 +125,3 @@ func isTerminalState(state agg.State) bool {
func buildPaymentStatusEventID(paymentRef string, version uint64, state agg.State) string {
return paymentRef + ":" + strconv.FormatUint(version, 10) + ":" + string(state)
}
func (e *rawEnvelope) Serialize() ([]byte, error) {
return append([]byte(nil), e.data...), nil
}
func (e *rawEnvelope) GetTimeStamp() time.Time {
return e.timestamp
}
func (e *rawEnvelope) GetMessageId() uuid.UUID {
return e.messageID
}
func (e *rawEnvelope) GetData() []byte {
return append([]byte(nil), e.data...)
}
func (e *rawEnvelope) GetSender() string {
return e.sender
}
func (e *rawEnvelope) GetSignature() model.NotificationEvent {
return e.signature
}
func (e *rawEnvelope) Wrap(data []byte) ([]byte, error) {
e.data = append([]byte(nil), data...)
return e.Serialize()
}
var _ me.Envelope = (*rawEnvelope)(nil)