Compare commits

...

8 Commits

Author SHA1 Message Date
lash
c8c0daac24 Merge remote-tracking branch 'origin/master' into feature/6-config-reporter-new 2025-03-15 02:25:42 +00:00
lash
1bcffe2d23
Make tests work without configreport flag 2025-03-15 02:22:48 +00:00
bf10e5357c Merge pull request 'config reporter' (#7) from konstantinmds/visedriver:feature/6-config-reporter-new into master
Reviewed-on: #7
2025-02-28 00:09:49 +01:00
Konstantin
d91c96f541 removing redundant logline 2025-02-28 00:06:14 +01:00
Konstantin
ec9032a42e change on report method 2025-02-25 00:17:00 +01:00
Konstantin
6619afe62b config reporter for external applications 2025-02-07 16:04:40 +01:00
lash
1eb0b15552
Update deps 2025-02-04 13:23:47 +00:00
lash
ef803e0ee2
Enable custom engine factory 2025-02-04 13:08:08 +00:00
7 changed files with 217 additions and 22 deletions

View File

@ -1,6 +1,7 @@
package config
import (
"strconv"
"strings"
"git.defalsify.org/vise.git/logging"
@ -23,6 +24,7 @@ var (
userDbConn string
userDbConnMode storage.DbMode
Languages []string
configManager *Config
)
type Override struct {
@ -134,6 +136,17 @@ func GetConns() (storage.Conns, error) {
// LoadConfig initializes the configuration values after environment variables are loaded.
func LoadConfig() error {
configManager = NewConfig(logg)
// Add configuration keys with validation
configManager.AddKey("HOST", "127.0.0.1", false, nil)
configManager.AddKey("PORT", "7123", false, func(v string) error {
_, err := strconv.Atoi(v)
return err
})
configManager.AddKey("DB_CONN", "", true, nil)
// ... add other keys ? or is enough :/ ...
err := setConn()
if err != nil {
return err
@ -145,5 +158,7 @@ func LoadConfig() error {
DefaultLanguage = defaultLanguage
Languages = languages
// Report configuration
configManager.Report("INFO")
return nil
}

63
config/config_test.go Normal file
View File

@ -0,0 +1,63 @@
// +build configreport
package config
import (
"fmt"
"os"
"testing"
"git.defalsify.org/vise.git/logging"
)
// go test -tags configreport ./config/... ---> run with tag
func TestConfig(t *testing.T) {
logger := logging.NewVanilla().WithDomain("test")
cfg := NewConfig(logger)
t.Run("Default Values", func(t *testing.T) {
cfg.AddKey("TEST_KEY", "default", false, nil)
value, err := cfg.GetValue("TEST_KEY")
t.Logf("Got value: %q, error: %v", value, err)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if value != "default" {
t.Errorf("expected 'default', got '%s'", value)
}
})
t.Run("Environment Override", func(t *testing.T) {
os.Setenv("TEST_ENV_KEY", "override")
defer os.Unsetenv("TEST_ENV_KEY")
cfg.AddKey("TEST_ENV_KEY", "default", false, nil)
value, err := cfg.GetValue("TEST_ENV_KEY")
t.Logf("Got value: %q, error: %v", value, err)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if value != "override" {
t.Errorf("expected 'override', got '%s'", value)
}
})
t.Run("Validation", func(t *testing.T) {
validator := func(v string) error {
if v != "valid" {
return fmt.Errorf("invalid value")
}
return nil
}
cfg.AddKey("VALIDATED_KEY", "valid", false, validator)
os.Setenv("VALIDATED_KEY", "invalid")
defer os.Unsetenv("VALIDATED_KEY")
value, err := cfg.GetValue("VALIDATED_KEY")
t.Logf("Got value: %q, error: %v", value, err)
if err == nil {
t.Error("expected validation error, got nil")
}
})
}

95
config/reporter.go Normal file
View File

@ -0,0 +1,95 @@
//go:build configreport
package config
import (
"fmt"
"git.defalsify.org/vise.git/logging"
"git.grassecon.net/grassrootseconomics/visedriver/env"
)
// ConfigValue represents a configuration key-value pair
type ConfigValue struct {
Key string
Default string
Validator func(string) error
Sensitive bool
}
// Config handles configuration management and reporting
type Config struct {
values map[string]ConfigValue
logger logging.Vanilla
}
func NewConfig(logger logging.Vanilla) *Config {
return &Config{
values: make(map[string]ConfigValue),
logger: logger,
}
}
// AddKey registers a new configuration key with optional validation
func (c *Config) AddKey(key string, defaultValue string, sensitive bool, validator func(string) error) {
c.values[key] = ConfigValue{
Key: key,
Default: defaultValue,
Validator: validator,
Sensitive: sensitive,
}
}
// GetValue returns the value for a given key, applying environment override if present
func (c *Config) GetValue(key string) (string, error) {
// Find config value by key
var cv ConfigValue
for _, v := range c.values {
if v.Key == key {
cv = v
break
}
}
if cv.Key == "" {
return "", fmt.Errorf("configuration key not found: %s", key)
}
// Get value from environment or default
value := env.GetEnv(key, cv.Default)
// Validate if validator exists
if cv.Validator != nil && cv.Validator(value) != nil {
return "", fmt.Errorf("invalid value for key %s", key)
}
return value, nil
}
// Report outputs all configuration values at the specified log level
func (c *Config) Report(level string) {
for _, cv := range c.values {
value, err := c.GetValue(cv.Key)
if err != nil {
c.logger.Errorf("Error getting value for %s: %v", cv.Key, err)
continue
}
if cv.Sensitive {
value = "****"
}
switch level {
case "DEBUG":
c.logger.Debugf("config set", cv.Key, value)
case "INFO":
c.logger.Infof("config set", cv.Key, value)
case "WARN":
c.logger.Warnf("config set", cv.Key, value)
case "ERROR":
c.logger.Errorf("config set", cv.Key, value)
default:
c.logger.Infof("config set", cv.Key, value)
}
}
}

21
config/reporter_noop.go Normal file
View File

@ -0,0 +1,21 @@
//go:build !configreport
package config
import (
"git.defalsify.org/vise.git/logging"
)
type Config struct{}
func NewConfig(logger logging.Vanilla) *Config {
return &Config{}
}
func (c *Config) AddKey(key string, defaultValue string, sensitive bool, validator func(string) error) {}
func (c *Config) GetValue(key string) (string, error) {
return "", nil
}
func (c *Config) Report(level string) {}

2
go.mod
View File

@ -3,7 +3,7 @@ module git.grassecon.net/grassrootseconomics/visedriver
go 1.23.0
require (
git.defalsify.org/vise.git v0.2.3-0.20250120121301-10739fb4a8c9
git.defalsify.org/vise.git v0.2.3-0.20250204132233-2bffe532f21e
github.com/jackc/pgx/v5 v5.7.1
github.com/joho/godotenv v1.5.1
)

4
go.sum
View File

@ -1,5 +1,5 @@
git.defalsify.org/vise.git v0.2.3-0.20250120121301-10739fb4a8c9 h1:sPcqXQcywxA8W3W+9qQncLPmsrgqTIlec7vmD4/7vyA=
git.defalsify.org/vise.git v0.2.3-0.20250120121301-10739fb4a8c9/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck=
git.defalsify.org/vise.git v0.2.3-0.20250204132233-2bffe532f21e h1:gtB9OdX6x5gQRM3W824dEurXuuf/YPInqgtv2KAp5Zo=
git.defalsify.org/vise.git v0.2.3-0.20250204132233-2bffe532f21e/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck=
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c h1:H9Nm+I7Cg/YVPpEV1RzU3Wq2pjamPc/UtHDgItcb7lE=
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c/go.mod h1:rGod7o6KPeJ+hyBpHfhi4v7blx9sf+QsHsA7KAsdN6U=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

View File

@ -12,23 +12,32 @@ import (
"git.grassecon.net/grassrootseconomics/visedriver/storage"
)
type EngineFunc func(engine.Config, resource.Resource, *persist.Persister) engine.Engine
type BaseRequestHandler struct {
cfgTemplate engine.Config
rp RequestParser
rs resource.Resource
hn entry.EntryHandler
provider storage.StorageProvider
engineFunc EngineFunc
}
// func NewBaseRequestHandler(cfg engine.Config, rs resource.Resource, stateDb db.Db, userdataDb db.Db, rp request.RequestParser, hn *handlers.Handlers) *BaseRequestHandler {
func NewBaseRequestHandler(cfg engine.Config, rs resource.Resource, stateDb db.Db, userdataDb db.Db, rp RequestParser, hn entry.EntryHandler) *BaseRequestHandler {
return &BaseRequestHandler{
h := &BaseRequestHandler{
cfgTemplate: cfg,
rs: rs,
hn: hn,
rp: rp,
provider: storage.NewSimpleStorageProvider(stateDb, userdataDb),
}
h.engineFunc = h.getDefaultEngine
return h
}
func (f *BaseRequestHandler) WithEngineFunc(fn EngineFunc) *BaseRequestHandler {
f.engineFunc = fn
return f
}
func (f *BaseRequestHandler) Shutdown(ctx context.Context) {
@ -39,15 +48,22 @@ func (f *BaseRequestHandler) Shutdown(ctx context.Context) {
}
func (f *BaseRequestHandler) GetEngine(cfg engine.Config, rs resource.Resource, pr *persist.Persister) engine.Engine {
return f.engineFunc(cfg, rs, pr)
}
func (f *BaseRequestHandler) getDefaultEngine(cfg engine.Config, rs resource.Resource, pr *persist.Persister) engine.Engine {
en := engine.NewEngine(cfg, rs)
en = en.WithPersister(pr)
en = en.WithFirst(f.hn.Init)
if f.cfgTemplate.EngineDebug {
en = en.WithDebug(nil)
}
return en
}
func (f *BaseRequestHandler) Process(rqs RequestSession) (RequestSession, error) {
var r bool
var err error
var ok bool
logg.InfoCtxf(rqs.Ctx, "new request", "data", rqs)
@ -57,27 +73,12 @@ func (f *BaseRequestHandler) Process(rqs RequestSession) (RequestSession, error)
return rqs, errors.ErrStorage
}
//f.hn = f.hn.WithPersister(rqs.Storage.Persister)
f.hn.SetPersister(rqs.Storage.Persister)
defer func() {
f.hn.Exit()
}()
eni := f.GetEngine(rqs.Config, f.rs, rqs.Storage.Persister)
en, ok := eni.(*engine.DefaultEngine)
if !ok {
perr := f.provider.Put(rqs.Ctx, rqs.Config.SessionId, rqs.Storage)
rqs.Storage = nil
if perr != nil {
logg.ErrorCtxf(rqs.Ctx, "", "storage put error", perr)
}
return rqs, errors.ErrEngineType
}
en = en.WithFirst(f.hn.Init)
if rqs.Config.EngineDebug {
en = en.WithDebug(nil)
}
rqs.Engine = en
rqs.Engine = f.GetEngine(rqs.Config, f.rs, rqs.Storage.Persister)
r, err = rqs.Engine.Exec(rqs.Ctx, rqs.Input)
if err != nil {
perr := f.provider.Put(rqs.Ctx, rqs.Config.SessionId, rqs.Storage)