mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-05 14:37:45 +00:00
refactor(query): use new packages for org by id query (#7826)
If the feature is enabled the new packages are used to query org by id Part of: https://github.com/zitadel/zitadel/issues/7639 ### Definition of Ready - [x] I am happy with the code - [x] Short description of the feature/issue is added in the pr description - [x] PR is linked to the corresponding user story - [ ] Acceptance criteria are met - [ ] All open todos and follow ups are defined in a new ticket and justified - [ ] Deviations from the acceptance criteria and design are agreed with the PO and documented. - [x] No debug or dead code - [x] My code has no repetitions - [ ] Critical parts are tested automatically - [ ] Where possible E2E tests are implemented - [ ] Documentation/examples are up-to-date - [ ] All non-functional requirements are met - [x] Functionality of the acceptance criteria is checked manually on the dev system.
This commit is contained in:
parent
e58869c090
commit
0bfcf2c317
1
.github/workflows/e2e.yml
vendored
1
.github/workflows/e2e.yml
vendored
@ -5,6 +5,7 @@ on:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
timeout-minutes: 10
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
@ -16,6 +16,7 @@ func systemFeaturesToCommand(req *feature_pb.SetSystemFeaturesRequest) *command.
|
||||
UserSchema: req.UserSchema,
|
||||
Actions: req.Actions,
|
||||
TokenExchange: req.OidcTokenExchange,
|
||||
ImprovedPerformance: improvedPerformanceListToDomain(req.ImprovedPerformance),
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +29,7 @@ func systemFeaturesToPb(f *query.SystemFeatures) *feature_pb.GetSystemFeaturesRe
|
||||
UserSchema: featureSourceToFlagPb(&f.UserSchema),
|
||||
OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange),
|
||||
Actions: featureSourceToFlagPb(&f.Actions),
|
||||
ImprovedPerformance: featureSourceToImprovedPerformanceFlagPb(&f.ImprovedPerformance),
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,6 +41,7 @@ func instanceFeaturesToCommand(req *feature_pb.SetInstanceFeaturesRequest) *comm
|
||||
UserSchema: req.UserSchema,
|
||||
TokenExchange: req.OidcTokenExchange,
|
||||
Actions: req.Actions,
|
||||
ImprovedPerformance: improvedPerformanceListToDomain(req.ImprovedPerformance),
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,6 +54,14 @@ func instanceFeaturesToPb(f *query.InstanceFeatures) *feature_pb.GetInstanceFeat
|
||||
UserSchema: featureSourceToFlagPb(&f.UserSchema),
|
||||
OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange),
|
||||
Actions: featureSourceToFlagPb(&f.Actions),
|
||||
ImprovedPerformance: featureSourceToImprovedPerformanceFlagPb(&f.ImprovedPerformance),
|
||||
}
|
||||
}
|
||||
|
||||
func featureSourceToImprovedPerformanceFlagPb(fs *query.FeatureSource[[]feature.ImprovedPerformanceType]) *feature_pb.ImprovedPerformanceFeatureFlag {
|
||||
return &feature_pb.ImprovedPerformanceFeatureFlag{
|
||||
ExecutionPaths: improvedPerformanceTypesToPb(fs.Value),
|
||||
Source: featureLevelToSourcePb(fs.Level),
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,3 +92,48 @@ func featureLevelToSourcePb(level feature.Level) feature_pb.Source {
|
||||
return feature_pb.Source(level)
|
||||
}
|
||||
}
|
||||
|
||||
func improvedPerformanceTypesToPb(types []feature.ImprovedPerformanceType) []feature_pb.ImprovedPerformance {
|
||||
res := make([]feature_pb.ImprovedPerformance, len(types))
|
||||
|
||||
for i, typ := range types {
|
||||
res[i] = improvedPerformanceTypeToPb(typ)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func improvedPerformanceTypeToPb(typ feature.ImprovedPerformanceType) feature_pb.ImprovedPerformance {
|
||||
switch typ {
|
||||
case feature.ImprovedPerformanceTypeUnknown:
|
||||
return feature_pb.ImprovedPerformance_IMPROVED_PERFORMANCE_UNSPECIFIED
|
||||
case feature.ImprovedPerformanceTypeOrgByID:
|
||||
return feature_pb.ImprovedPerformance_IMPROVED_PERFORMANCE_ORG_BY_ID
|
||||
default:
|
||||
return feature_pb.ImprovedPerformance(typ)
|
||||
}
|
||||
}
|
||||
|
||||
func improvedPerformanceListToDomain(list []feature_pb.ImprovedPerformance) []feature.ImprovedPerformanceType {
|
||||
if list == nil {
|
||||
return nil
|
||||
}
|
||||
res := make([]feature.ImprovedPerformanceType, len(list))
|
||||
|
||||
for i, typ := range list {
|
||||
res[i] = improvedPerformanceToDomain(typ)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func improvedPerformanceToDomain(typ feature_pb.ImprovedPerformance) feature.ImprovedPerformanceType {
|
||||
switch typ {
|
||||
case feature_pb.ImprovedPerformance_IMPROVED_PERFORMANCE_UNSPECIFIED:
|
||||
return feature.ImprovedPerformanceTypeUnknown
|
||||
case feature_pb.ImprovedPerformance_IMPROVED_PERFORMANCE_ORG_BY_ID:
|
||||
return feature.ImprovedPerformanceTypeOrgByID
|
||||
default:
|
||||
return feature.ImprovedPerformanceTypeUnknown
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ func Test_systemFeaturesToCommand(t *testing.T) {
|
||||
UserSchema: gu.Ptr(true),
|
||||
Actions: gu.Ptr(true),
|
||||
OidcTokenExchange: gu.Ptr(true),
|
||||
ImprovedPerformance: nil,
|
||||
}
|
||||
want := &command.SystemFeatures{
|
||||
LoginDefaultOrg: gu.Ptr(true),
|
||||
@ -32,6 +33,7 @@ func Test_systemFeaturesToCommand(t *testing.T) {
|
||||
UserSchema: gu.Ptr(true),
|
||||
Actions: gu.Ptr(true),
|
||||
TokenExchange: gu.Ptr(true),
|
||||
ImprovedPerformance: nil,
|
||||
}
|
||||
got := systemFeaturesToCommand(arg)
|
||||
assert.Equal(t, want, got)
|
||||
@ -68,6 +70,10 @@ func Test_systemFeaturesToPb(t *testing.T) {
|
||||
Level: feature.LevelSystem,
|
||||
Value: false,
|
||||
},
|
||||
ImprovedPerformance: query.FeatureSource[[]feature.ImprovedPerformanceType]{
|
||||
Level: feature.LevelSystem,
|
||||
Value: []feature.ImprovedPerformanceType{feature.ImprovedPerformanceTypeOrgByID},
|
||||
},
|
||||
}
|
||||
want := &feature_pb.GetSystemFeaturesResponse{
|
||||
Details: &object.Details{
|
||||
@ -99,6 +105,10 @@ func Test_systemFeaturesToPb(t *testing.T) {
|
||||
Enabled: true,
|
||||
Source: feature_pb.Source_SOURCE_SYSTEM,
|
||||
},
|
||||
ImprovedPerformance: &feature_pb.ImprovedPerformanceFeatureFlag{
|
||||
ExecutionPaths: []feature_pb.ImprovedPerformance{feature_pb.ImprovedPerformance_IMPROVED_PERFORMANCE_ORG_BY_ID},
|
||||
Source: feature_pb.Source_SOURCE_SYSTEM,
|
||||
},
|
||||
}
|
||||
got := systemFeaturesToPb(arg)
|
||||
assert.Equal(t, want, got)
|
||||
@ -112,6 +122,7 @@ func Test_instanceFeaturesToCommand(t *testing.T) {
|
||||
UserSchema: gu.Ptr(true),
|
||||
OidcTokenExchange: gu.Ptr(true),
|
||||
Actions: gu.Ptr(true),
|
||||
ImprovedPerformance: nil,
|
||||
}
|
||||
want := &command.InstanceFeatures{
|
||||
LoginDefaultOrg: gu.Ptr(true),
|
||||
@ -120,6 +131,7 @@ func Test_instanceFeaturesToCommand(t *testing.T) {
|
||||
UserSchema: gu.Ptr(true),
|
||||
TokenExchange: gu.Ptr(true),
|
||||
Actions: gu.Ptr(true),
|
||||
ImprovedPerformance: nil,
|
||||
}
|
||||
got := instanceFeaturesToCommand(arg)
|
||||
assert.Equal(t, want, got)
|
||||
@ -156,6 +168,10 @@ func Test_instanceFeaturesToPb(t *testing.T) {
|
||||
Level: feature.LevelSystem,
|
||||
Value: false,
|
||||
},
|
||||
ImprovedPerformance: query.FeatureSource[[]feature.ImprovedPerformanceType]{
|
||||
Level: feature.LevelSystem,
|
||||
Value: []feature.ImprovedPerformanceType{feature.ImprovedPerformanceTypeOrgByID},
|
||||
},
|
||||
}
|
||||
want := &feature_pb.GetInstanceFeaturesResponse{
|
||||
Details: &object.Details{
|
||||
@ -187,6 +203,10 @@ func Test_instanceFeaturesToPb(t *testing.T) {
|
||||
Enabled: false,
|
||||
Source: feature_pb.Source_SOURCE_SYSTEM,
|
||||
},
|
||||
ImprovedPerformance: &feature_pb.ImprovedPerformanceFeatureFlag{
|
||||
ExecutionPaths: []feature_pb.ImprovedPerformance{feature_pb.ImprovedPerformance_IMPROVED_PERFORMANCE_ORG_BY_ID},
|
||||
Source: feature_pb.Source_SOURCE_SYSTEM,
|
||||
},
|
||||
}
|
||||
got := instanceFeaturesToPb(arg)
|
||||
assert.Equal(t, want, got)
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/command/preparation"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/feature"
|
||||
"github.com/zitadel/zitadel/internal/repository/feature/feature_v2"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
)
|
||||
@ -18,6 +19,7 @@ type InstanceFeatures struct {
|
||||
UserSchema *bool
|
||||
TokenExchange *bool
|
||||
Actions *bool
|
||||
ImprovedPerformance []feature.ImprovedPerformanceType
|
||||
}
|
||||
|
||||
func (m *InstanceFeatures) isEmpty() bool {
|
||||
@ -26,7 +28,9 @@ func (m *InstanceFeatures) isEmpty() bool {
|
||||
m.LegacyIntrospection == nil &&
|
||||
m.UserSchema == nil &&
|
||||
m.TokenExchange == nil &&
|
||||
m.Actions == nil
|
||||
m.Actions == nil &&
|
||||
// nil check to allow unset improvements
|
||||
m.ImprovedPerformance == nil
|
||||
}
|
||||
|
||||
func (c *Commands) SetInstanceFeatures(ctx context.Context, f *InstanceFeatures) (*domain.ObjectDetails, error) {
|
||||
@ -37,11 +41,11 @@ func (c *Commands) SetInstanceFeatures(ctx context.Context, f *InstanceFeatures)
|
||||
if err := c.eventstore.FilterToQueryReducer(ctx, wm); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmds := wm.setCommands(ctx, f)
|
||||
if len(cmds) == 0 {
|
||||
commands := wm.setCommands(ctx, f)
|
||||
if len(commands) == 0 {
|
||||
return writeModelToObjectDetails(wm.WriteModel), nil
|
||||
}
|
||||
events, err := c.eventstore.Push(ctx, cmds...)
|
||||
events, err := c.eventstore.Push(ctx, commands...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -30,14 +30,23 @@ func (m *InstanceFeaturesWriteModel) Reduce() (err error) {
|
||||
case *feature_v2.ResetEvent:
|
||||
m.reduceReset()
|
||||
case *feature_v1.SetEvent[feature_v1.Boolean]:
|
||||
err = m.reduceBoolFeature(
|
||||
feature_v1.DefaultLoginInstanceEventToV2(e),
|
||||
reduceInstanceFeature(
|
||||
&m.InstanceFeatures,
|
||||
feature.KeyLoginDefaultOrg,
|
||||
feature_v1.DefaultLoginInstanceEventToV2(e).Value,
|
||||
)
|
||||
case *feature_v2.SetEvent[bool]:
|
||||
err = m.reduceBoolFeature(e)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
_, key, err := e.FeatureInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reduceInstanceFeature(&m.InstanceFeatures, key, e.Value)
|
||||
case *feature_v2.SetEvent[[]feature.ImprovedPerformanceType]:
|
||||
_, key, err := e.FeatureInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reduceInstanceFeature(&m.InstanceFeatures, key, e.Value)
|
||||
}
|
||||
}
|
||||
return m.WriteModel.Reduce()
|
||||
@ -57,41 +66,41 @@ func (m *InstanceFeaturesWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
feature_v2.InstanceUserSchemaEventType,
|
||||
feature_v2.InstanceTokenExchangeEventType,
|
||||
feature_v2.InstanceActionsEventType,
|
||||
feature_v2.InstanceImprovedPerformanceEventType,
|
||||
).
|
||||
Builder().ResourceOwner(m.ResourceOwner)
|
||||
}
|
||||
|
||||
func (m *InstanceFeaturesWriteModel) reduceReset() {
|
||||
m.LoginDefaultOrg = nil
|
||||
m.TriggerIntrospectionProjections = nil
|
||||
m.LegacyIntrospection = nil
|
||||
m.UserSchema = nil
|
||||
m.TokenExchange = nil
|
||||
m.Actions = nil
|
||||
m.InstanceFeatures = InstanceFeatures{}
|
||||
}
|
||||
|
||||
func (m *InstanceFeaturesWriteModel) reduceBoolFeature(event *feature_v2.SetEvent[bool]) error {
|
||||
_, key, err := event.FeatureInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func reduceInstanceFeature(features *InstanceFeatures, key feature.Key, value any) {
|
||||
switch key {
|
||||
case feature.KeyUnspecified:
|
||||
return nil
|
||||
return
|
||||
case feature.KeyLoginDefaultOrg:
|
||||
m.LoginDefaultOrg = &event.Value
|
||||
v := value.(bool)
|
||||
features.LoginDefaultOrg = &v
|
||||
case feature.KeyTriggerIntrospectionProjections:
|
||||
m.TriggerIntrospectionProjections = &event.Value
|
||||
v := value.(bool)
|
||||
features.TriggerIntrospectionProjections = &v
|
||||
case feature.KeyLegacyIntrospection:
|
||||
m.LegacyIntrospection = &event.Value
|
||||
v := value.(bool)
|
||||
features.LegacyIntrospection = &v
|
||||
case feature.KeyTokenExchange:
|
||||
m.TokenExchange = &event.Value
|
||||
v := value.(bool)
|
||||
features.TokenExchange = &v
|
||||
case feature.KeyUserSchema:
|
||||
m.UserSchema = &event.Value
|
||||
v := value.(bool)
|
||||
features.UserSchema = &v
|
||||
case feature.KeyActions:
|
||||
m.Actions = &event.Value
|
||||
v := value.(bool)
|
||||
features.Actions = &v
|
||||
case feature.KeyImprovedPerformance:
|
||||
v := value.([]feature.ImprovedPerformanceType)
|
||||
features.ImprovedPerformance = v
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wm *InstanceFeaturesWriteModel) setCommands(ctx context.Context, f *InstanceFeatures) []eventstore.Command {
|
||||
@ -103,5 +112,6 @@ func (wm *InstanceFeaturesWriteModel) setCommands(ctx context.Context, f *Instan
|
||||
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.TokenExchange, f.TokenExchange, feature_v2.InstanceTokenExchangeEventType)
|
||||
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.UserSchema, f.UserSchema, feature_v2.InstanceUserSchemaEventType)
|
||||
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.Actions, f.Actions, feature_v2.InstanceActionsEventType)
|
||||
cmds = appendFeatureSliceUpdate(ctx, cmds, aggregate, wm.ImprovedPerformance, f.ImprovedPerformance, feature_v2.InstanceImprovedPerformanceEventType)
|
||||
return cmds
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/feature"
|
||||
"github.com/zitadel/zitadel/internal/repository/feature/feature_v2"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
)
|
||||
@ -15,6 +16,7 @@ type SystemFeatures struct {
|
||||
TokenExchange *bool
|
||||
UserSchema *bool
|
||||
Actions *bool
|
||||
ImprovedPerformance []feature.ImprovedPerformanceType
|
||||
}
|
||||
|
||||
func (m *SystemFeatures) isEmpty() bool {
|
||||
@ -23,7 +25,9 @@ func (m *SystemFeatures) isEmpty() bool {
|
||||
m.LegacyIntrospection == nil &&
|
||||
m.UserSchema == nil &&
|
||||
m.TokenExchange == nil &&
|
||||
m.Actions == nil
|
||||
m.Actions == nil &&
|
||||
// nil check to allow unset improvements
|
||||
m.ImprovedPerformance == nil
|
||||
}
|
||||
|
||||
func (c *Commands) SetSystemFeatures(ctx context.Context, f *SystemFeatures) (*domain.ObjectDetails, error) {
|
||||
|
@ -23,16 +23,23 @@ func NewSystemFeaturesWriteModel() *SystemFeaturesWriteModel {
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *SystemFeaturesWriteModel) Reduce() (err error) {
|
||||
func (m *SystemFeaturesWriteModel) Reduce() error {
|
||||
for _, event := range m.Events {
|
||||
switch e := event.(type) {
|
||||
case *feature_v2.ResetEvent:
|
||||
m.reduceReset()
|
||||
case *feature_v2.SetEvent[bool]:
|
||||
err = m.reduceBoolFeature(e)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
_, key, err := e.FeatureInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reduceSystemFeature(&m.SystemFeatures, key, e.Value)
|
||||
case *feature_v2.SetEvent[[]feature.ImprovedPerformanceType]:
|
||||
_, key, err := e.FeatureInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reduceSystemFeature(&m.SystemFeatures, key, e.Value)
|
||||
}
|
||||
}
|
||||
return m.WriteModel.Reduce()
|
||||
@ -52,41 +59,40 @@ func (m *SystemFeaturesWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
feature_v2.SystemUserSchemaEventType,
|
||||
feature_v2.SystemTokenExchangeEventType,
|
||||
feature_v2.SystemActionsEventType,
|
||||
feature_v2.SystemImprovedPerformanceEventType,
|
||||
).
|
||||
Builder().ResourceOwner(m.ResourceOwner)
|
||||
}
|
||||
|
||||
func (m *SystemFeaturesWriteModel) reduceReset() {
|
||||
m.LoginDefaultOrg = nil
|
||||
m.TriggerIntrospectionProjections = nil
|
||||
m.LegacyIntrospection = nil
|
||||
m.TokenExchange = nil
|
||||
m.UserSchema = nil
|
||||
m.Actions = nil
|
||||
m.SystemFeatures = SystemFeatures{}
|
||||
}
|
||||
|
||||
func (m *SystemFeaturesWriteModel) reduceBoolFeature(event *feature_v2.SetEvent[bool]) error {
|
||||
_, key, err := event.FeatureInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func reduceSystemFeature(features *SystemFeatures, key feature.Key, value any) {
|
||||
switch key {
|
||||
case feature.KeyUnspecified:
|
||||
return nil
|
||||
return
|
||||
case feature.KeyLoginDefaultOrg:
|
||||
m.LoginDefaultOrg = &event.Value
|
||||
v := value.(bool)
|
||||
features.LoginDefaultOrg = &v
|
||||
case feature.KeyTriggerIntrospectionProjections:
|
||||
m.TriggerIntrospectionProjections = &event.Value
|
||||
v := value.(bool)
|
||||
features.TriggerIntrospectionProjections = &v
|
||||
case feature.KeyLegacyIntrospection:
|
||||
m.LegacyIntrospection = &event.Value
|
||||
v := value.(bool)
|
||||
features.LegacyIntrospection = &v
|
||||
case feature.KeyUserSchema:
|
||||
m.UserSchema = &event.Value
|
||||
v := value.(bool)
|
||||
features.UserSchema = &v
|
||||
case feature.KeyTokenExchange:
|
||||
m.TokenExchange = &event.Value
|
||||
v := value.(bool)
|
||||
features.TokenExchange = &v
|
||||
case feature.KeyActions:
|
||||
m.Actions = &event.Value
|
||||
v := value.(bool)
|
||||
features.Actions = &v
|
||||
case feature.KeyImprovedPerformance:
|
||||
features.ImprovedPerformance = value.([]feature.ImprovedPerformanceType)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wm *SystemFeaturesWriteModel) setCommands(ctx context.Context, f *SystemFeatures) []eventstore.Command {
|
||||
@ -98,6 +104,7 @@ func (wm *SystemFeaturesWriteModel) setCommands(ctx context.Context, f *SystemFe
|
||||
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.UserSchema, f.UserSchema, feature_v2.SystemUserSchemaEventType)
|
||||
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.TokenExchange, f.TokenExchange, feature_v2.SystemTokenExchangeEventType)
|
||||
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.Actions, f.Actions, feature_v2.SystemActionsEventType)
|
||||
cmds = appendFeatureSliceUpdate(ctx, cmds, aggregate, wm.ImprovedPerformance, f.ImprovedPerformance, feature_v2.SystemImprovedPerformanceEventType)
|
||||
return cmds
|
||||
}
|
||||
|
||||
@ -107,3 +114,15 @@ func appendFeatureUpdate[T comparable](ctx context.Context, cmds []eventstore.Co
|
||||
}
|
||||
return cmds
|
||||
}
|
||||
|
||||
func appendFeatureSliceUpdate[T comparable](ctx context.Context, cmds []eventstore.Command, aggregate *feature_v2.Aggregate, oldValues, newValues []T, eventType eventstore.EventType) []eventstore.Command {
|
||||
if len(newValues) != len(oldValues) {
|
||||
return append(cmds, feature_v2.NewSetEvent[[]T](ctx, aggregate, eventType, newValues))
|
||||
}
|
||||
for i, oldValue := range oldValues {
|
||||
if oldValue != newValues[i] {
|
||||
return append(cmds, feature_v2.NewSetEvent[[]T](ctx, aggregate, eventType, newValues))
|
||||
}
|
||||
}
|
||||
return cmds
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ const (
|
||||
KeyUserSchema
|
||||
KeyTokenExchange
|
||||
KeyActions
|
||||
KeyImprovedPerformance
|
||||
)
|
||||
|
||||
//go:generate enumer -type Level -transform snake -trimprefix Level
|
||||
@ -27,10 +28,27 @@ const (
|
||||
)
|
||||
|
||||
type Features struct {
|
||||
LoginDefaultOrg bool `json:"login_default_org,omitempty"`
|
||||
TriggerIntrospectionProjections bool `json:"trigger_introspection_projections,omitempty"`
|
||||
LegacyIntrospection bool `json:"legacy_introspection,omitempty"`
|
||||
UserSchema bool `json:"user_schema,omitempty"`
|
||||
TokenExchange bool `json:"token_exchange,omitempty"`
|
||||
Actions bool `json:"actions,omitempty"`
|
||||
LoginDefaultOrg bool `json:"login_default_org,omitempty"`
|
||||
TriggerIntrospectionProjections bool `json:"trigger_introspection_projections,omitempty"`
|
||||
LegacyIntrospection bool `json:"legacy_introspection,omitempty"`
|
||||
UserSchema bool `json:"user_schema,omitempty"`
|
||||
TokenExchange bool `json:"token_exchange,omitempty"`
|
||||
Actions bool `json:"actions,omitempty"`
|
||||
ImprovedPerformance []ImprovedPerformanceType `json:"improved_performance,omitempty"`
|
||||
}
|
||||
|
||||
type ImprovedPerformanceType int32
|
||||
|
||||
const (
|
||||
ImprovedPerformanceTypeUnknown = iota
|
||||
ImprovedPerformanceTypeOrgByID
|
||||
)
|
||||
|
||||
func (f Features) ShouldUseImprovedPerformance(typ ImprovedPerformanceType) bool {
|
||||
for _, improvedType := range f.ImprovedPerformance {
|
||||
if improvedType == typ {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -7,11 +7,11 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const _KeyName = "unspecifiedlogin_default_orgtrigger_introspection_projectionslegacy_introspectionuser_schematoken_exchangeactions"
|
||||
const _KeyName = "unspecifiedlogin_default_orgtrigger_introspection_projectionslegacy_introspectionuser_schematoken_exchangeactionsimproved_performance"
|
||||
|
||||
var _KeyIndex = [...]uint8{0, 11, 28, 61, 81, 92, 106, 113}
|
||||
var _KeyIndex = [...]uint8{0, 11, 28, 61, 81, 92, 106, 113, 133}
|
||||
|
||||
const _KeyLowerName = "unspecifiedlogin_default_orgtrigger_introspection_projectionslegacy_introspectionuser_schematoken_exchangeactions"
|
||||
const _KeyLowerName = "unspecifiedlogin_default_orgtrigger_introspection_projectionslegacy_introspectionuser_schematoken_exchangeactionsimproved_performance"
|
||||
|
||||
func (i Key) String() string {
|
||||
if i < 0 || i >= Key(len(_KeyIndex)-1) {
|
||||
@ -31,9 +31,10 @@ func _KeyNoOp() {
|
||||
_ = x[KeyUserSchema-(4)]
|
||||
_ = x[KeyTokenExchange-(5)]
|
||||
_ = x[KeyActions-(6)]
|
||||
_ = x[KeyImprovedPerformance-(7)]
|
||||
}
|
||||
|
||||
var _KeyValues = []Key{KeyUnspecified, KeyLoginDefaultOrg, KeyTriggerIntrospectionProjections, KeyLegacyIntrospection, KeyUserSchema, KeyTokenExchange, KeyActions}
|
||||
var _KeyValues = []Key{KeyUnspecified, KeyLoginDefaultOrg, KeyTriggerIntrospectionProjections, KeyLegacyIntrospection, KeyUserSchema, KeyTokenExchange, KeyActions, KeyImprovedPerformance}
|
||||
|
||||
var _KeyNameToValueMap = map[string]Key{
|
||||
_KeyName[0:11]: KeyUnspecified,
|
||||
@ -50,6 +51,8 @@ var _KeyNameToValueMap = map[string]Key{
|
||||
_KeyLowerName[92:106]: KeyTokenExchange,
|
||||
_KeyName[106:113]: KeyActions,
|
||||
_KeyLowerName[106:113]: KeyActions,
|
||||
_KeyName[113:133]: KeyImprovedPerformance,
|
||||
_KeyLowerName[113:133]: KeyImprovedPerformance,
|
||||
}
|
||||
|
||||
var _KeyNames = []string{
|
||||
@ -60,6 +63,7 @@ var _KeyNames = []string{
|
||||
_KeyName[81:92],
|
||||
_KeyName[92:106],
|
||||
_KeyName[106:113],
|
||||
_KeyName[113:133],
|
||||
}
|
||||
|
||||
// KeyString retrieves an enum value from the enum constants string name.
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/feature"
|
||||
)
|
||||
|
||||
type InstanceFeatures struct {
|
||||
@ -14,6 +15,7 @@ type InstanceFeatures struct {
|
||||
UserSchema FeatureSource[bool]
|
||||
TokenExchange FeatureSource[bool]
|
||||
Actions FeatureSource[bool]
|
||||
ImprovedPerformance FeatureSource[[]feature.ImprovedPerformanceType]
|
||||
}
|
||||
|
||||
func (q *Queries) GetInstanceFeatures(ctx context.Context, cascade bool) (_ *InstanceFeatures, err error) {
|
||||
|
@ -36,11 +36,14 @@ func (m *InstanceFeaturesReadModel) Reduce() (err error) {
|
||||
case *feature_v2.ResetEvent:
|
||||
m.reduceReset()
|
||||
case *feature_v1.SetEvent[feature_v1.Boolean]:
|
||||
err = m.reduceBoolFeature(
|
||||
err = reduceInstanceFeatureSet(
|
||||
m.instance,
|
||||
feature_v1.DefaultLoginInstanceEventToV2(e),
|
||||
)
|
||||
case *feature_v2.SetEvent[bool]:
|
||||
err = m.reduceBoolFeature(e)
|
||||
err = reduceInstanceFeatureSet(m.instance, e)
|
||||
case *feature_v2.SetEvent[[]feature.ImprovedPerformanceType]:
|
||||
err = reduceInstanceFeatureSet(m.instance, e)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@ -63,6 +66,7 @@ func (m *InstanceFeaturesReadModel) Query() *eventstore.SearchQueryBuilder {
|
||||
feature_v2.InstanceUserSchemaEventType,
|
||||
feature_v2.InstanceTokenExchangeEventType,
|
||||
feature_v2.InstanceActionsEventType,
|
||||
feature_v2.InstanceImprovedPerformanceEventType,
|
||||
).
|
||||
Builder().ResourceOwner(m.ResourceOwner)
|
||||
}
|
||||
@ -71,12 +75,8 @@ func (m *InstanceFeaturesReadModel) reduceReset() {
|
||||
if m.populateFromSystem() {
|
||||
return
|
||||
}
|
||||
m.instance.LoginDefaultOrg = FeatureSource[bool]{}
|
||||
m.instance.TriggerIntrospectionProjections = FeatureSource[bool]{}
|
||||
m.instance.LegacyIntrospection = FeatureSource[bool]{}
|
||||
m.instance.UserSchema = FeatureSource[bool]{}
|
||||
m.instance.TokenExchange = FeatureSource[bool]{}
|
||||
m.instance.Actions = FeatureSource[bool]{}
|
||||
m.instance = nil
|
||||
m.instance = new(InstanceFeatures)
|
||||
}
|
||||
|
||||
func (m *InstanceFeaturesReadModel) populateFromSystem() bool {
|
||||
@ -89,35 +89,32 @@ func (m *InstanceFeaturesReadModel) populateFromSystem() bool {
|
||||
m.instance.UserSchema = m.system.UserSchema
|
||||
m.instance.TokenExchange = m.system.TokenExchange
|
||||
m.instance.Actions = m.system.Actions
|
||||
m.instance.ImprovedPerformance = m.system.ImprovedPerformance
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *InstanceFeaturesReadModel) reduceBoolFeature(event *feature_v2.SetEvent[bool]) error {
|
||||
func reduceInstanceFeatureSet[T any](features *InstanceFeatures, event *feature_v2.SetEvent[T]) error {
|
||||
level, key, err := event.FeatureInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var dst *FeatureSource[bool]
|
||||
|
||||
switch key {
|
||||
case feature.KeyUnspecified:
|
||||
return nil
|
||||
case feature.KeyLoginDefaultOrg:
|
||||
dst = &m.instance.LoginDefaultOrg
|
||||
features.LoginDefaultOrg.set(level, event.Value)
|
||||
case feature.KeyTriggerIntrospectionProjections:
|
||||
dst = &m.instance.TriggerIntrospectionProjections
|
||||
features.TriggerIntrospectionProjections.set(level, event.Value)
|
||||
case feature.KeyLegacyIntrospection:
|
||||
dst = &m.instance.LegacyIntrospection
|
||||
features.LegacyIntrospection.set(level, event.Value)
|
||||
case feature.KeyUserSchema:
|
||||
dst = &m.instance.UserSchema
|
||||
features.UserSchema.set(level, event.Value)
|
||||
case feature.KeyTokenExchange:
|
||||
dst = &m.instance.TokenExchange
|
||||
features.TokenExchange.set(level, event.Value)
|
||||
case feature.KeyActions:
|
||||
dst = &m.instance.Actions
|
||||
}
|
||||
*dst = FeatureSource[bool]{
|
||||
Level: level,
|
||||
Value: event.Value,
|
||||
features.Actions.set(level, event.Value)
|
||||
case feature.KeyImprovedPerformance:
|
||||
features.ImprovedPerformance.set(level, event.Value)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -13,8 +13,11 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/api/call"
|
||||
domain_pkg "github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
|
||||
"github.com/zitadel/zitadel/internal/feature"
|
||||
"github.com/zitadel/zitadel/internal/query/projection"
|
||||
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
||||
"github.com/zitadel/zitadel/internal/v2/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/v2/readmodel"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
)
|
||||
|
||||
@ -92,7 +95,44 @@ func (q *OrgSearchQueries) toQuery(query sq.SelectBuilder) sq.SelectBuilder {
|
||||
return query
|
||||
}
|
||||
|
||||
func (q *Queries) OrgByID(ctx context.Context, shouldTriggerBulk bool, id string) (org *Org, err error) {
|
||||
func (q *Queries) OrgByID(ctx context.Context, shouldTriggerBulk bool, id string) (_ *Org, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
if !authz.GetInstance(ctx).Features().ShouldUseImprovedPerformance(feature.ImprovedPerformanceTypeOrgByID) {
|
||||
return q.oldOrgByID(ctx, shouldTriggerBulk, id)
|
||||
}
|
||||
|
||||
foundOrg := readmodel.NewOrg(id)
|
||||
eventCount, err := q.eventStoreV4.Query(
|
||||
ctx,
|
||||
eventstore.NewQuery(
|
||||
authz.GetInstance(ctx).InstanceID(),
|
||||
foundOrg,
|
||||
eventstore.AppendFilters(foundOrg.Filter()...),
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowInternal(err, "QUERY-AWx52", "Errors.Query.SQLStatement")
|
||||
}
|
||||
|
||||
if eventCount == 0 {
|
||||
return nil, zerrors.ThrowNotFound(nil, "QUERY-leq5Q", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return &Org{
|
||||
ID: foundOrg.ID,
|
||||
CreationDate: foundOrg.CreationDate,
|
||||
ChangeDate: foundOrg.ChangeDate,
|
||||
ResourceOwner: foundOrg.Owner,
|
||||
State: domain_pkg.OrgState(foundOrg.State.State),
|
||||
Sequence: uint64(foundOrg.Sequence),
|
||||
Name: foundOrg.Name,
|
||||
Domain: foundOrg.PrimaryDomain.Domain,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (q *Queries) oldOrgByID(ctx context.Context, shouldTriggerBulk bool, id string) (org *Org, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
old_handler "github.com/zitadel/zitadel/internal/eventstore/handler"
|
||||
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
|
||||
"github.com/zitadel/zitadel/internal/feature"
|
||||
feature_v1 "github.com/zitadel/zitadel/internal/repository/feature"
|
||||
"github.com/zitadel/zitadel/internal/repository/feature/feature_v2"
|
||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||
@ -83,6 +84,10 @@ func (*instanceFeatureProjection) Reducers() []handler.AggregateReducer {
|
||||
Event: feature_v2.InstanceActionsEventType,
|
||||
Reduce: reduceInstanceSetFeature[bool],
|
||||
},
|
||||
{
|
||||
Event: feature_v2.InstanceImprovedPerformanceEventType,
|
||||
Reduce: reduceInstanceSetFeature[[]feature.ImprovedPerformanceType],
|
||||
},
|
||||
{
|
||||
Event: instance.InstanceRemovedEventType,
|
||||
Reduce: reduceInstanceRemovedHelper(InstanceDomainInstanceIDCol),
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
old_handler "github.com/zitadel/zitadel/internal/eventstore/handler"
|
||||
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
|
||||
"github.com/zitadel/zitadel/internal/feature"
|
||||
"github.com/zitadel/zitadel/internal/repository/feature/feature_v2"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
)
|
||||
@ -75,6 +76,10 @@ func (*systemFeatureProjection) Reducers() []handler.AggregateReducer {
|
||||
Event: feature_v2.SystemActionsEventType,
|
||||
Reduce: reduceSystemSetFeature[bool],
|
||||
},
|
||||
{
|
||||
Event: feature_v2.SystemImprovedPerformanceEventType,
|
||||
Reduce: reduceSystemSetFeature[[]feature.ImprovedPerformanceType],
|
||||
},
|
||||
},
|
||||
}}
|
||||
}
|
||||
|
@ -19,11 +19,14 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
|
||||
"github.com/zitadel/zitadel/internal/query/projection"
|
||||
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
||||
es_v4 "github.com/zitadel/zitadel/internal/v2/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/v2/eventstore/postgres"
|
||||
)
|
||||
|
||||
type Queries struct {
|
||||
eventstore *eventstore.Eventstore
|
||||
client *database.DB
|
||||
eventstore *eventstore.Eventstore
|
||||
eventStoreV4 es_v4.Querier
|
||||
client *database.DB
|
||||
|
||||
keyEncryptionAlgorithm crypto.EncryptionAlgorithm
|
||||
idpConfigEncryption crypto.EncryptionAlgorithm
|
||||
@ -56,6 +59,7 @@ func StartQueries(
|
||||
) (repo *Queries, err error) {
|
||||
repo = &Queries{
|
||||
eventstore: es,
|
||||
eventStoreV4: postgres.New(querySqlClient),
|
||||
client: querySqlClient,
|
||||
DefaultLanguage: language.Und,
|
||||
LoginTranslationFileContents: make(map[string][]byte),
|
||||
|
@ -12,6 +12,11 @@ type FeatureSource[T any] struct {
|
||||
Value T
|
||||
}
|
||||
|
||||
func (f *FeatureSource[T]) set(level feature.Level, value any) {
|
||||
f.Level = level
|
||||
f.Value = value.(T)
|
||||
}
|
||||
|
||||
type SystemFeatures struct {
|
||||
Details *domain.ObjectDetails
|
||||
|
||||
@ -21,6 +26,7 @@ type SystemFeatures struct {
|
||||
UserSchema FeatureSource[bool]
|
||||
TokenExchange FeatureSource[bool]
|
||||
Actions FeatureSource[bool]
|
||||
ImprovedPerformance FeatureSource[[]feature.ImprovedPerformanceType]
|
||||
}
|
||||
|
||||
func (q *Queries) GetSystemFeatures(ctx context.Context) (_ *SystemFeatures, err error) {
|
||||
|
@ -28,7 +28,12 @@ func (m *SystemFeaturesReadModel) Reduce() error {
|
||||
case *feature_v2.ResetEvent:
|
||||
m.reduceReset()
|
||||
case *feature_v2.SetEvent[bool]:
|
||||
err := m.reduceBoolFeature(e)
|
||||
err := reduceSystemFeatureSet(m.system, e)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case *feature_v2.SetEvent[[]feature.ImprovedPerformanceType]:
|
||||
err := reduceSystemFeatureSet(m.system, e)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -51,41 +56,38 @@ func (m *SystemFeaturesReadModel) Query() *eventstore.SearchQueryBuilder {
|
||||
feature_v2.SystemUserSchemaEventType,
|
||||
feature_v2.SystemTokenExchangeEventType,
|
||||
feature_v2.SystemActionsEventType,
|
||||
feature_v2.SystemImprovedPerformanceEventType,
|
||||
).
|
||||
Builder().ResourceOwner(m.ResourceOwner)
|
||||
}
|
||||
|
||||
func (m *SystemFeaturesReadModel) reduceReset() {
|
||||
m.system = nil
|
||||
m.system = new(SystemFeatures)
|
||||
}
|
||||
|
||||
func (m *SystemFeaturesReadModel) reduceBoolFeature(event *feature_v2.SetEvent[bool]) error {
|
||||
func reduceSystemFeatureSet[T any](features *SystemFeatures, event *feature_v2.SetEvent[T]) error {
|
||||
level, key, err := event.FeatureInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var dst *FeatureSource[bool]
|
||||
|
||||
switch key {
|
||||
case feature.KeyUnspecified:
|
||||
return nil
|
||||
case feature.KeyLoginDefaultOrg:
|
||||
dst = &m.system.LoginDefaultOrg
|
||||
features.LoginDefaultOrg.set(level, event.Value)
|
||||
case feature.KeyTriggerIntrospectionProjections:
|
||||
dst = &m.system.TriggerIntrospectionProjections
|
||||
features.TriggerIntrospectionProjections.set(level, event.Value)
|
||||
case feature.KeyLegacyIntrospection:
|
||||
dst = &m.system.LegacyIntrospection
|
||||
features.LegacyIntrospection.set(level, event.Value)
|
||||
case feature.KeyUserSchema:
|
||||
dst = &m.system.UserSchema
|
||||
features.UserSchema.set(level, event.Value)
|
||||
case feature.KeyTokenExchange:
|
||||
dst = &m.system.TokenExchange
|
||||
features.TokenExchange.set(level, event.Value)
|
||||
case feature.KeyActions:
|
||||
dst = &m.system.Actions
|
||||
}
|
||||
|
||||
*dst = FeatureSource[bool]{
|
||||
Level: level,
|
||||
Value: event.Value,
|
||||
features.Actions.set(level, event.Value)
|
||||
case feature.KeyImprovedPerformance:
|
||||
features.ImprovedPerformance.set(level, event.Value)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package feature_v2
|
||||
|
||||
import (
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/feature"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -12,6 +13,8 @@ func init() {
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SystemUserSchemaEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SystemTokenExchangeEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SystemActionsEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, SystemImprovedPerformanceEventType, eventstore.GenericEventMapper[SetEvent[[]feature.ImprovedPerformanceType]])
|
||||
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceResetEventType, eventstore.GenericEventMapper[ResetEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceLoginDefaultOrgEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceTriggerIntrospectionProjectionsEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
||||
@ -19,4 +22,5 @@ func init() {
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceUserSchemaEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceTokenExchangeEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceActionsEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceImprovedPerformanceEventType, eventstore.GenericEventMapper[SetEvent[[]feature.ImprovedPerformanceType]])
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ var (
|
||||
SystemUserSchemaEventType = setEventTypeFromFeature(feature.LevelSystem, feature.KeyUserSchema)
|
||||
SystemTokenExchangeEventType = setEventTypeFromFeature(feature.LevelSystem, feature.KeyTokenExchange)
|
||||
SystemActionsEventType = setEventTypeFromFeature(feature.LevelSystem, feature.KeyActions)
|
||||
SystemImprovedPerformanceEventType = setEventTypeFromFeature(feature.LevelSystem, feature.KeyImprovedPerformance)
|
||||
|
||||
InstanceResetEventType = resetEventTypeFromFeature(feature.LevelInstance)
|
||||
InstanceLoginDefaultOrgEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyLoginDefaultOrg)
|
||||
@ -26,6 +27,7 @@ var (
|
||||
InstanceUserSchemaEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyUserSchema)
|
||||
InstanceTokenExchangeEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyTokenExchange)
|
||||
InstanceActionsEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyActions)
|
||||
InstanceImprovedPerformanceEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyImprovedPerformance)
|
||||
)
|
||||
|
||||
const (
|
||||
|
57
internal/v2/projection/org_primary_domain.go
Normal file
57
internal/v2/projection/org_primary_domain.go
Normal file
@ -0,0 +1,57 @@
|
||||
package projection
|
||||
|
||||
import (
|
||||
"github.com/zitadel/zitadel/internal/v2/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/v2/org"
|
||||
)
|
||||
|
||||
type OrgPrimaryDomain struct {
|
||||
projection
|
||||
|
||||
id string
|
||||
|
||||
Domain string
|
||||
}
|
||||
|
||||
func NewOrgPrimaryDomain(id string) *OrgPrimaryDomain {
|
||||
return &OrgPrimaryDomain{
|
||||
id: id,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *OrgPrimaryDomain) Filter() []*eventstore.Filter {
|
||||
return []*eventstore.Filter{
|
||||
eventstore.NewFilter(
|
||||
eventstore.FilterPagination(
|
||||
eventstore.GlobalPositionGreater(&p.position),
|
||||
),
|
||||
eventstore.AppendAggregateFilter(
|
||||
org.AggregateType,
|
||||
eventstore.AggregateIDs(p.id),
|
||||
eventstore.AppendEvent(
|
||||
eventstore.SetEventTypes(org.DomainPrimarySetType),
|
||||
),
|
||||
),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *OrgPrimaryDomain) Reduce(events ...*eventstore.StorageEvent) error {
|
||||
for _, event := range events {
|
||||
if !p.shouldReduce(event) {
|
||||
continue
|
||||
}
|
||||
if event.Type != org.DomainPrimarySetType {
|
||||
continue
|
||||
}
|
||||
e, err := org.DomainPrimarySetEventFromStorage(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.Domain = e.Payload.Name
|
||||
p.projection.reduce(event)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
67
internal/v2/projection/org_state.go
Normal file
67
internal/v2/projection/org_state.go
Normal file
@ -0,0 +1,67 @@
|
||||
package projection
|
||||
|
||||
import (
|
||||
"github.com/zitadel/zitadel/internal/v2/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/v2/org"
|
||||
)
|
||||
|
||||
type OrgState struct {
|
||||
projection
|
||||
|
||||
id string
|
||||
|
||||
org.State
|
||||
}
|
||||
|
||||
func NewStateProjection(id string) *OrgState {
|
||||
// TODO: check buffer for id and return from buffer if exists
|
||||
return &OrgState{
|
||||
id: id,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *OrgState) Filter() []*eventstore.Filter {
|
||||
return []*eventstore.Filter{
|
||||
eventstore.NewFilter(
|
||||
eventstore.FilterPagination(
|
||||
eventstore.Descending(),
|
||||
eventstore.GlobalPositionGreater(&p.position),
|
||||
),
|
||||
eventstore.AppendAggregateFilter(
|
||||
org.AggregateType,
|
||||
eventstore.AggregateIDs(p.id),
|
||||
eventstore.AppendEvent(
|
||||
eventstore.SetEventTypes(
|
||||
org.AddedType,
|
||||
org.DeactivatedType,
|
||||
org.ReactivatedType,
|
||||
org.RemovedType,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *OrgState) Reduce(events ...*eventstore.StorageEvent) error {
|
||||
for _, event := range events {
|
||||
if !p.shouldReduce(event) {
|
||||
continue
|
||||
}
|
||||
|
||||
switch event.Type {
|
||||
case org.AddedType:
|
||||
p.State = org.ActiveState
|
||||
case org.DeactivatedType:
|
||||
p.State = org.InactiveState
|
||||
case org.ReactivatedType:
|
||||
p.State = org.ActiveState
|
||||
case org.RemovedType:
|
||||
p.State = org.RemovedState
|
||||
default:
|
||||
continue
|
||||
}
|
||||
p.position = event.Position
|
||||
}
|
||||
return nil
|
||||
}
|
20
internal/v2/projection/projection.go
Normal file
20
internal/v2/projection/projection.go
Normal file
@ -0,0 +1,20 @@
|
||||
package projection
|
||||
|
||||
import "github.com/zitadel/zitadel/internal/v2/eventstore"
|
||||
|
||||
type projection struct {
|
||||
instance string
|
||||
position eventstore.GlobalPosition
|
||||
}
|
||||
|
||||
func (p *projection) reduce(event *eventstore.StorageEvent) {
|
||||
if p.instance == "" {
|
||||
p.instance = event.Aggregate.Instance
|
||||
}
|
||||
p.position = event.Position
|
||||
}
|
||||
|
||||
func (p *projection) shouldReduce(event *eventstore.StorageEvent) bool {
|
||||
shouldReduce := p.instance == "" || p.instance == event.Aggregate.Instance
|
||||
return shouldReduce && p.position.IsLess(event.Position)
|
||||
}
|
68
internal/v2/readmodel/org.go
Normal file
68
internal/v2/readmodel/org.go
Normal file
@ -0,0 +1,68 @@
|
||||
package readmodel
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/v2/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/v2/org"
|
||||
"github.com/zitadel/zitadel/internal/v2/projection"
|
||||
)
|
||||
|
||||
type Org struct {
|
||||
ID string
|
||||
Name string
|
||||
PrimaryDomain *projection.OrgPrimaryDomain
|
||||
State *projection.OrgState
|
||||
|
||||
Sequence uint32
|
||||
CreationDate time.Time
|
||||
ChangeDate time.Time
|
||||
Owner string
|
||||
}
|
||||
|
||||
func NewOrg(id string) *Org {
|
||||
return &Org{
|
||||
ID: id,
|
||||
State: projection.NewStateProjection(id),
|
||||
PrimaryDomain: projection.NewOrgPrimaryDomain(id),
|
||||
}
|
||||
}
|
||||
|
||||
func (rm *Org) Filter() []*eventstore.Filter {
|
||||
return []*eventstore.Filter{
|
||||
// we don't need the filters of the projections as we filter all events of the read model
|
||||
eventstore.NewFilter(
|
||||
eventstore.AppendAggregateFilter(
|
||||
org.AggregateType,
|
||||
eventstore.SetAggregateID(rm.ID),
|
||||
),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (rm *Org) Reduce(events ...*eventstore.StorageEvent) error {
|
||||
for _, event := range events {
|
||||
switch event.Type {
|
||||
case org.AddedType:
|
||||
added, err := org.AddedEventFromStorage(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rm.Name = added.Payload.Name
|
||||
rm.Owner = event.Aggregate.Owner
|
||||
rm.CreationDate = event.CreatedAt
|
||||
case org.ChangedType:
|
||||
changed, err := org.ChangedEventFromStorage(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rm.Name = changed.Payload.Name
|
||||
}
|
||||
rm.Sequence = event.Sequence
|
||||
rm.ChangeDate = event.CreatedAt
|
||||
}
|
||||
if err := rm.State.Reduce(events...); err != nil {
|
||||
return err
|
||||
}
|
||||
return rm.PrimaryDomain.Reduce(events...)
|
||||
}
|
15
internal/v2/readmodel/query.go
Normal file
15
internal/v2/readmodel/query.go
Normal file
@ -0,0 +1,15 @@
|
||||
package readmodel
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/v2/eventstore"
|
||||
)
|
||||
|
||||
type QueryOpt func(opts []eventstore.QueryOpt) []eventstore.QueryOpt
|
||||
|
||||
func WithTx(tx *sql.Tx) QueryOpt {
|
||||
return func(opts []eventstore.QueryOpt) []eventstore.QueryOpt {
|
||||
return append(opts, eventstore.SetQueryTx(tx))
|
||||
}
|
||||
}
|
@ -33,3 +33,25 @@ message FeatureFlag {
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message ImprovedPerformanceFeatureFlag {
|
||||
repeated ImprovedPerformance execution_paths = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "[1]";
|
||||
description: "Which of the performance improvements is enabled";
|
||||
}
|
||||
];
|
||||
|
||||
Source source = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "The source where the setting of the feature was defined. The source may be the resource itself or a resource owner through inheritance.";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
enum ImprovedPerformance {
|
||||
IMPROVED_PERFORMANCE_UNSPECIFIED = 0;
|
||||
// Uses the eventstore to query the org by id
|
||||
// instead of the sql table.
|
||||
IMPROVED_PERFORMANCE_ORG_BY_ID = 1;
|
||||
}
|
@ -49,6 +49,15 @@ message SetInstanceFeaturesRequest{
|
||||
description: "Actions allow to manage data executions and targets. If the flag is enabled, you'll be able to use the new API and its features. Note that it is still in an early stage.";
|
||||
}
|
||||
];
|
||||
|
||||
repeated ImprovedPerformance improved_performance = 7 [
|
||||
(validate.rules).repeated.unique = true,
|
||||
(validate.rules).repeated.items.enum = {defined_only: true, not_in: [0]},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "[1]";
|
||||
description: "Improves performance of specified execution paths.";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message SetInstanceFeaturesResponse {
|
||||
@ -113,4 +122,11 @@ message GetInstanceFeaturesResponse {
|
||||
description: "Actions v2 allow to manage data executions and targets. If the flag is enabled, you'll be able to use the new API and its features. Note that it is still in an early stage.";
|
||||
}
|
||||
];
|
||||
|
||||
ImprovedPerformanceFeatureFlag improved_performance = 8 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "[1]";
|
||||
description: "Improves performance of specified execution paths.";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
@ -46,13 +46,21 @@ message SetSystemFeaturesRequest{
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
optional bool actions = 6 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "true";
|
||||
description: "Actions allow to manage data executions and targets. If the flag is enabled, you'll be able to use the new API and its features. Note that it is still in an early stage.";
|
||||
}
|
||||
];
|
||||
|
||||
repeated ImprovedPerformance improved_performance = 7 [
|
||||
(validate.rules).repeated.unique = true,
|
||||
(validate.rules).repeated.items.enum = {defined_only: true, not_in: [0]},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "[1]";
|
||||
description: "Improves performance of specified execution paths.";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message SetSystemFeaturesResponse {
|
||||
@ -110,4 +118,11 @@ message GetSystemFeaturesResponse {
|
||||
description: "Actions v2 allow to manage data executions and targets. If the flag is enabled, you'll be able to use the new API and its features. Note that it is still in an early stage.";
|
||||
}
|
||||
];
|
||||
|
||||
ImprovedPerformanceFeatureFlag improved_performance = 8 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "[1]";
|
||||
description: "Improves performance of specified execution paths.";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user