Files
go-caatsm/internal/infra/nats/utils.go
T

103 lines
2.4 KiB
Go

package nats
import (
"context"
"errors"
"net/url"
"strings"
"time"
"github.com/nats-io/nats.go"
)
// sleepWithContext sleeps for the specified duration, but returns early if the context is canceled.
// Returns true if the full duration was slept, false if the context was canceled.
func sleepWithContext(ctx context.Context, duration time.Duration) bool {
timer := time.NewTimer(duration)
defer timer.Stop()
select {
case <-timer.C:
return true
case <-ctx.Done():
return false
}
}
// isJetStreamResourceNotFound checks if an error indicates missing JetStream resources.
func isJetStreamResourceNotFound(err error) bool {
if err == nil {
return false
}
if errors.Is(err, nats.ErrStreamNotFound) || errors.Is(err, nats.ErrConsumerNotFound) {
return true
}
// Some JetStream API errors are only exposed via error strings.
msg := strings.ToLower(err.Error())
return strings.Contains(msg, "stream not found") || strings.Contains(msg, "consumer not found")
}
// sanitizeURLForLogging removes credentials from URLs for safe logging.
func sanitizeURLForLogging(rawURL string) string {
if rawURL == "" {
return ""
}
// Parse URL
u, err := url.Parse(rawURL)
if err != nil {
// If parsing fails, return a safe placeholder
return "***"
}
// Rebuild without credentials
u.User = nil
return u.String()
}
// mapDeliverPolicy maps string configuration to NATS DeliverPolicy.
func mapDeliverPolicy(value string) nats.DeliverPolicy {
switch strings.ToLower(value) {
case "new":
return nats.DeliverNewPolicy
case "last":
return nats.DeliverLastPolicy
case "last_per_subject":
return nats.DeliverLastPerSubjectPolicy
case "sequence":
return nats.DeliverByStartSequencePolicy
case "time":
return nats.DeliverByStartTimePolicy
default:
return nats.DeliverAllPolicy
}
}
// mapReplayPolicy maps string configuration to NATS ReplayPolicy.
func mapReplayPolicy(value string) nats.ReplayPolicy {
switch strings.ToLower(value) {
case "original":
return nats.ReplayOriginalPolicy
default:
return nats.ReplayInstantPolicy
}
}
// dedupeSubjects removes duplicate and empty subjects from a list.
func dedupeSubjects(subjects []string) []string {
seen := make(map[string]struct{})
result := make([]string, 0, len(subjects))
for _, subj := range subjects {
subj = strings.TrimSpace(subj)
if subj == "" {
continue
}
if _, ok := seen[subj]; ok {
continue
}
seen[subj] = struct{}{}
result = append(result, subj)
}
return result
}