fix: assorted robustness and clarity fixes - #3533
Open
csviri wants to merge 1 commit into
Open
Conversation
Three unrelated small items found while auditing. ManagedInformerEventSource.get could throw instead of falling back to the informer cache. It compared a temporary-cache hit against `manager().lastSyncResourceVersion(namespace)` without guarding either failure mode: * `lastSyncResourceVersion` is null until an informer has completed its initial list, and `compareResourceVersions` dereferences it, so this threw a NullPointerException. * `InformerManager.lastSyncResourceVersion` does `getSource(ns) .orElseThrow()`, which throws `NoSuchElementException` for a namespace that is no longer watched after a dynamic namespace change - a window that only closes on the next re-list, when `checkGhostResources` prunes the entry. `TemporaryResourceCache.putResource` already guards the null case; the comparison is now extracted into a helper that guards both and falls back to the informer cache, which is the safe answer in either case. ExpectationResult.name() threw a bare NullPointerException when no expectation was registered, which is a normal result state produced by `ExpectationManager.checkExpectation`. It now throws `IllegalStateException` pointing at `isExpectationPresent()`, and says so in the javadoc. ResourceOperations cleanups: drops the `options` parameter of `desiredForJsonPatch`, which was never read at any of its six call sites, and rewrites the comment on `create` - it claimed the operation "check if the resource already exists", which it does not; the actual reason filtering is safe is that the API server rejects a duplicate create.
16 tasks
Contributor
There was a problem hiding this comment.
Pull request overview
This PR delivers a small set of robustness and clarity improvements across the operator framework core, primarily addressing edge cases in informer cache reads, improving error reporting for missing expectations, and simplifying internal patch helper APIs.
Changes:
- Prevent
ManagedInformerEventSource.getfrom throwing when last-sync resource versions are unavailable or namespaces are no longer watched, preferring the informer cache in those cases. - Improve
ExpectationResult.name()behavior and documentation by throwing a descriptiveIllegalStateExceptionwhen no expectation is present. - Clean up
ResourceOperationsby removing an unused internal parameter and correcting/improving create-event-filtering comments.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/expectation/ExpectationResult.java | Adds a guard + clearer exception and Javadoc for name() when no expectation is registered. |
| operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/ManagedInformerEventSource.java | Extracts resource-version comparison into a helper and adds guards to fall back to informer cache in problematic cases. |
| operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceOperations.java | Removes an unused internal parameter from JSON patch desired-state creation and clarifies create filtering comments. |
Comment on lines
+248
to
+256
| private boolean isLaterThanLastSyncResourceVersion(R resource) { | ||
| var namespace = resource.getMetadata().getNamespace(); | ||
| if (!manager().isWatchingNamespace(namespace)) { | ||
| return false; | ||
| } | ||
| var lastSyncResourceVersion = manager().lastSyncResourceVersion(namespace); | ||
| if (lastSyncResourceVersion == null) { | ||
| return false; | ||
| } |
csviri
marked this pull request as ready for review
July 31, 2026 08:06
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three unrelated small items found while auditing.
ManagedInformerEventSource.get could throw instead of falling back to the
informer cache. It compared a temporary-cache hit against
manager().lastSyncResourceVersion(namespace)without guarding eitherfailure mode:
lastSyncResourceVersionis null until an informer has completed itsinitial list, and
compareResourceVersionsdereferences it, so thisthrew a NullPointerException.
InformerManager.lastSyncResourceVersiondoesgetSource(ns) .orElseThrow(), which throwsNoSuchElementExceptionfor a namespacethat is no longer watched after a dynamic namespace change - a window
that only closes on the next re-list, when
checkGhostResourcesprunesthe entry.
TemporaryResourceCache.putResourcealready guards the null case; thecomparison is now extracted into a helper that guards both and falls back
to the informer cache, which is the safe answer in either case.
ExpectationResult.name() threw a bare NullPointerException when no
expectation was registered, which is a normal result state produced by
ExpectationManager.checkExpectation. It now throwsIllegalStateExceptionpointing atisExpectationPresent(), and says soin the javadoc.
ResourceOperations cleanups: drops the
optionsparameter ofdesiredForJsonPatch, which was never read at any of its six call sites,and rewrites the comment on
create- it claimed the operation "check ifthe resource already exists", which it does not; the actual reason
filtering is safe is that the API server rejects a duplicate create.
Part of #3517