From 85bdf015054185cc411e2f6ee31faa7792d64d1a Mon Sep 17 00:00:00 2001 From: Livio Spring Date: Thu, 14 Nov 2024 15:04:39 +0100 Subject: [PATCH] fix(actions): preserve order of execution (#8895) # Which Problems Are Solved The order of actions on a trigger was not respected on the execution and not correctly returned when retrieving the flow, for example in Console. The supposed correction of the order (e.g. in the UI) would then return a "no changes" error since the order was already as desired. # How the Problems Are Solved - Correctly order the actions of a trigger based on their configuration (`trigger_sequence`). # Additional Changes - replaced a `reflect.DeepEqual` with `slices.Equal` for checking the action list # Additional Context - reported by a customer - requires backports --- internal/command/org_flow.go | 4 ++-- internal/query/action_flow.go | 2 ++ internal/query/action_flow_test.go | 10 ++++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/internal/command/org_flow.go b/internal/command/org_flow.go index eff7a90286..24143aa96b 100644 --- a/internal/command/org_flow.go +++ b/internal/command/org_flow.go @@ -2,7 +2,7 @@ package command import ( "context" - "reflect" + "slices" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/repository/org" @@ -47,7 +47,7 @@ func (c *Commands) SetTriggerActions(ctx context.Context, flowType domain.FlowTy if err != nil { return nil, err } - if reflect.DeepEqual(existingFlow.Triggers[triggerType], actionIDs) { + if slices.Equal(existingFlow.Triggers[triggerType], actionIDs) { return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-Nfh52", "Errors.Flow.NoChanges") } if len(actionIDs) > 0 { diff --git a/internal/query/action_flow.go b/internal/query/action_flow.go index d6d4243d94..c5263d6c43 100644 --- a/internal/query/action_flow.go +++ b/internal/query/action_flow.go @@ -168,6 +168,7 @@ func prepareTriggerActionsQuery(ctx context.Context, db prepareDatabase) (sq.Sel ). From(flowsTriggersTable.name). LeftJoin(join(ActionColumnID, FlowsTriggersColumnActionID) + db.Timetravel(call.Took(ctx))). + OrderBy(FlowsTriggersColumnTriggerSequence.identifier()). PlaceholderFormat(sq.Dollar), func(rows *sql.Rows) ([]*Action, error) { actions := make([]*Action, 0) @@ -220,6 +221,7 @@ func prepareFlowQuery(ctx context.Context, db prepareDatabase, flowType domain.F ). From(flowsTriggersTable.name). LeftJoin(join(ActionColumnID, FlowsTriggersColumnActionID) + db.Timetravel(call.Took(ctx))). + OrderBy(FlowsTriggersColumnTriggerSequence.identifier()). PlaceholderFormat(sq.Dollar), func(rows *sql.Rows) (*Flow, error) { flow := &Flow{ diff --git a/internal/query/action_flow_test.go b/internal/query/action_flow_test.go index 75f1ed22b4..af0db27278 100644 --- a/internal/query/action_flow_test.go +++ b/internal/query/action_flow_test.go @@ -33,8 +33,9 @@ var ( ` projections.flow_triggers3.sequence,` + ` projections.flow_triggers3.resource_owner` + ` FROM projections.flow_triggers3` + - ` LEFT JOIN projections.actions3 ON projections.flow_triggers3.action_id = projections.actions3.id AND projections.flow_triggers3.instance_id = projections.actions3.instance_id` - // ` AS OF SYSTEM TIME '-1 ms'` + ` LEFT JOIN projections.actions3 ON projections.flow_triggers3.action_id = projections.actions3.id AND projections.flow_triggers3.instance_id = projections.actions3.instance_id` + + ` AS OF SYSTEM TIME '-1 ms'` + + ` ORDER BY projections.flow_triggers3.trigger_sequence` prepareFlowCols = []string{ "id", "creation_date", @@ -66,8 +67,9 @@ var ( ` projections.actions3.allowed_to_fail,` + ` projections.actions3.timeout` + ` FROM projections.flow_triggers3` + - ` LEFT JOIN projections.actions3 ON projections.flow_triggers3.action_id = projections.actions3.id AND projections.flow_triggers3.instance_id = projections.actions3.instance_id` - // ` AS OF SYSTEM TIME '-1 ms'` + ` LEFT JOIN projections.actions3 ON projections.flow_triggers3.action_id = projections.actions3.id AND projections.flow_triggers3.instance_id = projections.actions3.instance_id` + + ` AS OF SYSTEM TIME '-1 ms'` + + ` ORDER BY projections.flow_triggers3.trigger_sequence` prepareTriggerActionCols = []string{ "id",