From 5ae29c077ff1bcb36456114b8de1d91312a7e0e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Wed, 15 Nov 2023 17:15:47 +0200 Subject: [PATCH] bring triggers back --- internal/api/oidc/introspect.go | 4 +++ internal/eventstore/handler/v2/handler.go | 5 ++++ ...trospection_client.go => introspection.go} | 11 ++++++++ ...n_client_test.go => introspection_test.go} | 0 internal/query/query.go | 26 +++++++++++++++++++ internal/query/user.go | 23 ++-------------- internal/query/userinfo.go | 14 ++++++++++ 7 files changed, 62 insertions(+), 21 deletions(-) rename internal/query/{introspection_client.go => introspection.go} (75%) rename internal/query/{introspection_client_test.go => introspection_test.go} (100%) diff --git a/internal/api/oidc/introspect.go b/internal/api/oidc/introspect.go index 589198a4481..d5716063b6c 100644 --- a/internal/api/oidc/introspect.go +++ b/internal/api/oidc/introspect.go @@ -23,6 +23,10 @@ func (s *Server) Introspect(ctx context.Context, r *op.Request[op.IntrospectionR if s.features.LegacyIntrospection { return s.LegacyServer.Introspect(ctx, r) } + if s.features.TriggerIntrospectionProjections { + // Execute all triggers in one concurrent sweep. + ctx = query.TriggerIntrospectionProjections(ctx) + } ctx, cancel := context.WithCancel(ctx) defer cancel() diff --git a/internal/eventstore/handler/v2/handler.go b/internal/eventstore/handler/v2/handler.go index c03d695dd89..cfa21b05abc 100644 --- a/internal/eventstore/handler/v2/handler.go +++ b/internal/eventstore/handler/v2/handler.go @@ -456,3 +456,8 @@ func (h *Handler) eventQuery(currentState *state) *eventstore.SearchQueryBuilder return builder } + +// ProjectionName returns the name of the unlying projection. +func (h *Handler) ProjectionName() string { + return h.projection.Name() +} diff --git a/internal/query/introspection_client.go b/internal/query/introspection.go similarity index 75% rename from internal/query/introspection_client.go rename to internal/query/introspection.go index bfccf30b516..da60db07ca1 100644 --- a/internal/query/introspection_client.go +++ b/internal/query/introspection.go @@ -8,9 +8,20 @@ import ( "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/crypto" "github.com/zitadel/zitadel/internal/database" + "github.com/zitadel/zitadel/internal/query/projection" "github.com/zitadel/zitadel/internal/telemetry/tracing" ) +var introspectionTriggerHandlers = append(oidcUserInfoTriggerHandlers, + projection.AppProjection, + projection.OIDCSettingsProjection, + projection.AuthNKeyProjection, +) + +func TriggerIntrospectionProjections(ctx context.Context) context.Context { + return triggerBatch(ctx, introspectionTriggerHandlers...) +} + type IntrospectionClient struct { ClientID string ClientSecret *crypto.CryptoValue diff --git a/internal/query/introspection_client_test.go b/internal/query/introspection_test.go similarity index 100% rename from internal/query/introspection_client_test.go rename to internal/query/introspection_test.go diff --git a/internal/query/query.go b/internal/query/query.go index 58f4b3009b9..e923151aa60 100644 --- a/internal/query/query.go +++ b/internal/query/query.go @@ -11,6 +11,8 @@ import ( "github.com/rakyll/statik/fs" "golang.org/x/text/language" + "github.com/zitadel/logging" + "github.com/zitadel/zitadel/internal/api/authz" internal_authz "github.com/zitadel/zitadel/internal/api/authz" sd "github.com/zitadel/zitadel/internal/config/systemdefaults" @@ -18,6 +20,7 @@ import ( "github.com/zitadel/zitadel/internal/database" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/eventstore" + "github.com/zitadel/zitadel/internal/eventstore/handler/v2" "github.com/zitadel/zitadel/internal/query/projection" "github.com/zitadel/zitadel/internal/repository/action" "github.com/zitadel/zitadel/internal/repository/authrequest" @@ -32,6 +35,7 @@ import ( "github.com/zitadel/zitadel/internal/repository/session" usr_repo "github.com/zitadel/zitadel/internal/repository/user" "github.com/zitadel/zitadel/internal/repository/usergrant" + "github.com/zitadel/zitadel/internal/telemetry/tracing" ) type Queries struct { @@ -146,3 +150,25 @@ func init() { &authRequestByIDQuery, ) } + +// triggerBatch calls Trigger on every handler in a seperate Go routine. +// The returned context is the context returned by the Trigger that finishes last. +func triggerBatch(ctx context.Context, handlers ...*handler.Handler) context.Context { + ctxChan := make(chan context.Context) + + for _, h := range handlers { + go func(ctx context.Context, h *handler.Handler, ctxChan chan<- context.Context) { + name := h.ProjectionName() + _, traceSpan := tracing.NewNamedSpan(ctx, fmt.Sprintf("Trigger%s", name)) + newCtx, err := h.Trigger(ctx, handler.WithAwaitRunning()) + logging.OnError(err).WithField("projection", name).Debug("trigger failed") + traceSpan.EndWithError(err) + ctxChan <- newCtx + }(ctx, h, ctxChan) + } + + for i := 0; i < len(handlers); i++ { + ctx = <-ctxChan + } + return ctx +} diff --git a/internal/query/user.go b/internal/query/user.go index 11dd51f92aa..6bc556a11d1 100644 --- a/internal/query/user.go +++ b/internal/query/user.go @@ -5,11 +5,9 @@ import ( "database/sql" errs "errors" "strings" - "sync" "time" sq "github.com/Masterminds/squirrel" - "github.com/zitadel/logging" "golang.org/x/text/language" "github.com/zitadel/zitadel/internal/api/authz" @@ -17,7 +15,6 @@ import ( "github.com/zitadel/zitadel/internal/database" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/errors" - "github.com/zitadel/zitadel/internal/eventstore/handler/v2" "github.com/zitadel/zitadel/internal/query/projection" "github.com/zitadel/zitadel/internal/telemetry/tracing" ) @@ -709,24 +706,8 @@ func NewUserLoginNameExistsQuery(value string, comparison TextComparison) (Searc ) } -func triggerUserProjections(ctx context.Context) { - wg := sync.WaitGroup{} - wg.Add(2) - func() { - _, traceSpan := tracing.NewNamedSpan(ctx, "TriggerUserProjection") - _, err := projection.UserProjection.Trigger(ctx, handler.WithAwaitRunning()) - logging.OnError(err).Debug("trigger failed") - traceSpan.EndWithError(err) - wg.Done() - }() - func() { - _, traceSpan := tracing.NewNamedSpan(ctx, "TriggerLoginNameProjection") - _, err := projection.LoginNameProjection.Trigger(ctx, handler.WithAwaitRunning()) - traceSpan.EndWithError(err) - logging.OnError(err).Debug("trigger failed") - wg.Done() - }() - wg.Wait() +func triggerUserProjections(ctx context.Context) context.Context { + return triggerBatch(ctx, projection.UserProjection, projection.LoginNameProjection) } func prepareLoginNamesQuery() (string, []interface{}, error) { diff --git a/internal/query/userinfo.go b/internal/query/userinfo.go index 2cfbb6cdecf..a3d7a6a7332 100644 --- a/internal/query/userinfo.go +++ b/internal/query/userinfo.go @@ -9,9 +9,23 @@ import ( "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/database" "github.com/zitadel/zitadel/internal/errors" + "github.com/zitadel/zitadel/internal/eventstore/handler/v2" + "github.com/zitadel/zitadel/internal/query/projection" "github.com/zitadel/zitadel/internal/telemetry/tracing" ) +var oidcUserInfoTriggerHandlers = []*handler.Handler{ + projection.UserProjection, + projection.UserMetadataProjection, + projection.UserGrantProjection, + projection.OrgProjection, + projection.ProjectProjection, +} + +func TriggerOIDCUserInfoProjections(ctx context.Context) context.Context { + return triggerBatch(ctx, oidcUserInfoTriggerHandlers...) +} + //go:embed embed/userinfo_by_id.sql var oidcUserInfoQuery string