Merge pull request 'cb-586' (#587) from cb-586 into main
Some checks failed
ci/woodpecker/push/callbacks Pipeline was successful
ci/woodpecker/push/discovery Pipeline was successful
ci/woodpecker/push/frontend Pipeline failed
ci/woodpecker/push/fx_ingestor Pipeline failed
ci/woodpecker/push/gateway_chain Pipeline was successful
ci/woodpecker/push/fx_oracle Pipeline failed
ci/woodpecker/push/gateway_mntx Pipeline was successful
ci/woodpecker/push/gateway_tgsettle Pipeline was successful
ci/woodpecker/push/ledger Pipeline failed
ci/woodpecker/push/gateway_tron Pipeline was successful
ci/woodpecker/push/notification Pipeline was successful
ci/woodpecker/push/payments_methods Pipeline was successful
ci/woodpecker/push/payments_quotation Pipeline failed
ci/woodpecker/push/payments_orchestrator Pipeline was successful
ci/woodpecker/push/billing_documents Pipeline was successful
ci/woodpecker/push/bff Pipeline was successful
ci/woodpecker/push/billing_fees Pipeline was successful

Reviewed-on: #587
This commit was merged in pull request #587.
This commit is contained in:
2026-02-28 20:02:08 +00:00
50 changed files with 371 additions and 366 deletions

View File

@@ -53,7 +53,7 @@ require (
github.com/nats-io/nuid v1.0.1 // indirect github.com/nats-io/nuid v1.0.1 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.2.0 // indirect github.com/xdg-go/scram v1.2.0 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect

View File

@@ -158,8 +158,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=

View File

@@ -38,7 +38,7 @@ require (
github.com/prometheus/client_golang v1.23.2 github.com/prometheus/client_golang v1.23.2
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.2.0 // indirect github.com/xdg-go/scram v1.2.0 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect

View File

@@ -113,8 +113,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=

View File

@@ -30,7 +30,7 @@ require (
github.com/nats-io/nuid v1.0.1 // indirect github.com/nats-io/nuid v1.0.1 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.2.0 // indirect github.com/xdg-go/scram v1.2.0 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect

View File

@@ -113,8 +113,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=

View File

@@ -119,7 +119,7 @@ require (
github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/segmentio/asm v1.2.1 // indirect github.com/segmentio/asm v1.2.1 // indirect
github.com/shirou/gopsutil/v3 v3.24.5 // indirect github.com/shirou/gopsutil/v3 v3.24.5 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect

View File

@@ -204,8 +204,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/segmentio/asm v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0= github.com/segmentio/asm v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0=

View File

@@ -28,15 +28,6 @@ messaging:
reconnect_wait: 5 reconnect_wait: 5
buffer_size: 1024 buffer_size: 1024
ingest:
stream: CALLBACKS
subject: callbacks.events
durable: callbacks-ingest
batch_size: 32
fetch_timeout_ms: 2000
idle_sleep_ms: 500
delivery: delivery:
worker_concurrency: 8 worker_concurrency: 8
worker_poll_ms: 200 worker_poll_ms: 200

View File

@@ -28,14 +28,6 @@ messaging:
reconnect_wait: 5 reconnect_wait: 5
buffer_size: 1024 buffer_size: 1024
ingest:
stream: CALLBACKS
subject: callbacks.events
durable: callbacks-ingest
batch_size: 32
fetch_timeout_ms: 2000
idle_sleep_ms: 500
delivery: delivery:
worker_concurrency: 8 worker_concurrency: 8
worker_poll_ms: 200 worker_poll_ms: 200

View File

@@ -6,7 +6,6 @@ replace github.com/tech/sendico/pkg => ../../pkg
require ( require (
github.com/go-chi/chi/v5 v5.2.5 github.com/go-chi/chi/v5 v5.2.5
github.com/nats-io/nats.go v1.49.0
github.com/prometheus/client_golang v1.23.2 github.com/prometheus/client_golang v1.23.2
github.com/tech/sendico/pkg v0.1.0 github.com/tech/sendico/pkg v0.1.0
go.mongodb.org/mongo-driver/v2 v2.5.0 go.mongodb.org/mongo-driver/v2 v2.5.0
@@ -40,11 +39,12 @@ require (
github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nats-io/nats.go v1.49.0 // indirect
github.com/nats-io/nkeys v0.4.15 // indirect github.com/nats-io/nkeys v0.4.15 // indirect
github.com/nats-io/nuid v1.0.1 // indirect github.com/nats-io/nuid v1.0.1 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.2.0 // indirect github.com/xdg-go/scram v1.2.0 // indirect

View File

@@ -144,8 +144,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=

View File

@@ -10,15 +10,6 @@ import (
const ( const (
defaultShutdownTimeoutSeconds = 15 defaultShutdownTimeoutSeconds = 15
defaultMetricsAddress = ":9420" defaultMetricsAddress = ":9420"
defaultIngestStream = "CALLBACKS"
defaultIngestSubject = "callbacks.events"
defaultIngestDurable = "callbacks-ingest"
defaultIngestBatchSize = 32
defaultIngestFetchTimeoutMS = 2000
defaultIngestIdleSleepMS = 500
defaultTaskCollection = "callback_tasks"
defaultInboxCollection = "callback_inbox"
defaultEndpointsCollection = "webhook_endpoints"
defaultWorkerConcurrency = 8 defaultWorkerConcurrency = 8
defaultWorkerPollIntervalMS = 200 defaultWorkerPollIntervalMS = 200
defaultLockTTLSeconds = 30 defaultLockTTLSeconds = 30
@@ -42,7 +33,6 @@ type Config struct {
Metrics *MetricsConfig `yaml:"metrics"` Metrics *MetricsConfig `yaml:"metrics"`
Database *db.Config `yaml:"database"` Database *db.Config `yaml:"database"`
Messaging *messaging.Config `yaml:"messaging"` Messaging *messaging.Config `yaml:"messaging"`
Ingest IngestConfig `yaml:"ingest"`
Delivery DeliveryConfig `yaml:"delivery"` Delivery DeliveryConfig `yaml:"delivery"`
Security SecurityConfig `yaml:"security"` Security SecurityConfig `yaml:"security"`
Secrets SecretsConfig `yaml:"secrets"` Secrets SecretsConfig `yaml:"secrets"`
@@ -72,30 +62,6 @@ func (c *MetricsConfig) ListenAddress() string {
return c.Address return c.Address
} }
// IngestConfig configures JetStream ingestion.
type IngestConfig struct {
Stream string `yaml:"stream"`
Subject string `yaml:"subject"`
Durable string `yaml:"durable"`
BatchSize int `yaml:"batch_size"`
FetchTimeoutMS int `yaml:"fetch_timeout_ms"`
IdleSleepMS int `yaml:"idle_sleep_ms"`
}
func (c *IngestConfig) FetchTimeout() time.Duration {
if c.FetchTimeoutMS <= 0 {
return time.Duration(defaultIngestFetchTimeoutMS) * time.Millisecond
}
return time.Duration(c.FetchTimeoutMS) * time.Millisecond
}
func (c *IngestConfig) IdleSleep() time.Duration {
if c.IdleSleepMS <= 0 {
return time.Duration(defaultIngestIdleSleepMS) * time.Millisecond
}
return time.Duration(c.IdleSleepMS) * time.Millisecond
}
// DeliveryConfig controls dispatcher behavior. // DeliveryConfig controls dispatcher behavior.
type DeliveryConfig struct { type DeliveryConfig struct {
WorkerConcurrency int `yaml:"worker_concurrency"` WorkerConcurrency int `yaml:"worker_concurrency"`

View File

@@ -1,6 +1,7 @@
package config package config
import ( import (
"bytes"
"os" "os"
"strings" "strings"
@@ -34,7 +35,9 @@ func (s *service) Load(path string) (*Config, error) {
} }
cfg := &Config{} cfg := &Config{}
if err := yaml.Unmarshal(data, cfg); err != nil { decoder := yaml.NewDecoder(bytes.NewReader(data))
decoder.KnownFields(true)
if err := decoder.Decode(cfg); err != nil {
s.logger.Error("Failed to parse config yaml", zap.String("path", path), zap.Error(err)) s.logger.Error("Failed to parse config yaml", zap.String("path", path), zap.Error(err))
return nil, merrors.InternalWrap(err, "failed to parse callbacks config") return nil, merrors.InternalWrap(err, "failed to parse callbacks config")
} }
@@ -58,25 +61,6 @@ func (s *service) applyDefaults(cfg *Config) {
cfg.Metrics.Address = defaultMetricsAddress cfg.Metrics.Address = defaultMetricsAddress
} }
if strings.TrimSpace(cfg.Ingest.Stream) == "" {
cfg.Ingest.Stream = defaultIngestStream
}
if strings.TrimSpace(cfg.Ingest.Subject) == "" {
cfg.Ingest.Subject = defaultIngestSubject
}
if strings.TrimSpace(cfg.Ingest.Durable) == "" {
cfg.Ingest.Durable = defaultIngestDurable
}
if cfg.Ingest.BatchSize <= 0 {
cfg.Ingest.BatchSize = defaultIngestBatchSize
}
if cfg.Ingest.FetchTimeoutMS <= 0 {
cfg.Ingest.FetchTimeoutMS = defaultIngestFetchTimeoutMS
}
if cfg.Ingest.IdleSleepMS <= 0 {
cfg.Ingest.IdleSleepMS = defaultIngestIdleSleepMS
}
if cfg.Delivery.WorkerConcurrency <= 0 { if cfg.Delivery.WorkerConcurrency <= 0 {
cfg.Delivery.WorkerConcurrency = defaultWorkerConcurrency cfg.Delivery.WorkerConcurrency = defaultWorkerConcurrency
} }
@@ -139,9 +123,6 @@ func (s *service) validate(cfg *Config) error {
if cfg.Delivery.MaxAttempts < 1 { if cfg.Delivery.MaxAttempts < 1 {
return merrors.InvalidArgument("delivery.max_attempts must be > 0", "delivery.max_attempts") return merrors.InvalidArgument("delivery.max_attempts must be > 0", "delivery.max_attempts")
} }
if cfg.Ingest.BatchSize < 1 {
return merrors.InvalidArgument("ingest.batch_size must be > 0", "ingest.batch_size")
}
vaultAddress := strings.TrimSpace(cfg.Secrets.Vault.Address) vaultAddress := strings.TrimSpace(cfg.Secrets.Vault.Address)
vaultTokenEnv := strings.TrimSpace(cfg.Secrets.Vault.TokenEnv) vaultTokenEnv := strings.TrimSpace(cfg.Secrets.Vault.TokenEnv)
vaultMountPath := strings.TrimSpace(cfg.Secrets.Vault.MountPath) vaultMountPath := strings.TrimSpace(cfg.Secrets.Vault.MountPath)

View File

@@ -4,10 +4,10 @@ import (
"context" "context"
"time" "time"
"github.com/nats-io/nats.go"
"github.com/tech/sendico/edge/callbacks/internal/events" "github.com/tech/sendico/edge/callbacks/internal/events"
"github.com/tech/sendico/edge/callbacks/internal/storage" "github.com/tech/sendico/edge/callbacks/internal/storage"
"github.com/tech/sendico/edge/callbacks/internal/subscriptions" "github.com/tech/sendico/edge/callbacks/internal/subscriptions"
mb "github.com/tech/sendico/pkg/messaging/broker"
"github.com/tech/sendico/pkg/mlogger" "github.com/tech/sendico/pkg/mlogger"
) )
@@ -16,21 +16,10 @@ type Observer interface {
ObserveIngest(result string, duration time.Duration) ObserveIngest(result string, duration time.Duration)
} }
// Config contains JetStream ingest settings.
type Config struct {
Stream string
Subject string
Durable string
BatchSize int
FetchTimeout time.Duration
IdleSleep time.Duration
}
// Dependencies configure the ingest service. // Dependencies configure the ingest service.
type Dependencies struct { type Dependencies struct {
Logger mlogger.Logger Logger mlogger.Logger
JetStream nats.JetStreamContext Broker mb.Broker
Config Config
Events events.Service Events events.Service
Resolver subscriptions.Resolver Resolver subscriptions.Resolver
InboxRepo storage.InboxRepo InboxRepo storage.InboxRepo
@@ -39,7 +28,7 @@ type Dependencies struct {
Observer Observer Observer Observer
} }
// Service runs JetStream ingest workers. // Service runs ingest workers.
type Service interface { type Service interface {
Start(ctx context.Context) Start(ctx context.Context)
Stop() Stop()

View File

@@ -2,59 +2,86 @@ package ingest
import ( import (
"context" "context"
"encoding/json"
"errors" "errors"
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/nats-io/nats.go" "github.com/tech/sendico/edge/callbacks/internal/events"
"github.com/tech/sendico/pkg/merrors" "github.com/tech/sendico/pkg/merrors"
pkgmsg "github.com/tech/sendico/pkg/messaging"
cons "github.com/tech/sendico/pkg/messaging/consumer"
me "github.com/tech/sendico/pkg/messaging/envelope"
pon "github.com/tech/sendico/pkg/messaging/notifications/paymentorchestrator"
np "github.com/tech/sendico/pkg/messaging/notifications/processor"
"github.com/tech/sendico/pkg/mlogger" "github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
"go.uber.org/zap" "go.uber.org/zap"
) )
const (
loggerNameIngest = "ingest"
logFieldSubject = "subject"
errBrokerRequired = "ingest: broker is required"
errEventsRequired = "ingest: events service is required"
errResolverRequired = "ingest: subscriptions resolver is required"
errInboxRepoRequired = "ingest: inbox repo is required"
errTaskRepoRequired = "ingest: task repo is required"
configFieldBroker = "broker"
configFieldEvents = "events"
configFieldResolver = "resolver"
configFieldInboxRepo = "inboxRepo"
configFieldTaskRepo = "taskRepo"
logFailedStartConsumer = "Failed to start messaging consumer"
logIngestConsumerStarted = "Ingest consumer started"
logIngestConsumerStopped = "Ingest consumer stopped"
logIngestConsumerWarn = "Ingest consumer stopped with error"
ingestResultOK = "ok"
ingestResultEmptyPayload = "empty_payload"
ingestResultInvalidEvent = "invalid_event"
ingestResultPayloadError = "payload_error"
ingestResultInboxError = "inbox_error"
ingestResultDuplicate = "duplicate"
ingestResultResolveError = "resolve_error"
ingestResultNoEndpoints = "no_endpoints"
ingestResultTaskError = "task_error"
)
type service struct { type service struct {
logger mlogger.Logger logger mlogger.Logger
js nats.JetStreamContext
cfg Config
deps Dependencies deps Dependencies
event model.NotificationEvent
cancel context.CancelFunc cancel context.CancelFunc
wg sync.WaitGroup wg sync.WaitGroup
once sync.Once once sync.Once
stop sync.Once stop sync.Once
mu sync.Mutex
consumer pkgmsg.Consumer
processor np.EnvelopeProcessor
} }
func newService(deps Dependencies) (Service, error) { func newService(deps Dependencies) (Service, error) {
if deps.JetStream == nil { if deps.Broker == nil {
return nil, merrors.InvalidArgument("ingest: jetstream context is required", "jetstream") return nil, merrors.InvalidArgument(errBrokerRequired, configFieldBroker)
} }
if deps.Events == nil { if deps.Events == nil {
return nil, merrors.InvalidArgument("ingest: events service is required", "events") return nil, merrors.InvalidArgument(errEventsRequired, configFieldEvents)
} }
if deps.Resolver == nil { if deps.Resolver == nil {
return nil, merrors.InvalidArgument("ingest: subscriptions resolver is required", "resolver") return nil, merrors.InvalidArgument(errResolverRequired, configFieldResolver)
} }
if deps.InboxRepo == nil { if deps.InboxRepo == nil {
return nil, merrors.InvalidArgument("ingest: inbox repo is required", "inboxRepo") return nil, merrors.InvalidArgument(errInboxRepoRequired, configFieldInboxRepo)
} }
if deps.TaskRepo == nil { if deps.TaskRepo == nil {
return nil, merrors.InvalidArgument("ingest: task repo is required", "taskRepo") return nil, merrors.InvalidArgument(errTaskRepoRequired, configFieldTaskRepo)
}
if strings.TrimSpace(deps.Config.Subject) == "" {
return nil, merrors.InvalidArgument("ingest: subject is required", "config.subject")
}
if strings.TrimSpace(deps.Config.Durable) == "" {
return nil, merrors.InvalidArgument("ingest: durable is required", "config.durable")
}
if deps.Config.BatchSize <= 0 {
deps.Config.BatchSize = 1
}
if deps.Config.FetchTimeout <= 0 {
deps.Config.FetchTimeout = 2 * time.Second
}
if deps.Config.IdleSleep <= 0 {
deps.Config.IdleSleep = 500 * time.Millisecond
} }
logger := deps.Logger logger := deps.Logger
@@ -62,12 +89,14 @@ func newService(deps Dependencies) (Service, error) {
logger = zap.NewNop() logger = zap.NewNop()
} }
return &service{ svc := &service{
logger: logger.Named("ingest"), logger: logger.Named(loggerNameIngest),
js: deps.JetStream,
cfg: deps.Config,
deps: deps, deps: deps,
}, nil }
svc.processor = pon.NewPaymentStatusUpdatedProcessor(svc.logger, svc.handlePaymentStatusUpdated)
svc.event = svc.processor.GetSubject()
return svc, nil
} }
func (s *service) Start(ctx context.Context) { func (s *service) Start(ctx context.Context) {
@@ -91,114 +120,119 @@ func (s *service) Stop() {
if s.cancel != nil { if s.cancel != nil {
s.cancel() s.cancel()
} }
s.closeConsumer()
s.wg.Wait() s.wg.Wait()
}) })
} }
func (s *service) run(ctx context.Context) { func (s *service) run(ctx context.Context) {
subOpts := []nats.SubOpt{} consumer, err := cons.NewConsumer(s.logger, s.deps.Broker, s.event)
if stream := strings.TrimSpace(s.cfg.Stream); stream != "" {
subOpts = append(subOpts, nats.BindStream(stream))
}
sub, err := s.js.PullSubscribe(strings.TrimSpace(s.cfg.Subject), strings.TrimSpace(s.cfg.Durable), subOpts...)
if err != nil { if err != nil {
s.logger.Error("Failed to start JetStream subscription", zap.String("subject", s.cfg.Subject), zap.String("durable", s.cfg.Durable), zap.Error(err)) s.logger.Error(logFailedStartConsumer, zap.String(logFieldSubject, s.event.ToString()), zap.Error(err))
return return
} }
s.setConsumer(consumer)
defer s.closeConsumer()
s.logger.Info("Ingest consumer started", zap.String("subject", s.cfg.Subject), zap.String("durable", s.cfg.Durable), zap.Int("batch_size", s.cfg.BatchSize)) s.logger.Info(logIngestConsumerStarted, zap.String(logFieldSubject, s.event.ToString()))
if err := consumer.ConsumeMessages(func(messageCtx context.Context, envelope me.Envelope) error {
for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
s.logger.Info("Ingest consumer stopped") return ctx.Err()
return
default: default:
} }
return s.processor.Process(messageCtx, envelope)
}); err != nil && !errors.Is(err, context.Canceled) {
s.logger.Warn(logIngestConsumerWarn, zap.String(logFieldSubject, s.event.ToString()), zap.Error(err))
}
s.logger.Info(logIngestConsumerStopped, zap.String(logFieldSubject, s.event.ToString()))
}
msgs, err := sub.Fetch(s.cfg.BatchSize, nats.MaxWait(s.cfg.FetchTimeout)) func (s *service) setConsumer(consumer pkgmsg.Consumer) {
if err != nil { s.mu.Lock()
if errors.Is(err, nats.ErrTimeout) { s.consumer = consumer
time.Sleep(s.cfg.IdleSleep) s.mu.Unlock()
continue }
}
if ctx.Err() != nil {
return
}
s.logger.Warn("Failed to fetch JetStream messages", zap.Error(err))
time.Sleep(s.cfg.IdleSleep)
continue
}
for _, msg := range msgs { func (s *service) closeConsumer() {
s.handleMessage(ctx, msg) s.mu.Lock()
} consumer := s.consumer
s.consumer = nil
s.mu.Unlock()
if consumer != nil {
consumer.Close()
} }
} }
func (s *service) handleMessage(ctx context.Context, msg *nats.Msg) { func (s *service) handlePaymentStatusUpdated(ctx context.Context, msg *model.PaymentStatusUpdated) error {
start := time.Now() start := time.Now()
result := "ok" result := ingestResultOK
nak := false
defer func() { defer func() {
if s.deps.Observer != nil { if s.deps.Observer != nil {
s.deps.Observer.ObserveIngest(result, time.Since(start)) s.deps.Observer.ObserveIngest(result, time.Since(start))
} }
var ackErr error
if nak {
ackErr = msg.Nak()
} else {
ackErr = msg.Ack()
}
if ackErr != nil {
s.logger.Warn("Failed to ack ingest message", zap.Bool("nak", nak), zap.Error(ackErr))
}
}() }()
envelope, err := s.deps.Events.Parse(msg.Data) if msg == nil {
if err != nil { result = ingestResultEmptyPayload
result = "invalid_event" return nil
nak = false }
return if strings.TrimSpace(msg.EventID) == "" || strings.TrimSpace(msg.ClientID) == "" || msg.OccurredAt.IsZero() {
result = ingestResultInvalidEvent
return nil
} }
inserted, err := s.deps.InboxRepo.TryInsert(ctx, envelope.EventID, envelope.ClientID, envelope.Type, time.Now().UTC()) eventType := strings.TrimSpace(msg.Type)
if eventType == "" {
eventType = model.PaymentStatusUpdatedType
}
data, err := json.Marshal(msg.Data)
if err != nil { if err != nil {
result = "inbox_error" result = ingestResultPayloadError
nak = true return err
return }
parsed := &events.Envelope{
EventID: strings.TrimSpace(msg.EventID),
Type: eventType,
ClientID: strings.TrimSpace(msg.ClientID),
OccurredAt: msg.OccurredAt.UTC(),
PublishedAt: msg.PublishedAt.UTC(),
Data: data,
}
inserted, err := s.deps.InboxRepo.TryInsert(ctx, parsed.EventID, parsed.ClientID, parsed.Type, time.Now().UTC())
if err != nil {
result = ingestResultInboxError
return err
} }
if !inserted { if !inserted {
result = "duplicate" result = ingestResultDuplicate
nak = false return nil
return
} }
endpoints, err := s.deps.Resolver.Resolve(ctx, envelope.ClientID, envelope.Type) endpoints, err := s.deps.Resolver.Resolve(ctx, parsed.ClientID, parsed.Type)
if err != nil { if err != nil {
result = "resolve_error" result = ingestResultResolveError
nak = true return err
return
} }
if len(endpoints) == 0 { if len(endpoints) == 0 {
result = "no_endpoints" result = ingestResultNoEndpoints
nak = false return nil
return
} }
payload, err := s.deps.Events.BuildPayload(ctx, envelope) payload, err := s.deps.Events.BuildPayload(ctx, parsed)
if err != nil { if err != nil {
result = "payload_error" result = ingestResultPayloadError
nak = true return err
return
} }
if err := s.deps.TaskRepo.UpsertTasks(ctx, envelope.EventID, endpoints, payload, s.deps.TaskDefaults, time.Now().UTC()); err != nil { if err := s.deps.TaskRepo.UpsertTasks(ctx, parsed.EventID, endpoints, payload, s.deps.TaskDefaults, time.Now().UTC()); err != nil {
result = "task_error" result = ingestResultTaskError
nak = true return err
return
} }
return nil
} }

View File

@@ -4,7 +4,6 @@ import (
"context" "context"
"time" "time"
"github.com/nats-io/nats.go"
"github.com/tech/sendico/edge/callbacks/internal/config" "github.com/tech/sendico/edge/callbacks/internal/config"
"github.com/tech/sendico/edge/callbacks/internal/delivery" "github.com/tech/sendico/edge/callbacks/internal/delivery"
"github.com/tech/sendico/edge/callbacks/internal/events" "github.com/tech/sendico/edge/callbacks/internal/events"
@@ -18,7 +17,6 @@ import (
"github.com/tech/sendico/edge/callbacks/internal/subscriptions" "github.com/tech/sendico/edge/callbacks/internal/subscriptions"
"github.com/tech/sendico/pkg/api/routers/health" "github.com/tech/sendico/pkg/api/routers/health"
"github.com/tech/sendico/pkg/db" "github.com/tech/sendico/pkg/db"
"github.com/tech/sendico/pkg/merrors"
msg "github.com/tech/sendico/pkg/messaging" msg "github.com/tech/sendico/pkg/messaging"
"github.com/tech/sendico/pkg/mlogger" "github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/vault/kv" "github.com/tech/sendico/pkg/vault/kv"
@@ -27,10 +25,6 @@ import (
const defaultShutdownTimeout = 15 * time.Second const defaultShutdownTimeout = 15 * time.Second
type jetStreamProvider interface {
JetStream() nats.JetStreamContext
}
func Create(logger mlogger.Logger, file string, debug bool) (*Imp, error) { func Create(logger mlogger.Logger, file string, debug bool) (*Imp, error) {
return &Imp{ return &Imp{
logger: logger.Named("server"), logger: logger.Named("server"),
@@ -118,23 +112,9 @@ func (i *Imp) Start() error {
} }
i.broker = broker i.broker = broker
jsProvider, ok := broker.(jetStreamProvider)
if !ok || jsProvider.JetStream() == nil {
i.shutdownRuntime(context.Background())
return merrors.Internal("callbacks: messaging broker does not provide JetStream")
}
ingestSvc, err := ingest.New(ingest.Dependencies{ ingestSvc, err := ingest.New(ingest.Dependencies{
Logger: i.logger, Logger: i.logger,
JetStream: jsProvider.JetStream(), Broker: broker,
Config: ingest.Config{
Stream: cfg.Ingest.Stream,
Subject: cfg.Ingest.Subject,
Durable: cfg.Ingest.Durable,
BatchSize: cfg.Ingest.BatchSize,
FetchTimeout: cfg.Ingest.FetchTimeout(),
IdleSleep: cfg.Ingest.IdleSleep(),
},
Events: eventSvc, Events: eventSvc,
Resolver: resolver, Resolver: resolver,
InboxRepo: repo.Inbox(), InboxRepo: repo.Inbox(),
@@ -176,8 +156,6 @@ func (i *Imp) Start() error {
i.opServer.SetStatus(health.SSRunning) i.opServer.SetStatus(health.SSRunning)
i.logger.Info("Callbacks service ready", i.logger.Info("Callbacks service ready",
zap.String("subject", cfg.Ingest.Subject),
zap.String("stream", cfg.Ingest.Stream),
zap.Int("workers", cfg.Delivery.WorkerConcurrency), zap.Int("workers", cfg.Delivery.WorkerConcurrency),
) )

View File

@@ -35,7 +35,7 @@ require (
github.com/nats-io/nuid v1.0.1 // indirect github.com/nats-io/nuid v1.0.1 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.2.0 // indirect github.com/xdg-go/scram v1.2.0 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect

View File

@@ -113,8 +113,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=

View File

@@ -36,7 +36,7 @@ require (
github.com/nats-io/nuid v1.0.1 // indirect github.com/nats-io/nuid v1.0.1 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.2.0 // indirect github.com/xdg-go/scram v1.2.0 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect

View File

@@ -113,8 +113,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=

View File

@@ -67,7 +67,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/supranational/blst v0.3.16 // indirect github.com/supranational/blst v0.3.16 // indirect

View File

@@ -236,8 +236,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=

View File

@@ -37,7 +37,7 @@ require (
github.com/nats-io/nkeys v0.4.15 // indirect github.com/nats-io/nkeys v0.4.15 // indirect
github.com/nats-io/nuid v1.0.1 // indirect github.com/nats-io/nuid v1.0.1 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/tklauser/go-sysconf v0.3.16 // indirect github.com/tklauser/go-sysconf v0.3.16 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect

View File

@@ -113,8 +113,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=

View File

@@ -36,7 +36,7 @@ require (
github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.2.0 // indirect github.com/xdg-go/scram v1.2.0 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect

View File

@@ -113,8 +113,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=

View File

@@ -74,7 +74,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/rjeczalik/notify v0.9.3 // indirect github.com/rjeczalik/notify v0.9.3 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect

View File

@@ -247,8 +247,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rjeczalik/notify v0.9.3 h1:6rJAzHTGKXGj76sbRgDiDcYj/HniypXmSJo1SWakZeY= github.com/rjeczalik/notify v0.9.3 h1:6rJAzHTGKXGj76sbRgDiDcYj/HniypXmSJo1SWakZeY=
github.com/rjeczalik/notify v0.9.3/go.mod h1:gF3zSOrafR9DQEWSE8TjfI9NkooDxbyT4UgRGKZA0lc= github.com/rjeczalik/notify v0.9.3/go.mod h1:gF3zSOrafR9DQEWSE8TjfI9NkooDxbyT4UgRGKZA0lc=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=

View File

@@ -37,7 +37,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.2.0 // indirect github.com/xdg-go/scram v1.2.0 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect

View File

@@ -113,8 +113,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=

View File

@@ -37,7 +37,7 @@ require (
github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/sendgrid/rest v2.6.9+incompatible // indirect github.com/sendgrid/rest v2.6.9+incompatible // indirect
github.com/toorop/go-dkim v0.0.0-20250226130143-9025cce95817 // indirect github.com/toorop/go-dkim v0.0.0-20250226130143-9025cce95817 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect

View File

@@ -119,8 +119,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/sendgrid/rest v2.6.9+incompatible h1:1EyIcsNdn9KIisLW50MKwmSRSK+ekueiEMJ7NEoxJo0= github.com/sendgrid/rest v2.6.9+incompatible h1:1EyIcsNdn9KIisLW50MKwmSRSK+ekueiEMJ7NEoxJo0=

View File

@@ -36,7 +36,7 @@ require (
github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/shopspring/decimal v1.4.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.2.0 // indirect github.com/xdg-go/scram v1.2.0 // indirect

View File

@@ -113,8 +113,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=

View File

@@ -51,7 +51,7 @@ require (
github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.2.0 // indirect github.com/xdg-go/scram v1.2.0 // indirect

View File

@@ -113,8 +113,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=

View File

@@ -128,7 +128,7 @@ func TestExecutePayment_PublishesStatusUpdates(t *testing.T) {
if strings.TrimSpace(outer.EventID) == "" { if strings.TrimSpace(outer.EventID) == "" {
t.Fatalf("expected non-empty event_id at %d", i) 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) t.Fatalf("event type mismatch at %d: got=%q want=%q", i, got, want)
} }
@@ -423,10 +423,17 @@ func (p *capturingProducer) SendMessage(envelope menv.Envelope) error {
if envelope == nil { if envelope == nil {
return nil return nil
} }
data, err := envelope.Serialize() data := envelope.GetData()
if len(data) == 0 {
serialized, err := envelope.Serialize()
if err != nil { if err != nil {
return err return err
} }
data = envelope.GetData()
if len(data) == 0 {
data = serialized
}
}
p.mu.Lock() p.mu.Lock()
p.items = append(p.items, capturedMessage{ p.items = append(p.items, capturedMessage{
Subject: envelope.GetSignature().ToString(), Subject: envelope.GetSignature().ToString(),

View File

@@ -2,25 +2,19 @@ package psvc
import ( import (
"context" "context"
"encoding/json"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"github.com/google/uuid"
"github.com/tech/sendico/payments/orchestrator/internal/service/orchestrationv2/agg" "github.com/tech/sendico/payments/orchestrator/internal/service/orchestrationv2/agg"
"github.com/tech/sendico/pkg/merrors"
msg "github.com/tech/sendico/pkg/messaging" 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/mlogger"
"github.com/tech/sendico/pkg/model" "github.com/tech/sendico/pkg/model"
nm "github.com/tech/sendico/pkg/model/notification"
"github.com/tech/sendico/pkg/mservice"
"go.uber.org/zap" "go.uber.org/zap"
) )
const ( const (
paymentStatusEventType = "payment.status.updated"
paymentStatusEventSender = "payments.orchestrator.v2" paymentStatusEventSender = "payments.orchestrator.v2"
) )
@@ -47,36 +41,6 @@ type brokerPaymentStatusPublisher struct {
producer msg.Producer 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 { func newPaymentStatusPublisher(logger mlogger.Logger, producer msg.Producer) paymentStatusPublisher {
if producer == nil { if producer == nil {
return noopPaymentStatusPublisher{} return noopPaymentStatusPublisher{}
@@ -114,7 +78,13 @@ func (p *brokerPaymentStatusPublisher) Publish(_ context.Context, in paymentStat
eventName = "state_changed" eventName = "state_changed"
} }
body, err := json.Marshal(paymentStatusEventData{ message := &model.PaymentStatusUpdated{
EventID: buildPaymentStatusEventID(paymentRef, payment.Version, in.CurrentState),
Type: model.PaymentStatusUpdatedType,
ClientID: payment.OrganizationRef.Hex(),
OccurredAt: occurredAt,
PublishedAt: time.Now().UTC(),
Data: model.PaymentStatusUpdatedData{
OrganizationRef: payment.OrganizationRef.Hex(), OrganizationRef: payment.OrganizationRef.Hex(),
PaymentRef: paymentRef, PaymentRef: paymentRef,
QuotationRef: strings.TrimSpace(payment.QuotationRef), QuotationRef: strings.TrimSpace(payment.QuotationRef),
@@ -125,31 +95,10 @@ func (p *brokerPaymentStatusPublisher) Publish(_ context.Context, in paymentStat
Version: payment.Version, Version: payment.Version,
IsTerminal: isTerminalState(in.CurrentState), IsTerminal: isTerminalState(in.CurrentState),
Event: eventName, Event: eventName,
}) },
if err != nil {
return merrors.InternalWrap(err, "payment status publish: marshal body failed")
} }
message, err := json.Marshal(callbackEventEnvelope{ envelope := pon.PaymentStatusUpdated(paymentStatusEventSender, message)
EventID: buildPaymentStatusEventID(paymentRef, payment.Version, in.CurrentState),
Type: paymentStatusEventType,
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")
}
signature := model.NewNotification(mservice.PaymentOrchestrator, nm.NAUpdated)
envelope := &rawEnvelope{
timestamp: occurredAt,
messageID: uuid.New(),
data: message,
sender: paymentStatusEventSender,
signature: signature,
}
if err := p.producer.SendMessage(envelope); err != nil { if err := p.producer.SendMessage(envelope); err != nil {
return err return err
@@ -176,34 +125,3 @@ func isTerminalState(state agg.State) bool {
func buildPaymentStatusEventID(paymentRef string, version uint64, state agg.State) string { func buildPaymentStatusEventID(paymentRef string, version uint64, state agg.State) string {
return paymentRef + ":" + strconv.FormatUint(version, 10) + ":" + string(state) 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)

View File

@@ -50,7 +50,7 @@ require (
github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.2.0 // indirect github.com/xdg-go/scram v1.2.0 // indirect

View File

@@ -113,8 +113,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=

View File

@@ -28,7 +28,7 @@ require (
github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.2.0 // indirect github.com/xdg-go/scram v1.2.0 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect

View File

@@ -107,8 +107,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=

View File

@@ -86,7 +86,7 @@ require (
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/shirou/gopsutil/v3 v3.24.5 // indirect github.com/shirou/gopsutil/v3 v3.24.5 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect

View File

@@ -193,8 +193,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=

View File

@@ -0,0 +1,42 @@
package notifications
import (
"encoding/json"
"strings"
messaging "github.com/tech/sendico/pkg/messaging/envelope"
"github.com/tech/sendico/pkg/model"
nm "github.com/tech/sendico/pkg/model/notification"
"github.com/tech/sendico/pkg/mservice"
)
type PaymentStatusUpdatedNotification struct {
messaging.Envelope
payload model.PaymentStatusUpdated
}
func (psn *PaymentStatusUpdatedNotification) Serialize() ([]byte, error) {
data, err := json.Marshal(psn.payload)
if err != nil {
return nil, err
}
return psn.Envelope.Wrap(data)
}
func paymentStatusUpdatedEvent() model.NotificationEvent {
return model.NewNotification(mservice.PaymentOrchestrator, nm.NAUpdated)
}
func NewPaymentStatusUpdatedEnvelope(sender string, status *model.PaymentStatusUpdated) messaging.Envelope {
payload := model.PaymentStatusUpdated{}
if status != nil {
payload = *status
}
if strings.TrimSpace(payload.Type) == "" {
payload.Type = model.PaymentStatusUpdatedType
}
return &PaymentStatusUpdatedNotification{
Envelope: messaging.CreateEnvelope(sender, paymentStatusUpdatedEvent()),
payload: payload,
}
}

View File

@@ -0,0 +1,51 @@
package notifications
import (
"context"
"encoding/json"
"strings"
me "github.com/tech/sendico/pkg/messaging/envelope"
ch "github.com/tech/sendico/pkg/messaging/notifications/paymentorchestrator/handler"
np "github.com/tech/sendico/pkg/messaging/notifications/processor"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
"go.uber.org/zap"
)
type PaymentStatusUpdatedProcessor struct {
logger mlogger.Logger
handler ch.PaymentStatusUpdatedHandler
event model.NotificationEvent
}
func (p *PaymentStatusUpdatedProcessor) Process(ctx context.Context, envelope me.Envelope) error {
var msg model.PaymentStatusUpdated
if err := json.Unmarshal(envelope.GetData(), &msg); err != nil {
p.logger.Warn("Failed to decode payment status updated envelope", zap.Error(err), zap.String("topic", p.event.ToString()))
return err
}
if strings.TrimSpace(msg.Type) == "" {
msg.Type = model.PaymentStatusUpdatedType
}
if p.handler == nil {
p.logger.Warn("Payment status updated handler is not configured", zap.String("topic", p.event.ToString()))
return nil
}
return p.handler(ctx, &msg)
}
func (p *PaymentStatusUpdatedProcessor) GetSubject() model.NotificationEvent {
return p.event
}
func NewPaymentStatusUpdatedProcessor(logger mlogger.Logger, handler ch.PaymentStatusUpdatedHandler) np.EnvelopeProcessor {
if logger != nil {
logger = logger.Named("payment_status_updated_processor")
}
return &PaymentStatusUpdatedProcessor{
logger: logger,
handler: handler,
event: paymentStatusUpdatedEvent(),
}
}

View File

@@ -0,0 +1,9 @@
package notifications
import (
"context"
"github.com/tech/sendico/pkg/model"
)
type PaymentStatusUpdatedHandler = func(context.Context, *model.PaymentStatusUpdated) error

View File

@@ -0,0 +1,18 @@
package notifications
import (
messaging "github.com/tech/sendico/pkg/messaging/envelope"
pinternal "github.com/tech/sendico/pkg/messaging/internal/notifications/paymentorchestrator"
ch "github.com/tech/sendico/pkg/messaging/notifications/paymentorchestrator/handler"
np "github.com/tech/sendico/pkg/messaging/notifications/processor"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
)
func PaymentStatusUpdated(sender string, status *model.PaymentStatusUpdated) messaging.Envelope {
return pinternal.NewPaymentStatusUpdatedEnvelope(sender, status)
}
func NewPaymentStatusUpdatedProcessor(logger mlogger.Logger, handler ch.PaymentStatusUpdatedHandler) np.EnvelopeProcessor {
return pinternal.NewPaymentStatusUpdatedProcessor(logger, handler)
}

View File

@@ -0,0 +1,29 @@
package model
import "time"
const (
PaymentStatusUpdatedType = "payment.status.updated"
)
type PaymentStatusUpdated struct {
EventID string `json:"event_id,omitempty"`
Type string `json:"type,omitempty"`
ClientID string `json:"client_id,omitempty"`
OccurredAt time.Time `json:"occurred_at,omitempty"`
PublishedAt time.Time `json:"published_at,omitempty"`
Data PaymentStatusUpdatedData `json:"data"`
}
type PaymentStatusUpdatedData struct {
OrganizationRef string `json:"organization_ref,omitempty"`
PaymentRef string `json:"payment_ref,omitempty"`
QuotationRef string `json:"quotation_ref,omitempty"`
ClientPaymentRef string `json:"client_payment_ref,omitempty"`
IdempotencyKey string `json:"idempotency_key,omitempty"`
State string `json:"state,omitempty"`
PreviousState string `json:"previous_state,omitempty"`
Version uint64 `json:"version,omitempty"`
IsTerminal bool `json:"is_terminal"`
Event string `json:"event,omitempty"`
}