mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-16 12:58:00 +00:00
1d84635836
# Which Problems Are Solved To improve performance a new table and method is implemented on eventstore. The goal of this table is to index searchable fields on command side to use it on command and query side. The table allows to store one primitive value (numeric, text) per row. The eventstore framework is extended by the `Search`-method which allows to search for objects. The `Command`-interface is extended by the `SearchOperations()`-method which does manipulate the the `search`-table. # How the Problems Are Solved This PR adds the capability of improving performance for command and query side by using the `Search`-method of the eventstore instead of using one of the `Filter`-methods. # Open Tasks - [x] Add feature flag - [x] Unit tests - [ ] ~~Benchmarks if needed~~ - [x] Ensure no behavior change - [x] Add setup step to fill table with current data - [x] Add projection which ensures data added between setup and start of the new version are also added to the table # Additional Changes The `Search`-method is currently used by `ProjectGrant`-command side. # Additional Context - Closes https://github.com/zitadel/zitadel/issues/8094
292 lines
15 KiB
Go
292 lines
15 KiB
Go
package projection
|
|
|
|
import (
|
|
"context"
|
|
|
|
internal_authz "github.com/zitadel/zitadel/internal/api/authz"
|
|
"github.com/zitadel/zitadel/internal/crypto"
|
|
"github.com/zitadel/zitadel/internal/database"
|
|
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
|
|
"github.com/zitadel/zitadel/internal/migration"
|
|
)
|
|
|
|
const (
|
|
CurrentStateTable = "projections.current_states"
|
|
LocksTable = "projections.locks"
|
|
FailedEventsTable = "projections.failed_events2"
|
|
)
|
|
|
|
var (
|
|
projectionConfig handler.Config
|
|
OrgProjection *handler.Handler
|
|
OrgMetadataProjection *handler.Handler
|
|
ActionProjection *handler.Handler
|
|
FlowProjection *handler.Handler
|
|
ProjectProjection *handler.Handler
|
|
PasswordComplexityProjection *handler.Handler
|
|
PasswordAgeProjection *handler.Handler
|
|
LockoutPolicyProjection *handler.Handler
|
|
PrivacyPolicyProjection *handler.Handler
|
|
DomainPolicyProjection *handler.Handler
|
|
LabelPolicyProjection *handler.Handler
|
|
ProjectGrantProjection *handler.Handler
|
|
ProjectRoleProjection *handler.Handler
|
|
OrgDomainProjection *handler.Handler
|
|
LoginPolicyProjection *handler.Handler
|
|
IDPProjection *handler.Handler
|
|
AppProjection *handler.Handler
|
|
IDPUserLinkProjection *handler.Handler
|
|
IDPLoginPolicyLinkProjection *handler.Handler
|
|
IDPTemplateProjection *handler.Handler
|
|
MailTemplateProjection *handler.Handler
|
|
MessageTextProjection *handler.Handler
|
|
CustomTextProjection *handler.Handler
|
|
UserProjection *handler.Handler
|
|
LoginNameProjection *handler.Handler
|
|
OrgMemberProjection *handler.Handler
|
|
InstanceDomainProjection *handler.Handler
|
|
InstanceMemberProjection *handler.Handler
|
|
ProjectMemberProjection *handler.Handler
|
|
ProjectGrantMemberProjection *handler.Handler
|
|
AuthNKeyProjection *handler.Handler
|
|
PersonalAccessTokenProjection *handler.Handler
|
|
UserGrantProjection *handler.Handler
|
|
UserMetadataProjection *handler.Handler
|
|
UserAuthMethodProjection *handler.Handler
|
|
InstanceProjection *handler.Handler
|
|
SecretGeneratorProjection *handler.Handler
|
|
SMTPConfigProjection *handler.Handler
|
|
SMSConfigProjection *handler.Handler
|
|
OIDCSettingsProjection *handler.Handler
|
|
DebugNotificationProviderProjection *handler.Handler
|
|
KeyProjection *handler.Handler
|
|
SecurityPolicyProjection *handler.Handler
|
|
NotificationPolicyProjection *handler.Handler
|
|
NotificationsProjection interface{}
|
|
NotificationsQuotaProjection interface{}
|
|
TelemetryPusherProjection interface{}
|
|
DeviceAuthProjection *handler.Handler
|
|
SessionProjection *handler.Handler
|
|
AuthRequestProjection *handler.Handler
|
|
MilestoneProjection *handler.Handler
|
|
QuotaProjection *quotaProjection
|
|
LimitsProjection *handler.Handler
|
|
RestrictionsProjection *handler.Handler
|
|
SystemFeatureProjection *handler.Handler
|
|
InstanceFeatureProjection *handler.Handler
|
|
TargetProjection *handler.Handler
|
|
ExecutionProjection *handler.Handler
|
|
UserSchemaProjection *handler.Handler
|
|
|
|
ProjectGrantFields *handler.FieldHandler
|
|
)
|
|
|
|
type projection interface {
|
|
Start(ctx context.Context)
|
|
Init(ctx context.Context) error
|
|
Trigger(ctx context.Context, opts ...handler.TriggerOpt) (_ context.Context, err error)
|
|
migration.Migration
|
|
}
|
|
|
|
var (
|
|
projections []projection
|
|
)
|
|
|
|
func Create(ctx context.Context, sqlClient *database.DB, es handler.EventStore, config Config, keyEncryptionAlgorithm crypto.EncryptionAlgorithm, certEncryptionAlgorithm crypto.EncryptionAlgorithm, systemUsers map[string]*internal_authz.SystemAPIUser) error {
|
|
projectionConfig = handler.Config{
|
|
Client: sqlClient,
|
|
Eventstore: es,
|
|
BulkLimit: uint16(config.BulkLimit),
|
|
RequeueEvery: config.RequeueEvery,
|
|
HandleActiveInstances: config.HandleActiveInstances,
|
|
MaxFailureCount: config.MaxFailureCount,
|
|
RetryFailedAfter: config.RetryFailedAfter,
|
|
TransactionDuration: config.TransactionDuration,
|
|
}
|
|
|
|
OrgProjection = newOrgProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["orgs"]))
|
|
OrgMetadataProjection = newOrgMetadataProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["org_metadata"]))
|
|
ActionProjection = newActionProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["actions"]))
|
|
FlowProjection = newFlowProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["flows"]))
|
|
ProjectProjection = newProjectProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["projects"]))
|
|
PasswordComplexityProjection = newPasswordComplexityProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["password_complexities"]))
|
|
PasswordAgeProjection = newPasswordAgeProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["password_age_policy"]))
|
|
LockoutPolicyProjection = newLockoutPolicyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["lockout_policy"]))
|
|
PrivacyPolicyProjection = newPrivacyPolicyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["privacy_policy"]))
|
|
DomainPolicyProjection = newDomainPolicyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["org_iam_policy"]))
|
|
LabelPolicyProjection = newLabelPolicyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["label_policy"]))
|
|
ProjectGrantProjection = newProjectGrantProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["project_grants"]))
|
|
ProjectRoleProjection = newProjectRoleProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["project_roles"]))
|
|
OrgDomainProjection = newOrgDomainProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["org_domains"]))
|
|
LoginPolicyProjection = newLoginPolicyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["login_policies"]))
|
|
IDPProjection = newIDPProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["idps"]))
|
|
AppProjection = newAppProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["apps"]))
|
|
IDPUserLinkProjection = newIDPUserLinkProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["idp_user_links"]))
|
|
IDPLoginPolicyLinkProjection = newIDPLoginPolicyLinkProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["idp_login_policy_links"]))
|
|
IDPTemplateProjection = newIDPTemplateProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["idp_templates"]))
|
|
MailTemplateProjection = newMailTemplateProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["mail_templates"]))
|
|
MessageTextProjection = newMessageTextProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["message_texts"]))
|
|
CustomTextProjection = newCustomTextProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["custom_texts"]))
|
|
UserProjection = newUserProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["users"]))
|
|
LoginNameProjection = newLoginNameProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["login_names"]))
|
|
OrgMemberProjection = newOrgMemberProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["org_members"]))
|
|
InstanceDomainProjection = newInstanceDomainProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["instance_domains"]))
|
|
InstanceMemberProjection = newInstanceMemberProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["iam_members"]))
|
|
ProjectMemberProjection = newProjectMemberProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["project_members"]))
|
|
ProjectGrantMemberProjection = newProjectGrantMemberProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["project_grant_members"]))
|
|
AuthNKeyProjection = newAuthNKeyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["authn_keys"]))
|
|
PersonalAccessTokenProjection = newPersonalAccessTokenProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["personal_access_tokens"]))
|
|
UserGrantProjection = newUserGrantProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["user_grants"]))
|
|
UserMetadataProjection = newUserMetadataProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["user_metadata"]))
|
|
UserAuthMethodProjection = newUserAuthMethodProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["user_auth_method"]))
|
|
InstanceProjection = newInstanceProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["instances"]))
|
|
SecretGeneratorProjection = newSecretGeneratorProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["secret_generators"]))
|
|
SMTPConfigProjection = newSMTPConfigProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["smtp_configs"]))
|
|
SMSConfigProjection = newSMSConfigProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["sms_config"]))
|
|
OIDCSettingsProjection = newOIDCSettingsProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["oidc_settings"]))
|
|
DebugNotificationProviderProjection = newDebugNotificationProviderProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["debug_notification_provider"]))
|
|
KeyProjection = newKeyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["keys"]), keyEncryptionAlgorithm, certEncryptionAlgorithm)
|
|
SecurityPolicyProjection = newSecurityPolicyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["security_policies"]))
|
|
NotificationPolicyProjection = newNotificationPolicyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["notification_policies"]))
|
|
DeviceAuthProjection = newDeviceAuthProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["device_auth"]))
|
|
SessionProjection = newSessionProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["sessions"]))
|
|
AuthRequestProjection = newAuthRequestProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["auth_requests"]))
|
|
MilestoneProjection = newMilestoneProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["milestones"]), systemUsers)
|
|
QuotaProjection = newQuotaProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["quotas"]))
|
|
LimitsProjection = newLimitsProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["limits"]))
|
|
RestrictionsProjection = newRestrictionsProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["restrictions"]))
|
|
SystemFeatureProjection = newSystemFeatureProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["system_features"]))
|
|
InstanceFeatureProjection = newInstanceFeatureProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["instance_features"]))
|
|
TargetProjection = newTargetProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["targets"]))
|
|
ExecutionProjection = newExecutionProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["executions"]))
|
|
UserSchemaProjection = newUserSchemaProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["user_schemas"]))
|
|
|
|
ProjectGrantFields = newFillProjectGrantFields(applyCustomConfig(projectionConfig, config.Customizations["project_grant_fields"]))
|
|
|
|
newProjectionsList()
|
|
return nil
|
|
}
|
|
|
|
func Projections() []projection {
|
|
return projections
|
|
}
|
|
|
|
func Init(ctx context.Context) error {
|
|
for _, p := range projections {
|
|
if err := p.Init(ctx); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func Start(ctx context.Context) {
|
|
for _, projection := range projections {
|
|
projection.Start(ctx)
|
|
}
|
|
}
|
|
|
|
func ProjectInstance(ctx context.Context) error {
|
|
for _, projection := range projections {
|
|
_, err := projection.Trigger(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func ApplyCustomConfig(customConfig CustomConfig) handler.Config {
|
|
return applyCustomConfig(projectionConfig, customConfig)
|
|
}
|
|
|
|
func applyCustomConfig(config handler.Config, customConfig CustomConfig) handler.Config {
|
|
if customConfig.BulkLimit != nil {
|
|
config.BulkLimit = *customConfig.BulkLimit
|
|
}
|
|
if customConfig.MaxFailureCount != nil {
|
|
config.MaxFailureCount = *customConfig.MaxFailureCount
|
|
}
|
|
if customConfig.RequeueEvery != nil {
|
|
config.RequeueEvery = *customConfig.RequeueEvery
|
|
}
|
|
if customConfig.RetryFailedAfter != nil {
|
|
config.RetryFailedAfter = *customConfig.RetryFailedAfter
|
|
}
|
|
if customConfig.HandleActiveInstances != nil {
|
|
config.HandleActiveInstances = *customConfig.HandleActiveInstances
|
|
}
|
|
if customConfig.TransactionDuration != nil {
|
|
config.TransactionDuration = *customConfig.TransactionDuration
|
|
}
|
|
|
|
return config
|
|
}
|
|
|
|
// we know this is ugly, but we need to have a singleton slice of all projections
|
|
// and are only able to initialize it after all projections are created
|
|
// as setup and start currently create them individually, we make sure we get the right one
|
|
// will be refactored when changing to new id based projections
|
|
//
|
|
// Event handlers NotificationsProjection, NotificationsQuotaProjection and NotificationsProjection are not added here, because they do not reduce to database statements
|
|
func newProjectionsList() {
|
|
projections = []projection{
|
|
OrgProjection,
|
|
OrgMetadataProjection,
|
|
ActionProjection,
|
|
FlowProjection,
|
|
ProjectProjection,
|
|
PasswordComplexityProjection,
|
|
PasswordAgeProjection,
|
|
LockoutPolicyProjection,
|
|
PrivacyPolicyProjection,
|
|
DomainPolicyProjection,
|
|
LabelPolicyProjection,
|
|
ProjectGrantProjection,
|
|
ProjectRoleProjection,
|
|
OrgDomainProjection,
|
|
LoginPolicyProjection,
|
|
IDPProjection,
|
|
IDPTemplateProjection,
|
|
AppProjection,
|
|
IDPUserLinkProjection,
|
|
IDPLoginPolicyLinkProjection,
|
|
MailTemplateProjection,
|
|
MessageTextProjection,
|
|
CustomTextProjection,
|
|
UserProjection,
|
|
LoginNameProjection,
|
|
OrgMemberProjection,
|
|
InstanceDomainProjection,
|
|
InstanceMemberProjection,
|
|
ProjectMemberProjection,
|
|
ProjectGrantMemberProjection,
|
|
AuthNKeyProjection,
|
|
PersonalAccessTokenProjection,
|
|
UserGrantProjection,
|
|
UserMetadataProjection,
|
|
UserAuthMethodProjection,
|
|
InstanceProjection,
|
|
SecretGeneratorProjection,
|
|
SMTPConfigProjection,
|
|
SMSConfigProjection,
|
|
OIDCSettingsProjection,
|
|
DebugNotificationProviderProjection,
|
|
KeyProjection,
|
|
SecurityPolicyProjection,
|
|
NotificationPolicyProjection,
|
|
DeviceAuthProjection,
|
|
SessionProjection,
|
|
AuthRequestProjection,
|
|
MilestoneProjection,
|
|
QuotaProjection.handler,
|
|
LimitsProjection,
|
|
RestrictionsProjection,
|
|
SystemFeatureProjection,
|
|
InstanceFeatureProjection,
|
|
TargetProjection,
|
|
ExecutionProjection,
|
|
UserSchemaProjection,
|
|
}
|
|
}
|