Skip to content

Commit

Permalink
Revert "feat: simplify config/secret API (#1241)"
Browse files Browse the repository at this point in the history
This reverts commit 2f3fc07.
  • Loading branch information
alecthomas committed Apr 12, 2024
1 parent 2f3fc07 commit f8e6d30
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 68 deletions.
1 change: 0 additions & 1 deletion common/configuration/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ type Entry struct {

// A Ref is a reference to a configuration value.
type Ref struct {
// If not present, the Ref is considered to be global.
Module optional.Option[string]
Name string
}
Expand Down
2 changes: 1 addition & 1 deletion examples/go/echo/echo.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ func Echo(ctx context.Context, req EchoRequest) (EchoResponse, error) {
return EchoResponse{}, err
}

return EchoResponse{Message: fmt.Sprintf("Hello, %s!!! It is %s!", req.Name.Default(defaultName.Get()), tresp.Time)}, nil
return EchoResponse{Message: fmt.Sprintf("Hello, %s!!! It is %s!", req.Name.Default(defaultName.Get(ctx)), tresp.Time)}, nil
}
43 changes: 12 additions & 31 deletions go-runtime/ftl/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,23 @@ package ftl
import (
"context"
"fmt"
"os"
"runtime"
"strings"
"sync"

cf "github.com/TBD54566975/ftl/common/configuration"
"github.com/TBD54566975/ftl/internal/log"
"github.com/TBD54566975/ftl/common/configuration"
)

var globalConfigurationManagerOnce sync.Once
// ConfigType is a type that can be used as a configuration value.
type ConfigType interface{ any }

// globalConfigurationManager returns a global configuration manager instance.
func globalConfigurationManager() (manager *cf.Manager[cf.Configuration]) {
globalConfigurationManagerOnce.Do(func() {
var configs []string
if envar, ok := os.LookupEnv("FTL_CONFIG"); ok {
configs = strings.Split(envar, ",")
}
config := cf.DefaultConfigMixin{}
var err error
ctx := log.ContextWithNewDefaultLogger(context.Background())
manager, err = config.NewConfigurationManager(ctx, cf.ProjectConfigResolver[cf.Configuration]{Config: configs})
if err != nil {
panic("failed to create global configuration manager: " + err.Error())
}
})
return manager
}

// Config loads a typed configuration value for the current module.
func Config[T any](name string) ConfigValue[T] {
// Config declares a typed configuration key for the current module.
func Config[T ConfigType](name string) ConfigValue[T] {
module := callerModule()
return ConfigValue[T]{module, name}
}

// ConfigValue is a typed configuration key for the current module.
type ConfigValue[T any] struct {
type ConfigValue[T ConfigType] struct {
module string
name string
}
Expand All @@ -52,11 +32,12 @@ func (c ConfigValue[T]) GoString() string {
}

// Get returns the value of the configuration key from FTL.
func (c ConfigValue[T]) Get() (out T) {
cm := globalConfigurationManager()
ctx := log.ContextWithNewDefaultLogger(context.Background())
if err := cm.Get(ctx, cf.NewRef(c.module, c.name), &out); err != nil {
panic(fmt.Errorf("failed to get configuration %s.%s: %w", c.module, c.name, err))
func (c ConfigValue[T]) Get(ctx context.Context) (out T) {
cm := configuration.ConfigFromContext(ctx)
ref := configuration.NewRef(c.module, c.name)
err := cm.Get(ctx, ref, &out)
if err != nil {
panic(fmt.Errorf("failed to get %s: %w", c, err))
}
return
}
Expand Down
14 changes: 12 additions & 2 deletions go-runtime/ftl/config_test.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
package ftl

import (
"context"
"testing"

"github.com/alecthomas/assert/v2"

"github.com/TBD54566975/ftl/common/configuration"
"github.com/TBD54566975/ftl/common/projectconfig"
"github.com/TBD54566975/ftl/internal/log"
)

func TestConfig(t *testing.T) {
t.Setenv("FTL_CONFIG", "testdata/ftl-project.toml")
ctx := log.ContextWithNewDefaultLogger(context.Background())
cr := configuration.ProjectConfigResolver[configuration.Configuration]{Config: []string{"testdata/ftl-project.toml"}}
assert.Equal(t, []string{"testdata/ftl-project.toml"}, projectconfig.ConfigPaths(cr.Config))
cm, err := configuration.NewConfigurationManager(ctx, cr)
assert.NoError(t, err)
ctx = configuration.ContextWithConfig(ctx, cm)
type C struct {
One string
Two string
}
config := Config[C]("test")
assert.Equal(t, C{"one", "two"}, config.Get())
assert.Equal(t, C{"one", "two"}, config.Get(ctx))
}
40 changes: 9 additions & 31 deletions go-runtime/ftl/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,21 @@ package ftl
import (
"context"
"fmt"
"os"
"strings"
"sync"

cf "github.com/TBD54566975/ftl/common/configuration"
"github.com/TBD54566975/ftl/internal/log"
"github.com/TBD54566975/ftl/common/configuration"
)

var globalSecretsManagerOnce sync.Once

// globalSecretsManager returns a global secrets manager instance.
func globalSecretsManager() (manager *cf.Manager[cf.Secrets]) {
globalSecretsManagerOnce.Do(func() {
var configs []string
if envar, ok := os.LookupEnv("FTL_CONFIG"); ok {
configs = strings.Split(envar, ",")
}
config := cf.DefaultSecretsMixin{}
var err error
ctx := log.ContextWithNewDefaultLogger(context.Background())
manager, err = config.NewSecretsManager(ctx, cf.ProjectConfigResolver[cf.Secrets]{Config: configs})
if err != nil {
panic("failed to create global secrets manager: " + err.Error())
}
})
return manager
}
// SecretType is a type that can be used as a secret value.
type SecretType interface{ any }

// Secret declares a typed secret for the current module.
func Secret[T any](name string) SecretValue[T] {
func Secret[T SecretType](name string) SecretValue[T] {
module := callerModule()
return SecretValue[T]{module, name}
}

// SecretValue is a typed secret for the current module.
type SecretValue[T any] struct {
type SecretValue[T SecretType] struct {
module string
name string
}
Expand All @@ -51,11 +30,10 @@ func (s SecretValue[T]) GoString() string {
}

// Get returns the value of the secret from FTL.
func (s SecretValue[T]) Get() (out T) {
sm := globalSecretsManager()
ctx := log.ContextWithNewDefaultLogger(context.Background())
if err := sm.Get(ctx, cf.NewRef(s.module, s.name), &out); err != nil {
panic(fmt.Errorf("failed to get secrets %s.%s: %w", s.module, s.name, err))
func (s SecretValue[T]) Get(ctx context.Context) (out T) {
sm := configuration.SecretsFromContext(ctx)
if err := sm.Get(ctx, configuration.NewRef(s.module, s.name), &out); err != nil {
panic(fmt.Errorf("failed to get %s: %w", s, err))
}
return
}
12 changes: 10 additions & 2 deletions go-runtime/ftl/secrets_test.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
package ftl

import (
"context"
"testing"

"github.com/alecthomas/assert/v2"

"github.com/TBD54566975/ftl/common/configuration"
"github.com/TBD54566975/ftl/internal/log"
)

func TestSecret(t *testing.T) {
t.Setenv("FTL_CONFIG", "testdata/ftl-project.toml")
ctx := log.ContextWithNewDefaultLogger(context.Background())
sr := configuration.ProjectConfigResolver[configuration.Secrets]{Config: []string{"testdata/ftl-project.toml"}}
sm, err := configuration.NewSecretsManager(ctx, sr)
assert.NoError(t, err)
ctx = configuration.ContextWithSecrets(ctx, sm)
type C struct {
One string
Two string
}
config := Secret[C]("secret")
assert.Equal(t, C{"one", "two"}, config.Get())
assert.Equal(t, C{"one", "two"}, config.Get(ctx))
}

0 comments on commit f8e6d30

Please sign in to comment.