Skip to content

fix: use the null-guarded metrics field in the Controller constructor - #3531

Merged
csviri merged 1 commit into
operator-framework:mainfrom
csviri:fix/controller-null-metrics-guard
Aug 3, 2026
Merged

fix: use the null-guarded metrics field in the Controller constructor#3531
csviri merged 1 commit into
operator-framework:mainfrom
csviri:fix/controller-null-metrics-guard

Conversation

@csviri

@csviri csviri commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

The constructor deliberately guards against a null Metrics:

this.metrics = Optional.ofNullable(configurationService.getMetrics()).orElse(Metrics.NOOP);

but its last statement bypasses that guard and calls the getter again:

configurationService.getMetrics().controllerRegistered(this);

so a ConfigurationService whose getMetrics() returns null fails with a
NullPointerException during controller construction, which is exactly what
the guard three lines up is meant to prevent. EventProcessor applies the
same != null ? metrics : Metrics.NOOP guard, so the codebase does treat
a null Metrics as reachable even though the interface default returns
Metrics.NOOP.

Uses the already-resolved metrics field instead.

Part of #3517

Copilot AI review requested due to automatic review settings July 30, 2026 09:05
@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 30, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a controller-construction correctness bug in operator-framework-core where the constructor would bypass the null-guarded metrics field and re-fetch Metrics from ConfigurationService, causing a potential NullPointerException when getMetrics() returns null.

Changes:

  • Use the already null-guarded metrics field to call controllerRegistered(this) instead of calling configurationService.getMetrics() again.

@csviri csviri left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@csviri
csviri marked this pull request as ready for review August 3, 2026 08:01
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Aug 3, 2026
@openshift-ci
openshift-ci Bot requested review from metacosm and xstefank August 3, 2026 08:02
The constructor deliberately guards against a null `Metrics`:

    this.metrics = Optional.ofNullable(configurationService.getMetrics()).orElse(Metrics.NOOP);

but its last statement bypasses that guard and calls the getter again:

    configurationService.getMetrics().controllerRegistered(this);

so a `ConfigurationService` whose `getMetrics()` returns null fails with a
NullPointerException during controller construction, which is exactly what
the guard three lines up is meant to prevent. `EventProcessor` applies the
same `!= null ? metrics : Metrics.NOOP` guard, so the codebase does treat
a null `Metrics` as reachable even though the interface default returns
`Metrics.NOOP`.

Uses the already-resolved `metrics` field instead.
Copilot AI review requested due to automatic review settings August 3, 2026 08:02
@csviri
csviri force-pushed the fix/controller-null-metrics-guard branch from 40c0890 to 24dc42b Compare August 3, 2026 08:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (1)

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/Controller.java:141

  • Consider adding a regression unit test covering the original failure mode: a ConfigurationService implementation whose getMetrics() returns null should not throw during Controller construction (and should behave as if Metrics.NOOP was used). There are existing Controller tests in this module, but none exercise the null-metrics path.
    metrics.controllerRegistered(this);

@csviri
csviri merged commit 7c8e197 into operator-framework:main Aug 3, 2026
28 checks passed
csviri added a commit to csviri/java-operator-sdk that referenced this pull request Aug 3, 2026
…operator-framework#3531)

The constructor deliberately guards against a null `Metrics`:

    this.metrics = Optional.ofNullable(configurationService.getMetrics()).orElse(Metrics.NOOP);

but its last statement bypasses that guard and calls the getter again:

    configurationService.getMetrics().controllerRegistered(this);

so a `ConfigurationService` whose `getMetrics()` returns null fails with a
NullPointerException during controller construction, which is exactly what
the guard three lines up is meant to prevent. `EventProcessor` applies the
same `!= null ? metrics : Metrics.NOOP` guard, so the codebase does treat
a null `Metrics` as reachable even though the interface default returns
`Metrics.NOOP`.

Uses the already-resolved `metrics` field instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants