diff --git a/backend/controller/controller.go b/backend/controller/controller.go index 859fb3a91b..ebfde92a9e 100644 --- a/backend/controller/controller.go +++ b/backend/controller/controller.go @@ -647,7 +647,11 @@ func (s *Service) GetModuleContext(ctx context.Context, req *connect.Request[ftl if err != nil { return nil, err } - return moduleContextToProto(ctx, req.Msg.Module, schemas) + 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)) + } + return moduleContextToProto(ctx, schema) } 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..5108789a14 100644 --- a/backend/controller/module_context.go +++ b/backend/controller/module_context.go @@ -11,41 +11,31 @@ import ( 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) (*connect.Response[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) diff --git a/backend/controller/module_context_test.go b/backend/controller/module_context_test.go index a53a092d6a..24b1394cbe 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,11 +42,7 @@ 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 { 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 +}