diff --git a/backend/cmd/configure/bla5/generator.go b/backend/cmd/configure/bla5/generator.go new file mode 100644 index 0000000000..d58d474609 --- /dev/null +++ b/backend/cmd/configure/bla5/generator.go @@ -0,0 +1 @@ +package bla5 diff --git a/backend/cmd/configure/bla5/update_config8.go b/backend/cmd/configure/bla5/update_config8.go index c2b033dccc..e283d5be3f 100644 --- a/backend/cmd/configure/bla5/update_config8.go +++ b/backend/cmd/configure/bla5/update_config8.go @@ -3,7 +3,6 @@ package bla5 import ( "log/slog" "os" - "reflect" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -16,6 +15,8 @@ var Logger = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ type Configure func() (value any, err error) +// Configurer should be implemented by each field of the configuration struct. +// It is used to configure the value of the field. type Configurer interface { // Configure is called to configure the value. // It must return the same type as itself. Otherwise [Update] will panic because it is not able to set the value. @@ -24,51 +25,51 @@ type Configurer interface { func Update(v *viper.Viper, config any) func(cmd *cobra.Command, args []string) { return func(cmd *cobra.Command, args []string) { - value := reflect.ValueOf(config) - structConfigures := structToConfigureMap(Logger, v, value) - for key, configure := range structConfigures { - result, err := configure() - if err != nil { - Logger.Error("error configuring field", slog.String("field", key), slog.Any("cause", err)) - return - } - value.Elem().FieldByName(key).Set(reflect.ValueOf(result)) - } + // value := reflect.ValueOf(config) + // structConfigures := structToConfigureMap(Logger, v, value) + // for key, configure := range structConfigures { + // result, err := configure() + // if err != nil { + // Logger.Error("error configuring field", slog.String("field", key), slog.Any("cause", err)) + // return + // } + // value.Elem().FieldByName(key).Set(reflect.ValueOf(result)) + // } - err := v.WriteConfig() - if err != nil { - Logger.Error("error writing config", slog.Any("cause", err)) - os.Exit(1) - } + // err := v.WriteConfig() + // if err != nil { + // Logger.Error("error writing config", slog.Any("cause", err)) + // os.Exit(1) + // } } } -func objectToFlow(l *slog.Logger, value reflect.Value) { - if value.Kind() == reflect.Pointer { - if value.IsNil() { - value = reflect.New(value.Type().Elem()) - } - value = value.Elem() - } +// func objectToFlow(l *slog.Logger, value reflect.Value) { +// if value.Kind() == reflect.Pointer { +// if value.IsNil() { +// value = reflect.New(value.Type().Elem()) +// } +// value = value.Elem() +// } - typeOfValue := value.Type() - for i := 0; i < value.NumField(); i++ { - fieldValue := value.Field(i) - fieldType := typeOfValue.Field(i) +// typeOfValue := value.Type() +// for i := 0; i < value.NumField(); i++ { +// fieldValue := value.Field(i) +// fieldType := typeOfValue.Field(i) - l.Info("Processing field", slog.String("field", fieldType.Name)) - } -} +// l.Info("Processing field", slog.String("field", fieldType.Name)) +// } +// } -type field struct { - set func(value reflect.Value) error -} +// type field struct { +// set func(value reflect.Value) error +// } -type structField struct { - name string +// type structField struct { +// name string - fields []field -} +// fields []field +// } -type primitiveField struct { -} +// type primitiveField struct { +// } diff --git a/backend/domain/factory/instance.go b/backend/domain/factory/instance.go index c461f3e4c9..dd07a8df37 100644 --- a/backend/domain/factory/instance.go +++ b/backend/domain/factory/instance.go @@ -4,18 +4,50 @@ import ( "context" "github.com/zitadel/zitadel/backend/repository" - "github.com/zitadel/zitadel/backend/storage/database" - "github.com/zitadel/zitadel/backend/telemetry/logging" - "github.com/zitadel/zitadel/backend/telemetry/tracing" ) -type InstanceBuilder struct { - tracer *tracing.Tracer - logger *logging.Logger +// type Middleware[O any, H Handler[O]] interface { +// New() H +// NewWithNext(next Handler[O]) H +// } +type Middleware[Req, Res any] interface { + New() Handler[Req, Res] + NewWithNext(next Handler[Req, Res]) Handler[Req, Res] } -func (f *InstanceBuilder) BuildSetUpInstance(tx database.Transaction) func(ctx context.Context, instance *repository.Instance) error { - return func(ctx context.Context, instance *repository.Instance) error { - return tx.Exec(ctx, "INSERT INTO instances (id, name) VALUES ($1, $2)", instance.ID, instance.Name) - } +type Handler[Req, Res any] interface { + Handle(ctx context.Context, request Req) (Res, error) + SetNext(next Handler[Req, Res]) + + Name() string +} + +// type InstanceBuilder struct { +// tracer *traced.Instance +// logger *logged.Instance +// cache *cache.Instance +// events *event.Instance +// db *sql.Instance +// } + +type InstanceSetUpBuilder struct { + tracer Middleware[*repository.Instance, *repository.Instance] + logger Middleware[*repository.Instance, *repository.Instance] + cache Middleware[*repository.Instance, *repository.Instance] + events Middleware[*repository.Instance, *repository.Instance] + db Middleware[*repository.Instance, *repository.Instance] +} + +func (i *InstanceSetUpBuilder) Build() { + instance := i.tracer.NewWithNext( + i.logger.NewWithNext( + i.db.NewWithNext( + i.events.NewWithNext( + i.cache.New(), + ), + ), + ), + ) + _ = instance + // instance. } diff --git a/backend/repository/telemetry/traced/global.go b/backend/repository/telemetry/traced/global.go new file mode 100644 index 0000000000..3fc12b678a --- /dev/null +++ b/backend/repository/telemetry/traced/global.go @@ -0,0 +1,55 @@ +package traced + +import ( + "context" + + "github.com/zitadel/zitadel/backend/domain/factory" + "github.com/zitadel/zitadel/backend/telemetry/tracing" +) + +type Tracer[Req, Res any] struct { + tracing.Tracer + next factory.Handler[Req, Res] +} + +func (*Tracer[Req, Res]) Name() string { + return "Tracer" +} + +// Handle implements [factory.Handler]. +func (t *Tracer[Req, Res]) Handle(ctx context.Context, request Req) (res Res, err error) { + if t.next == nil { + return res, nil + } + ctx, span := t.Tracer.Start( + ctx, + t.next.Name(), + ) + defer func() { + if err != nil { + span.RecordError(err) + } + span.End() + }() + return t.next.Handle(ctx, request) +} + +// SetNext implements [factory.Handler]. +func (t *Tracer[Req, Res]) SetNext(next factory.Handler[Req, Res]) { + t.next = next +} + +// New implements [factory.Middleware]. +func (t *Tracer[Req, Res]) New() factory.Handler[Req, Res] { + return t.NewWithNext(nil) +} + +// NewWithNext implements [factory.Middleware]. +func (t *Tracer[Req, Res]) NewWithNext(next factory.Handler[Req, Res]) factory.Handler[Req, Res] { + return &Tracer[Req, Res]{Tracer: t.Tracer, next: next} +} + +var ( + _ factory.Middleware[any, any] = (*Tracer[any, any])(nil) + _ factory.Handler[any, any] = (*Tracer[any, any])(nil) +) diff --git a/backend/storage/database/config.go b/backend/storage/database/config.go index cb2b28ab94..1604cda650 100644 --- a/backend/storage/database/config.go +++ b/backend/storage/database/config.go @@ -2,11 +2,9 @@ package database import ( "context" - - "github.com/zitadel/zitadel/backend/cmd/configure/bla4" ) type Connector interface { Connect(ctx context.Context) (Pool, error) - bla4.Configurer + // bla4.Configurer } diff --git a/backend/storage/database/dialect/config.go b/backend/storage/database/dialect/config.go index 4a7ac35c77..593b06ec84 100644 --- a/backend/storage/database/dialect/config.go +++ b/backend/storage/database/dialect/config.go @@ -5,11 +5,9 @@ import ( "errors" "reflect" - "github.com/manifoldco/promptui" "github.com/mitchellh/mapstructure" "github.com/spf13/viper" - "github.com/zitadel/zitadel/backend/cmd/configure/bla4" "github.com/zitadel/zitadel/backend/storage/database" "github.com/zitadel/zitadel/backend/storage/database/dialect/postgres" ) @@ -43,47 +41,47 @@ type Config struct { } // Configure implements [configure.Configurer]. -func (c *Config) Configure() (any, error) { - possibilities := make([]string, len(hooks)) - var cursor int - for i, hook := range hooks { - if _, ok := c.Dialects[hook.Name]; ok { - cursor = i - } - possibilities[i] = hook.Name - } +// func (c *Config) Configure() (any, error) { +// possibilities := make([]string, len(hooks)) +// var cursor int +// for i, hook := range hooks { +// if _, ok := c.Dialects[hook.Name]; ok { +// cursor = i +// } +// possibilities[i] = hook.Name +// } - prompt := promptui.Select{ - Label: "Select a dialect", - Items: possibilities, - CursorPos: cursor, - } - i, _, err := prompt.Run() - if err != nil { - return nil, err - } +// prompt := promptui.Select{ +// Label: "Select a dialect", +// Items: possibilities, +// CursorPos: cursor, +// } +// i, _, err := prompt.Run() +// if err != nil { +// return nil, err +// } - var config bla4.Configurer +// var config bla4.Configurer - if dialect, ok := c.Dialects[hooks[i].Name]; ok { - config, err = hooks[i].Decode(dialect) - if err != nil { - return nil, err - } - } else { - clear(c.Dialects) - config = hooks[i].Constructor() - } - if c.Dialects == nil { - c.Dialects = make(map[string]any) - } - c.Dialects[hooks[i].Name], err = config.Configure() - if err != nil { - return nil, err - } +// if dialect, ok := c.Dialects[hooks[i].Name]; ok { +// config, err = hooks[i].Decode(dialect) +// if err != nil { +// return nil, err +// } +// } else { +// clear(c.Dialects) +// config = hooks[i].Constructor() +// } +// if c.Dialects == nil { +// c.Dialects = make(map[string]any) +// } +// c.Dialects[hooks[i].Name], err = config.Configure() +// if err != nil { +// return nil, err +// } - return c, nil -} +// return c, nil +// } func (c Config) Connect(ctx context.Context) (database.Pool, error) { if len(c.Dialects) != 1 {