-
Notifications
You must be signed in to change notification settings - Fork 236
NoEventSourceForClassException thrown intermittently when BulkDependentResource with activationCondition is downstream of a failing reconcilePrecondition #3249
Description
Observed Behaviour
While testing kroxylicious/kroxylicious#3399, which adds a BulkDependentResource with an activationCondition to the Kroxylicious operator workflow, we observed intermittent NoEventSourceForClassException appearing in operator logs during normal operation. The exception is not caused by misconfiguration — it occurs under a specific workflow execution path.
The stack trace observed:
NoEventSourceForClassException
at EventSources.get(EventSources.java:125)
at EventSourceManager.getEventSourceFor(EventSourceManager.java:272)
at ClusterRouteDependentResource.getSecondaryResources(...)
at BulkDependentResourceReconciler.delete(BulkDependentResourceReconciler.java:71)
at AbstractDependentResource.delete(AbstractDependentResource.java:216)
at WorkflowReconcileExecutor$NodeDeleteExecutor.doRun(WorkflowReconcileExecutor.java:192)
Investigation
We believe the cause is that NodeDeleteExecutor.doRun() does not call registerOrDeregisterEventSourceBasedOnActivation() before invoking delete(), whereas NodeReconcileExecutor.doRun() does.
When a parent dependent's reconcilePrecondition fails, handleReconcileOrActivationConditionNotMet() calls markDependentsForDelete(), cascading NodeDeleteExecutor to all downstream dependents — including any child with an activationCondition. If NodeReconcileExecutor has never run for that child (e.g. on first reconciliation), the event source was never registered. The subsequent call to getSecondaryResources() inside delete() then attempts to retrieve the unregistered event source and throws.
The specific workflow that triggered this in Kroxylicious:
CONFIG_STATE_DEP
└── CONFIG_DEP (reconcilePrecondition: ProxyConfigReconcilePrecondition)
└── DEPLOYMENT_DEP
└── CLUSTERS_DEP
└── ROUTES_DEP (activationCondition: IsOpenshiftRouteSupportedActivationCondition)
On first reconciliation with no VirtualKafkaCluster present, ProxyConfigReconcilePrecondition fails → markDependentsForDelete cascades all the way to ROUTES_DEP → NodeDeleteExecutor fires for ROUTES_DEP → event source never registered → exception.
Reproducer
We have a minimal failing integration test that demonstrates the bug with a two-node workflow:
ConfigMapDependentResource (reconcilePrecondition = ALWAYS_FALSE)
└── SecretBulkDependentResource (activationCondition = ALWAYS_TRUE)
Available on my fork: https://github.com/SamBarker/java-operator-sdk/tree/bulk-activation-condition-reproducer