discovery service
This commit is contained in:
103
api/pkg/discovery/kv.go
Normal file
103
api/pkg/discovery/kv.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package discovery
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/nats-io/nats.go"
|
||||
"github.com/tech/sendico/pkg/mlogger"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
const DefaultKVBucket = "discovery_registry"
|
||||
|
||||
type KVStore struct {
|
||||
logger mlogger.Logger
|
||||
kv nats.KeyValue
|
||||
bucket string
|
||||
}
|
||||
|
||||
func NewKVStore(logger mlogger.Logger, js nats.JetStreamContext, bucket string) (*KVStore, error) {
|
||||
if js == nil {
|
||||
return nil, errors.New("discovery kv: jetstream is nil")
|
||||
}
|
||||
if logger != nil {
|
||||
logger = logger.Named("discovery_kv")
|
||||
}
|
||||
bucket = strings.TrimSpace(bucket)
|
||||
if bucket == "" {
|
||||
bucket = DefaultKVBucket
|
||||
}
|
||||
kv, err := js.KeyValue(bucket)
|
||||
if err != nil {
|
||||
if errors.Is(err, nats.ErrBucketNotFound) {
|
||||
kv, err = js.CreateKeyValue(&nats.KeyValueConfig{
|
||||
Bucket: bucket,
|
||||
Description: "service discovery registry",
|
||||
History: 1,
|
||||
})
|
||||
if err == nil && logger != nil {
|
||||
logger.Info("Discovery KV bucket created", zap.String("bucket", bucket))
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &KVStore{
|
||||
logger: logger,
|
||||
kv: kv,
|
||||
bucket: bucket,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *KVStore) Put(entry RegistryEntry) error {
|
||||
if s == nil || s.kv == nil {
|
||||
return errors.New("discovery kv: not configured")
|
||||
}
|
||||
key := registryEntryKey(normalizeEntry(entry))
|
||||
if key == "" {
|
||||
return errors.New("discovery kv: entry key is empty")
|
||||
}
|
||||
payload, err := json.Marshal(entry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = s.kv.Put(kvKeyFromRegistryKey(key), payload)
|
||||
if err != nil && s.logger != nil {
|
||||
fields := append(entryFields(entry), zap.String("bucket", s.bucket), zap.String("key", key), zap.Error(err))
|
||||
s.logger.Warn("Failed to persist discovery entry", fields...)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *KVStore) Delete(id string) error {
|
||||
if s == nil || s.kv == nil {
|
||||
return errors.New("discovery kv: not configured")
|
||||
}
|
||||
key := kvKeyFromRegistryKey(id)
|
||||
if key == "" {
|
||||
return nil
|
||||
}
|
||||
if err := s.kv.Delete(key); err != nil && s.logger != nil {
|
||||
s.logger.Warn("Failed to delete discovery entry", zap.String("bucket", s.bucket), zap.String("key", key), zap.Error(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *KVStore) WatchAll() (nats.KeyWatcher, error) {
|
||||
if s == nil || s.kv == nil {
|
||||
return nil, errors.New("discovery kv: not configured")
|
||||
}
|
||||
return s.kv.WatchAll()
|
||||
}
|
||||
|
||||
func (s *KVStore) Bucket() string {
|
||||
if s == nil {
|
||||
return ""
|
||||
}
|
||||
return s.bucket
|
||||
}
|
||||
Reference in New Issue
Block a user