diff --git a/backend/controller/controller.go b/backend/controller/controller.go index 859fb3a91b..f1ef249a4d 100644 --- a/backend/controller/controller.go +++ b/backend/controller/controller.go @@ -645,9 +645,17 @@ func (s *Service) GetModuleContext(ctx context.Context, req *connect.Request[ftl // get module schema schemas, err := s.dal.GetActiveDeploymentSchemas(ctx) if err != nil { - return nil, err + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("could not get active schemas: %w", err)) + } + schema, ok := slices.Find(schemas, func(s *schema.Module) bool { return s.Name == req.Msg.Module }) + if !ok { + return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("module %q not found", req.Msg.Module)) + } + response, err := moduleContextToProto(ctx, schema) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("could not get module context: %w", err)) } - return moduleContextToProto(ctx, req.Msg.Module, schemas) + return connect.NewResponse(response), nil } func (s *Service) Call(ctx context.Context, req *connect.Request[ftlv1.CallRequest]) (*connect.Response[ftlv1.CallResponse], error) { diff --git a/backend/controller/module_context.go b/backend/controller/module_context.go index 50ae41824c..306fe1f14f 100644 --- a/backend/controller/module_context.go +++ b/backend/controller/module_context.go @@ -6,46 +6,34 @@ import ( "os" "strings" - "connectrpc.com/connect" - ftlv1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1" "github.com/TBD54566975/ftl/backend/schema" cf "github.com/TBD54566975/ftl/common/configuration" - "github.com/TBD54566975/ftl/internal/slices" ) -func moduleContextToProto(ctx context.Context, name string, schemas []*schema.Module) (*connect.Response[ftlv1.ModuleContextResponse], error) { - schemas = slices.Filter(schemas, func(s *schema.Module) bool { - return s.Name == name - }) - if len(schemas) == 0 { - return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("no schema found for module %q", name)) - } else if len(schemas) > 1 { - return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("multiple schemas found for module %q", name)) - } - +func moduleContextToProto(ctx context.Context, module *schema.Module) (*ftlv1.ModuleContextResponse, error) { // configs configManager := cf.ConfigFromContext(ctx) - configMap, err := bytesMapFromConfigManager(ctx, configManager, name) + configMap, err := bytesMapFromConfigManager(ctx, configManager, module.Name) if err != nil { return nil, err } // secrets secretsManager := cf.SecretsFromContext(ctx) - secretsMap, err := bytesMapFromConfigManager(ctx, secretsManager, name) + secretsMap, err := bytesMapFromConfigManager(ctx, secretsManager, module.Name) if err != nil { return nil, err } // DSNs dsnProtos := []*ftlv1.ModuleContextResponse_DSN{} - for _, decl := range schemas[0].Decls { + for _, decl := range module.Decls { dbDecl, ok := decl.(*schema.Database) if !ok { continue } - key := fmt.Sprintf("FTL_POSTGRES_DSN_%s_%s", strings.ToUpper(name), strings.ToUpper(dbDecl.Name)) + key := fmt.Sprintf("FTL_POSTGRES_DSN_%s_%s", strings.ToUpper(module.Name), strings.ToUpper(dbDecl.Name)) dsn, ok := os.LookupEnv(key) if !ok { return nil, fmt.Errorf("missing environment variable %q", key) @@ -57,11 +45,11 @@ func moduleContextToProto(ctx context.Context, name string, schemas []*schema.Mo }) } - return connect.NewResponse(&ftlv1.ModuleContextResponse{ + return &ftlv1.ModuleContextResponse{ Configs: configMap, Secrets: secretsMap, Databases: dsnProtos, - }), nil + }, nil } func bytesMapFromConfigManager[R cf.Role](ctx context.Context, manager *cf.Manager[R], moduleName string) (map[string][]byte, error) { diff --git a/backend/controller/module_context_test.go b/backend/controller/module_context_test.go index a53a092d6a..37e79008ca 100644 --- a/backend/controller/module_context_test.go +++ b/backend/controller/module_context_test.go @@ -5,11 +5,12 @@ import ( "fmt" "testing" + "github.com/alecthomas/assert/v2" + "github.com/alecthomas/types/optional" + "github.com/TBD54566975/ftl/backend/schema" cf "github.com/TBD54566975/ftl/common/configuration" "github.com/TBD54566975/ftl/internal/log" - "github.com/alecthomas/assert/v2" - "github.com/alecthomas/types/optional" ) func TestModuleContextProto(t *testing.T) { @@ -41,15 +42,11 @@ func TestModuleContextProto(t *testing.T) { assert.NoError(t, cm.Set(ctx, cf.Ref{Module: optional.None[string](), Name: key}, globalStrValue)) } - response, err := moduleContextToProto(ctx, moduleName, []*schema.Module{ - { - Name: moduleName, - }, - }) + response, err := moduleContextToProto(ctx, &schema.Module{Name: moduleName}) assert.NoError(t, err) for i := range 50 { key := fmt.Sprintf("key%d", i) - assert.Equal(t, "\"HelloWorld\"", string(response.Msg.Configs[key]), "module configs should beat global configs") + assert.Equal(t, "\"HelloWorld\"", string(response.Configs[key]), "module configs should beat global configs") } } diff --git a/internal/slices/slices.go b/internal/slices/slices.go index 75f75ae444..89156f2f62 100644 --- a/internal/slices/slices.go +++ b/internal/slices/slices.go @@ -68,3 +68,13 @@ func FlatMap[T, U any](slice []T, fn func(T) []U) []U { } return result } + +func Find[T any](slice []T, fn func(T) bool) (T, bool) { + for _, v := range slice { + if fn(v) { + return v, true + } + } + var zero T + return zero, false +}