Skip to content

Instantly share code, notes, and snippets.

@adpande
Last active March 22, 2024 07:32
Show Gist options
  • Save adpande/99881aef7de899c46916a47e0968825b to your computer and use it in GitHub Desktop.
Save adpande/99881aef7de899c46916a47e0968825b to your computer and use it in GitHub Desktop.
Read Config from Nats Bucket in Golang
// nats kv add config
// nats kv create config host localhost
// nats kv create config port 8080
type AppConfig struct {
Host string `natsKey:"host" natsDefault:"localhost"`
Port int64 `natsKey:"port" natsDefault:"8080"`
}
func ReadConfigFromJetStreamBucket(bucket string) error {
ctx := context.Background()
structure := AppConfig{} // init above structure
kv, err := jetStreamClient.KeyValue(ctx, bucket)
if err != nil {
slog.Error("Error getting config bucket from nats", "error", err, "bucket", bucket)
panic(err)
}
val := reflect.ValueOf(*structure)
for i := 0; i < val.NumField(); i++ {
field := reflect.ValueOf(structure).Elem().Field(i)
natsKey := val.Type().Field(i).Tag.Get("natsKey")
natsDefault := val.Type().Field(i).Tag.Get("natsDefault")
kvEntry, err := kv.Get(ctx, natsKey)
if err != nil {
slog.Error("Error getting key value", "error", err)
slog.Info("Setting default value", "key", natsKey, "value", natsDefault)
// check field type and set default value
kind := val.Type().Field(i).Type.Kind()
switch kind {
case reflect.String:
if field.CanSet() {
field.SetString(natsDefault)
} else {
slog.Error("Field is not settable", "field", field)
panic("Field is not settable")
}
case reflect.Int:
// convert string to int
intValue, err := strconv.Atoi(natsDefault)
if err != nil {
slog.Error("Error converting string to int", "error", err)
}
if field.CanSet() {
field.SetInt(int64(intValue))
} else {
slog.Error("Field is not settable", "field", field)
panic("Field is not settable")
}
case reflect.Bool:
// convert string to bool
boolValue, err := strconv.ParseBool(natsDefault)
if err != nil {
slog.Error("Error converting string to bool", "error", err)
}
if field.CanSet() {
field.SetBool(boolValue)
} else {
slog.Error("Field is not settable", "field", field)
panic("Field is not settable")
}
default:
slog.Error("Unknown type", "type", kind)
}
} else {
value := kvEntry.Value()
valueString := string(value)
slog.Info("Setting value", "key", natsKey, "value", valueString)
// check field type and set value
kind := val.Type().Field(i).Type.Kind()
switch kind {
case reflect.String:
slog.Info("Setting value", "key", natsKey, "value", valueString)
//field.Set(reflect.ValueOf(valueString))
if field.CanSet() {
field.SetString(valueString)
} else {
slog.Error("Field is not settable", "field", field)
panic("Field is not settable")
}
case reflect.Int:
slog.Info("Setting value", "key", natsKey, "value", valueString)
// convert string to int
intValue, err := strconv.Atoi(valueString)
if err != nil {
slog.Error("Error converting string to int", "error", err)
}
if field.CanSet() {
field.SetInt(int64(intValue))
} else {
slog.Error("Field is not settable", "field", field)
panic("Field is not settable")
}
case reflect.Bool:
slog.Info("Setting value", "key", natsKey, "value", valueString)
// convert string to bool
boolValue, err := strconv.ParseBool(valueString)
if err != nil {
slog.Error("Error converting string to bool", "error", err)
}
if field.CanSet() {
field.SetBool(boolValue)
} else {
slog.Error("Field is not settable", "field", field)
panic("Field is not settable")
}
default:
slog.Error("Unknown type", "type", kind)
}
}
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment