This is an automated email from the ASF dual-hosted git repository. squakez pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 4a3d79d7b670c60ef9297edcae8353a2e94f65e4 Author: chaojixinren <[email protected]> AuthorDate: Thu Apr 16 17:01:06 2026 +0800 Remove factory indirection from controller action setup Update the remaining controllers that still stored action factories on the reconciler and rebuilt action slices during each reconcile. Integration, integrationkit, integrationplatform, and pipe now keep initialized action arrays directly on the struct, with integration selecting between the prebuilt synthetic and non-synthetic lists. Constraint: reviewer requested initialization-time action setup without an extra factory interface Rejected: keeping actionFactory on the reconciler | still recreates actions on each reconcile and preserves the unwanted indirection Confidence: high Scope-risk: narrow Reversibility: clean Directive: When controller actions are intended to be fixed at initialization time, store Action instances directly instead of factories Tested: go test ./pkg/controller/integration ./pkg/controller/integrationkit ./pkg/controller/pipe Tested: go test ./pkg/controller/integrationplatform -run TestActions Tested: go test ./pkg/controller/catalog Not-tested: full integrationplatform package in this environment (missing mvn) --- .../integration/integration_controller.go | 70 ++++++++++------------ .../integration/integration_controller_test.go | 52 +++++++++------- .../integrationkit/integrationkit_controller.go | 33 ++++------ .../integrationkit_controller_test.go | 30 ++++------ .../integrationplatform_controller.go | 31 +++------- .../integrationplatform_controller_test.go | 25 +++----- pkg/controller/pipe/pipe_controller.go | 29 +++------ pkg/controller/pipe/pipe_controller_test.go | 20 +++---- 8 files changed, 113 insertions(+), 177 deletions(-) diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go index 9c8e084d4..3f0b58084 100644 --- a/pkg/controller/integration/integration_controller.go +++ b/pkg/controller/integration/integration_controller.go @@ -58,8 +58,6 @@ import ( const retryMonitoring = 5 -type actionFactory func() Action - func Add(ctx context.Context, mgr manager.Manager, c client.Client) error { err := mgr.GetFieldIndexer().IndexField(ctx, &corev1.Pod{}, "status.phase", func(obj ctrl.Object) []string { @@ -81,20 +79,27 @@ func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler { client: c, scheme: mgr.GetScheme(), recorder: mgr.GetEventRecorder("camel-k-integration-controller"), - baseActionFactories: []actionFactory{ - NewPlatformSetupAction, - NewInitializeAction, - NewBuildAction, - newBuildKitAction, - NewBuildCompleteAction, - }, - syntheticActionFactories: []actionFactory{ - NewMonitorSyntheticAction, - }, - nonSyntheticActionFactories: []actionFactory{ - NewMonitorAction, - NewMonitorUnknownAction, - }, + syntheticActions: append( + []Action{ + NewPlatformSetupAction(), + NewInitializeAction(), + NewBuildAction(), + newBuildKitAction(), + NewBuildCompleteAction(), + }, + NewMonitorSyntheticAction(), + ), + nonSyntheticActions: append( + []Action{ + NewPlatformSetupAction(), + NewInitializeAction(), + NewBuildAction(), + newBuildKitAction(), + NewBuildCompleteAction(), + }, + NewMonitorAction(), + NewMonitorUnknownAction(), + ), }, schema.GroupVersionKind{ Group: v1.SchemeGroupVersion.Group, @@ -469,29 +474,11 @@ var _ reconcile.Reconciler = &reconcileIntegration{} type reconcileIntegration struct { // This client, initialized using mgr.Client() above, is a split client // that reads objects from the cache and writes to the API server - client client.Client - scheme *runtime.Scheme - recorder events.EventRecorder - baseActionFactories []actionFactory - syntheticActionFactories []actionFactory - nonSyntheticActionFactories []actionFactory -} - -func (r *reconcileIntegration) newActions(synthetic bool) []Action { - factories := make([]actionFactory, 0, len(r.baseActionFactories)+len(r.syntheticActionFactories)) - factories = append(factories, r.baseActionFactories...) - if synthetic { - factories = append(factories, r.syntheticActionFactories...) - } else { - factories = append(factories, r.nonSyntheticActionFactories...) - } - - actions := make([]Action, 0, len(factories)) - for _, newAction := range factories { - actions = append(actions, newAction()) - } - - return actions + client client.Client + scheme *runtime.Scheme + recorder events.EventRecorder + syntheticActions []Action + nonSyntheticActions []Action } // Reconcile reads that state of the cluster for an Integration object and makes changes based on the state read @@ -536,7 +523,10 @@ func (r *reconcileIntegration) Reconcile(ctx context.Context, request reconcile. target := instance.DeepCopy() targetLog := rlog.ForIntegration(target) - actions := r.newActions(instance.IsSynthetic()) + actions := r.nonSyntheticActions + if instance.IsSynthetic() { + actions = r.syntheticActions + } for _, a := range actions { a.InjectClient(r.client) diff --git a/pkg/controller/integration/integration_controller_test.go b/pkg/controller/integration/integration_controller_test.go index f019cac14..e6e2fe65b 100644 --- a/pkg/controller/integration/integration_controller_test.go +++ b/pkg/controller/integration/integration_controller_test.go @@ -24,26 +24,33 @@ import ( "github.com/stretchr/testify/require" ) -func TestNewActions(t *testing.T) { +func TestActions(t *testing.T) { reconciler := reconcileIntegration{ - baseActionFactories: []actionFactory{ - NewPlatformSetupAction, - NewInitializeAction, - NewBuildAction, - newBuildKitAction, - NewBuildCompleteAction, - }, - syntheticActionFactories: []actionFactory{ - NewMonitorSyntheticAction, - }, - nonSyntheticActionFactories: []actionFactory{ - NewMonitorAction, - NewMonitorUnknownAction, - }, + syntheticActions: append( + []Action{ + NewPlatformSetupAction(), + NewInitializeAction(), + NewBuildAction(), + newBuildKitAction(), + NewBuildCompleteAction(), + }, + NewMonitorSyntheticAction(), + ), + nonSyntheticActions: append( + []Action{ + NewPlatformSetupAction(), + NewInitializeAction(), + NewBuildAction(), + newBuildKitAction(), + NewBuildCompleteAction(), + }, + NewMonitorAction(), + NewMonitorUnknownAction(), + ), } t.Run("non-synthetic", func(t *testing.T) { - actions := reconciler.newActions(false) + actions := reconciler.nonSyntheticActions require.Len(t, actions, 7) assert.IsType(t, &platformSetupAction{}, actions[0]) @@ -53,18 +60,17 @@ func TestNewActions(t *testing.T) { assert.IsType(t, &buildCompleteAction{}, actions[4]) assert.IsType(t, &monitorAction{}, actions[5]) assert.IsType(t, &monitorUnknownAction{}, actions[6]) - - nextActions := reconciler.newActions(false) - assert.NotSame(t, actions[0], nextActions[0]) }) t.Run("synthetic", func(t *testing.T) { - actions := reconciler.newActions(true) + actions := reconciler.syntheticActions require.Len(t, actions, 6) + assert.IsType(t, &platformSetupAction{}, actions[0]) + assert.IsType(t, &initializeAction{}, actions[1]) + assert.IsType(t, &buildAction{}, actions[2]) + assert.IsType(t, &buildKitAction{}, actions[3]) + assert.IsType(t, &buildCompleteAction{}, actions[4]) assert.IsType(t, &monitorSyntheticAction{}, actions[5]) - - nextActions := reconciler.newActions(true) - assert.NotSame(t, actions[0], nextActions[0]) }) } diff --git a/pkg/controller/integrationkit/integrationkit_controller.go b/pkg/controller/integrationkit/integrationkit_controller.go index 95ece1c5c..ef62e16f1 100644 --- a/pkg/controller/integrationkit/integrationkit_controller.go +++ b/pkg/controller/integrationkit/integrationkit_controller.go @@ -48,8 +48,6 @@ const ( requeueAfterDuration = 2 * time.Second ) -type actionFactory func() Action - // Add creates a new IntegrationKit Controller and adds it to the Manager. The Manager will set fields on the Controller // and Start it when the Manager is Started. func Add(ctx context.Context, mgr manager.Manager, c client.Client) error { @@ -62,11 +60,11 @@ func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler { client: c, scheme: mgr.GetScheme(), recorder: mgr.GetEventRecorder("camel-k-integration-kit-controller"), - actionFactories: []actionFactory{ - NewInitializeAction, - NewBuildAction, - NewMonitorAction, - NewErrorAction, + actions: []Action{ + NewInitializeAction(), + NewBuildAction(), + NewMonitorAction(), + NewErrorAction(), }, }, schema.GroupVersionKind{ @@ -188,19 +186,10 @@ var _ reconcile.Reconciler = &reconcileIntegrationKit{} type reconcileIntegrationKit struct { // This client, initialized using mgr.Client() above, is a split client // that reads objects from the cache and writes to the API server - client client.Client - scheme *runtime.Scheme - recorder events.EventRecorder - actionFactories []actionFactory -} - -func (r *reconcileIntegrationKit) newActions() []Action { - actions := make([]Action, 0, len(r.actionFactories)) - for _, newAction := range r.actionFactories { - actions = append(actions, newAction()) - } - - return actions + client client.Client + scheme *runtime.Scheme + recorder events.EventRecorder + actions []Action } // Reconcile reads that state of the cluster for a IntegrationKit object and makes changes based on the state read @@ -281,11 +270,9 @@ func (r *reconcileIntegrationKit) Reconcile(ctx context.Context, request reconci return reconcile.Result{}, err } - actions := r.newActions() - targetPhase := instance.Status.Phase - for _, a := range actions { + for _, a := range r.actions { a.InjectClient(r.client) a.InjectLogger(targetLog) diff --git a/pkg/controller/integrationkit/integrationkit_controller_test.go b/pkg/controller/integrationkit/integrationkit_controller_test.go index 694aba5e0..af47229e4 100644 --- a/pkg/controller/integrationkit/integrationkit_controller_test.go +++ b/pkg/controller/integrationkit/integrationkit_controller_test.go @@ -24,27 +24,19 @@ import ( "github.com/stretchr/testify/require" ) -func TestNewActions(t *testing.T) { +func TestActions(t *testing.T) { reconciler := reconcileIntegrationKit{ - actionFactories: []actionFactory{ - NewInitializeAction, - NewBuildAction, - NewMonitorAction, - NewErrorAction, + actions: []Action{ + NewInitializeAction(), + NewBuildAction(), + NewMonitorAction(), + NewErrorAction(), }, } - actions := reconciler.newActions() - require.Len(t, actions, 4) - - assert.IsType(t, &initializeAction{}, actions[0]) - assert.IsType(t, &buildAction{}, actions[1]) - assert.IsType(t, &monitorAction{}, actions[2]) - assert.IsType(t, &errorAction{}, actions[3]) - - nextActions := reconciler.newActions() - assert.NotSame(t, actions[0], nextActions[0]) - assert.NotSame(t, actions[1], nextActions[1]) - assert.NotSame(t, actions[2], nextActions[2]) - assert.NotSame(t, actions[3], nextActions[3]) + require.Len(t, reconciler.actions, 4) + assert.IsType(t, &initializeAction{}, reconciler.actions[0]) + assert.IsType(t, &buildAction{}, reconciler.actions[1]) + assert.IsType(t, &monitorAction{}, reconciler.actions[2]) + assert.IsType(t, &errorAction{}, reconciler.actions[3]) } diff --git a/pkg/controller/integrationplatform/integrationplatform_controller.go b/pkg/controller/integrationplatform/integrationplatform_controller.go index bddf866f4..f03957026 100644 --- a/pkg/controller/integrationplatform/integrationplatform_controller.go +++ b/pkg/controller/integrationplatform/integrationplatform_controller.go @@ -40,8 +40,6 @@ import ( "github.com/apache/camel-k/v2/pkg/util/monitoring" ) -type actionFactory func() Action - // Add creates a new IntegrationPlatform Controller and adds it to the Manager. The Manager will set fields // on the Controller and Start it when the Manager is Started. func Add(ctx context.Context, mgr manager.Manager, c client.Client) error { @@ -55,10 +53,10 @@ func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler { reader: mgr.GetAPIReader(), scheme: mgr.GetScheme(), recorder: mgr.GetEventRecorder("camel-k-integration-platform-controller"), - actionFactories: []actionFactory{ - NewInitializeAction, - NewCreateAction, - NewMonitorAction, + actions: []Action{ + NewInitializeAction(), + NewCreateAction(), + NewMonitorAction(), }, }, schema.GroupVersionKind{ @@ -111,19 +109,10 @@ type reconcileIntegrationPlatform struct { // that reads objects from the cache and writes to the API server client client.Client // Non-caching client - reader ctrl.Reader - scheme *runtime.Scheme - recorder events.EventRecorder - actionFactories []actionFactory -} - -func (r *reconcileIntegrationPlatform) newActions() []Action { - actions := make([]Action, 0, len(r.actionFactories)) - for _, newAction := range r.actionFactories { - actions = append(actions, newAction()) - } - - return actions + reader ctrl.Reader + scheme *runtime.Scheme + recorder events.EventRecorder + actions []Action } // Reconcile reads that state of the cluster for a IntegrationPlatform object and makes changes based @@ -167,15 +156,13 @@ func (r *reconcileIntegrationPlatform) Reconcile(ctx context.Context, request re return reconcile.Result{}, nil } - actions := r.newActions() - var targetPhase v1.IntegrationPlatformPhase var err error target := instance.DeepCopy() targetLog := rlog.ForIntegrationPlatform(target) - for _, a := range actions { + for _, a := range r.actions { a.InjectClient(r.client) a.InjectLogger(targetLog) diff --git a/pkg/controller/integrationplatform/integrationplatform_controller_test.go b/pkg/controller/integrationplatform/integrationplatform_controller_test.go index 2497a5fe2..f06ab4698 100644 --- a/pkg/controller/integrationplatform/integrationplatform_controller_test.go +++ b/pkg/controller/integrationplatform/integrationplatform_controller_test.go @@ -24,24 +24,17 @@ import ( "github.com/stretchr/testify/require" ) -func TestNewActions(t *testing.T) { +func TestActions(t *testing.T) { reconciler := reconcileIntegrationPlatform{ - actionFactories: []actionFactory{ - NewInitializeAction, - NewCreateAction, - NewMonitorAction, + actions: []Action{ + NewInitializeAction(), + NewCreateAction(), + NewMonitorAction(), }, } - actions := reconciler.newActions() - require.Len(t, actions, 3) - - assert.IsType(t, &initializeAction{}, actions[0]) - assert.IsType(t, &createAction{}, actions[1]) - assert.IsType(t, &monitorAction{}, actions[2]) - - nextActions := reconciler.newActions() - assert.NotSame(t, actions[0], nextActions[0]) - assert.NotSame(t, actions[1], nextActions[1]) - assert.NotSame(t, actions[2], nextActions[2]) + require.Len(t, reconciler.actions, 3) + assert.IsType(t, &initializeAction{}, reconciler.actions[0]) + assert.IsType(t, &createAction{}, reconciler.actions[1]) + assert.IsType(t, &monitorAction{}, reconciler.actions[2]) } diff --git a/pkg/controller/pipe/pipe_controller.go b/pkg/controller/pipe/pipe_controller.go index e3130e92a..b5891c5cf 100644 --- a/pkg/controller/pipe/pipe_controller.go +++ b/pkg/controller/pipe/pipe_controller.go @@ -44,8 +44,6 @@ import ( "github.com/apache/camel-k/v2/pkg/util/monitoring" ) -type actionFactory func() Action - // Add creates a new Pipe Controller and adds it to the Manager. The Manager will set fields on the Controller // and Start it when the Manager is Started. func Add(ctx context.Context, mgr manager.Manager, c client.Client) error { @@ -58,9 +56,9 @@ func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler { client: c, scheme: mgr.GetScheme(), recorder: mgr.GetEventRecorder("camel-k-pipe-controller"), - actionFactories: []actionFactory{ - NewInitializeAction, - NewMonitorAction, + actions: []Action{ + NewInitializeAction(), + NewMonitorAction(), }, }, schema.GroupVersionKind{ @@ -138,19 +136,10 @@ var _ reconcile.Reconciler = &ReconcilePipe{} type ReconcilePipe struct { // This client, initialized using mgr.Client() above, is a split client // that reads objects from the cache and writes to the API server - client client.Client - scheme *runtime.Scheme - recorder events.EventRecorder - actionFactories []actionFactory -} - -func (r *ReconcilePipe) newActions() []Action { - actions := make([]Action, 0, len(r.actionFactories)) - for _, newAction := range r.actionFactories { - actions = append(actions, newAction()) - } - - return actions + client client.Client + scheme *runtime.Scheme + recorder events.EventRecorder + actions []Action } // Reconcile reads that state of the cluster for a Pipe object and makes changes based @@ -194,14 +183,12 @@ func (r *ReconcilePipe) Reconcile(ctx context.Context, request reconcile.Request return reconcile.Result{}, nil } - actions := r.newActions() - var err error target := instance.DeepCopy() targetLog := rlog.ForPipe(target) - for _, a := range actions { + for _, a := range r.actions { a.InjectClient(r.client) a.InjectLogger(targetLog) diff --git a/pkg/controller/pipe/pipe_controller_test.go b/pkg/controller/pipe/pipe_controller_test.go index 9772cd994..56dafa3bc 100644 --- a/pkg/controller/pipe/pipe_controller_test.go +++ b/pkg/controller/pipe/pipe_controller_test.go @@ -24,21 +24,15 @@ import ( "github.com/stretchr/testify/require" ) -func TestNewActions(t *testing.T) { +func TestActions(t *testing.T) { reconciler := ReconcilePipe{ - actionFactories: []actionFactory{ - NewInitializeAction, - NewMonitorAction, + actions: []Action{ + NewInitializeAction(), + NewMonitorAction(), }, } - actions := reconciler.newActions() - require.Len(t, actions, 2) - - assert.IsType(t, &initializeAction{}, actions[0]) - assert.IsType(t, &monitorAction{}, actions[1]) - - nextActions := reconciler.newActions() - assert.NotSame(t, actions[0], nextActions[0]) - assert.NotSame(t, actions[1], nextActions[1]) + require.Len(t, reconciler.actions, 2) + assert.IsType(t, &initializeAction{}, reconciler.actions[0]) + assert.IsType(t, &monitorAction{}, reconciler.actions[1]) }
