Files
warmbly/internal/infrastructure/eventbus/factory.go
T
Matthew Meszaros a552e69070 infra(eventbus): EventBus interface + NATS JetStream impl
Transport-agnostic EventBus (Publish / Subscribe / Close / Name) with
two implementations:

  KafkaBus  - wraps the existing internal/infrastructure/kafka producer
              and consumer. Existing call sites that use the kafka
              package directly keep working.
  NATSBus   - JetStream-backed. File storage, 7d max age, durable
              consumers per group, manual ack with redelivery on
              handler error.

Factory FromEnv selects via EVENTBUS_PROVIDER (default kafka). NATS
needs NATS_URL; Kafka reuses the existing bootstrap+SASL config.

Subject naming converts Kafka colons to NATS dots so the existing
w:<uuid> topic naming works on both backends.

16 tests including round-trip ack-redelivery against an embedded
nats-server.
2026-05-27 14:42:33 +00:00

50 lines
1.5 KiB
Go

package eventbus
import (
"fmt"
"os"
"github.com/warmbly/warmbly/internal/infrastructure/kafka"
)
// FromEnv constructs the active EventBus from environment variables.
//
// EVENTBUS_PROVIDER=kafka -> NewKafka (defaults: existing kafka package)
// EVENTBUS_PROVIDER=nats -> NewNATS (JetStream)
// (unset) -> defaults to "kafka" for backwards compatibility
//
// Kafka selection inputs:
//
// bootstrap, sasl — passed in by the caller (already loaded from secrets).
//
// NATS selection inputs (all env):
//
// NATS_URL -> nats://host:port (default: nats://localhost:4222)
// NATS_STREAM_NAME -> JetStream stream name (default: "warmbly")
// NATS_SUBJECT_PREFIX -> subject prefix under the stream (default: "warmbly")
//
// The Kafka inputs are passed positionally rather than via env to match the
// existing wiring: bootstrap / SASL config already flow from cfg.Load* helpers
// in cmd/*. Self-hosters who pick NATS will leave those unset.
func FromEnv(bootstrap string, sasl *kafka.SASLConfig) (EventBus, error) {
provider := os.Getenv("EVENTBUS_PROVIDER")
if provider == "" {
provider = "kafka"
}
switch provider {
case "kafka":
return NewKafka(KafkaConfig{
Bootstrap: bootstrap,
SASL: sasl,
})
case "nats":
return NewNATS(NATSConfig{
URL: natsURLFromEnv(),
StreamName: os.Getenv("NATS_STREAM_NAME"),
SubjectPrefix: os.Getenv("NATS_SUBJECT_PREFIX"),
})
default:
return nil, fmt.Errorf("eventbus: unknown EVENTBUS_PROVIDER %q (want: kafka, nats)", provider)
}
}