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
This commit is contained in:
Livio Spring 2024-11-14 15:04:39 +01:00 committed by GitHub
parent b77901cb4b
commit 85bdf01505
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 10 additions and 6 deletions

View File

@ -2,7 +2,7 @@ package command
import ( import (
"context" "context"
"reflect" "slices"
"github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/repository/org" "github.com/zitadel/zitadel/internal/repository/org"
@ -47,7 +47,7 @@ func (c *Commands) SetTriggerActions(ctx context.Context, flowType domain.FlowTy
if err != nil { if err != nil {
return nil, err 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") return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-Nfh52", "Errors.Flow.NoChanges")
} }
if len(actionIDs) > 0 { if len(actionIDs) > 0 {

View File

@ -168,6 +168,7 @@ func prepareTriggerActionsQuery(ctx context.Context, db prepareDatabase) (sq.Sel
). ).
From(flowsTriggersTable.name). From(flowsTriggersTable.name).
LeftJoin(join(ActionColumnID, FlowsTriggersColumnActionID) + db.Timetravel(call.Took(ctx))). LeftJoin(join(ActionColumnID, FlowsTriggersColumnActionID) + db.Timetravel(call.Took(ctx))).
OrderBy(FlowsTriggersColumnTriggerSequence.identifier()).
PlaceholderFormat(sq.Dollar), PlaceholderFormat(sq.Dollar),
func(rows *sql.Rows) ([]*Action, error) { func(rows *sql.Rows) ([]*Action, error) {
actions := make([]*Action, 0) actions := make([]*Action, 0)
@ -220,6 +221,7 @@ func prepareFlowQuery(ctx context.Context, db prepareDatabase, flowType domain.F
). ).
From(flowsTriggersTable.name). From(flowsTriggersTable.name).
LeftJoin(join(ActionColumnID, FlowsTriggersColumnActionID) + db.Timetravel(call.Took(ctx))). LeftJoin(join(ActionColumnID, FlowsTriggersColumnActionID) + db.Timetravel(call.Took(ctx))).
OrderBy(FlowsTriggersColumnTriggerSequence.identifier()).
PlaceholderFormat(sq.Dollar), PlaceholderFormat(sq.Dollar),
func(rows *sql.Rows) (*Flow, error) { func(rows *sql.Rows) (*Flow, error) {
flow := &Flow{ flow := &Flow{

View File

@ -33,8 +33,9 @@ var (
` projections.flow_triggers3.sequence,` + ` projections.flow_triggers3.sequence,` +
` projections.flow_triggers3.resource_owner` + ` projections.flow_triggers3.resource_owner` +
` FROM projections.flow_triggers3` + ` 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` ` 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'` ` AS OF SYSTEM TIME '-1 ms'` +
` ORDER BY projections.flow_triggers3.trigger_sequence`
prepareFlowCols = []string{ prepareFlowCols = []string{
"id", "id",
"creation_date", "creation_date",
@ -66,8 +67,9 @@ var (
` projections.actions3.allowed_to_fail,` + ` projections.actions3.allowed_to_fail,` +
` projections.actions3.timeout` + ` projections.actions3.timeout` +
` FROM projections.flow_triggers3` + ` 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` ` 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'` ` AS OF SYSTEM TIME '-1 ms'` +
` ORDER BY projections.flow_triggers3.trigger_sequence`
prepareTriggerActionCols = []string{ prepareTriggerActionCols = []string{
"id", "id",