| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
There was a problem hiding this comment.
Fixes a NullPointerException in ExternalResourceCachingEventSource when only a generic filter is configured (no add/delete/update-specific filter), ensuring add/delete/update paths remain null-safe and behave as before when specific filters are present.
Changes:
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSource.java | Prevents NPE by making specific filter invocation null-safe in add/delete/update acceptance logic. |
| operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSourceTest.java | Adds regression coverage for generic-filter-only configurations across add/delete/update branches. |
Sorry, something went wrong.
| var anyAddAccepted = | ||
| addedResources.values().stream() | ||
| .anyMatch(r -> acceptedByGenericFiler(r) && onAddFilter.accept(r)); | ||
| .anyMatch(r -> acceptedByGenericFiler(r) && acceptedByOnAddFilter(r)); |
There was a problem hiding this comment.
LGTM
Sorry, something went wrong.
…c filter is set
`acceptedByFiler` guards each of its three filter branches with
`onXFilter != null || genericFilter != null`, but the branch body
dereferences `onXFilter` unconditionally:
if (onAddFilter != null || genericFilter != null) {
... .anyMatch(r -> acceptedByGenericFiler(r) && onAddFilter.accept(r));
So configuring only a generic filter via `setGenericFilter(...)` throws a
NullPointerException as soon as a resource is added, deleted or updated.
All three branches (add / delete / update) are affected, which means
`PollingEventSource`, `PerResourcePollingEventSource` and
`CachingInboundEventSource` all break when used with a generic filter
only.
The existing `genericFilteringEvents` test missed this because it uses a
filter that returns `false`: `&&` short-circuits before the null
dereference. Only a generic filter that accepts a resource reaches the
NPE.
Each filter check is now null-safe (an absent filter accepts), which
preserves the previous behaviour whenever the specific filter is set.
Adds three regression tests, one per branch; they fail with
NullPointerException without this change.
…c filter is set (operator-framework#3518) `acceptedByFiler` guards each of its three filter branches with `onXFilter != null || genericFilter != null`, but the branch body dereferences `onXFilter` unconditionally: if (onAddFilter != null || genericFilter != null) { ... .anyMatch(r -> acceptedByGenericFiler(r) && onAddFilter.accept(r)); So configuring only a generic filter via `setGenericFilter(...)` throws a NullPointerException as soon as a resource is added, deleted or updated. All three branches (add / delete / update) are affected, which means `PollingEventSource`, `PerResourcePollingEventSource` and `CachingInboundEventSource` all break when used with a generic filter only. The existing `genericFilteringEvents` test missed this because it uses a filter that returns `false`: `&&` short-circuits before the null dereference. Only a generic filter that accepts a resource reaches the NPE. Each filter check is now null-safe (an absent filter accepts), which preserves the previous behaviour whenever the specific filter is set. Adds three regression tests, one per branch; they fail with NullPointerException without this change. Signed-off-by: Attila Mészáros <a_meszaros@apple.com> # Conflicts: # operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSourceTest.java
…c filter is set (operator-framework#3518) `acceptedByFiler` guards each of its three filter branches with `onXFilter != null || genericFilter != null`, but the branch body dereferences `onXFilter` unconditionally: if (onAddFilter != null || genericFilter != null) { ... .anyMatch(r -> acceptedByGenericFiler(r) && onAddFilter.accept(r)); So configuring only a generic filter via `setGenericFilter(...)` throws a NullPointerException as soon as a resource is added, deleted or updated. All three branches (add / delete / update) are affected, which means `PollingEventSource`, `PerResourcePollingEventSource` and `CachingInboundEventSource` all break when used with a generic filter only. The existing `genericFilteringEvents` test missed this because it uses a filter that returns `false`: `&&` short-circuits before the null dereference. Only a generic filter that accepts a resource reaches the NPE. Each filter check is now null-safe (an absent filter accepts), which preserves the previous behaviour whenever the specific filter is set. Adds three regression tests, one per branch; they fail with NullPointerException without this change. Signed-off-by: Attila Mészáros <a_meszaros@apple.com> # Conflicts: # operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSourceTest.java
…3524) * fix: read the external resource cache under the event source monitor `ExternalResourceCachingEventSource` mutates its cache from `synchronized` methods (`handleResources`, `handleDelete`, `handleRecentResourceCreate/Update`), but the read paths were not synchronized. The outer map is a `ConcurrentHashMap`; the nested per-primary maps are plain `HashMap`s that `handleDelete` mutates in place, so a reconciler thread reading them while a poll or informer thread writes can observe a corrupted map or throw. `getSecondaryResources(ResourceID)` additionally looked the primary up twice: var cachedValues = cache.get(primaryID); if (cachedValues == null) { return Collections.emptySet(); } else { return new HashSet<>(cache.get(primaryID).values()); } If a concurrent `handleDelete` removes the entry between the two calls, the second `get` returns null and this throws a NullPointerException. Adds a `cachedResourcesFor` helper that snapshots the cached resources while holding the monitor, and routes `getSecondaryResources` plus the `PerResourcePollingEventSource` and `CachingInboundEventSource` overrides (and `checkAndRegisterTask`) through it. The helper only copies, so the potentially slow `ResourceFetcher` calls in those overrides still run outside the lock and cannot block the informer or poll threads. `getCache()` still returns a live view for backwards compatibility, but now documents that iterating the nested maps requires synchronizing on the event source. Adds a test asserting `getSecondaryResources` returns a snapshot rather than a live view. * fix: NPE in external resource caching event source when only a generic filter is set (#3518) `acceptedByFiler` guards each of its three filter branches with `onXFilter != null || genericFilter != null`, but the branch body dereferences `onXFilter` unconditionally: if (onAddFilter != null || genericFilter != null) { ... .anyMatch(r -> acceptedByGenericFiler(r) && onAddFilter.accept(r)); So configuring only a generic filter via `setGenericFilter(...)` throws a NullPointerException as soon as a resource is added, deleted or updated. All three branches (add / delete / update) are affected, which means `PollingEventSource`, `PerResourcePollingEventSource` and `CachingInboundEventSource` all break when used with a generic filter only. The existing `genericFilteringEvents` test missed this because it uses a filter that returns `false`: `&&` short-circuits before the null dereference. Only a generic filter that accepts a resource reaches the NPE. Each filter check is now null-safe (an absent filter accepts), which preserves the previous behaviour whenever the specific filter is set. Adds three regression tests, one per branch; they fail with NullPointerException without this change. Signed-off-by: Attila Mészáros <a_meszaros@apple.com> # Conflicts: # operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSourceTest.java --------- Signed-off-by: Attila Mészáros <a_meszaros@apple.com>
| Back | FazBrowse Home | New Git URL |
acceptedByFiler guards each of its three filter branches with
onXFilter != null || genericFilter != null, but the branch body
dereferences onXFilter unconditionally:
if (onAddFilter != null || genericFilter != null) { ... .anyMatch(r -> acceptedByGenericFiler(r) && onAddFilter.accept(r));So configuring only a generic filter via setGenericFilter(...) throws a
NullPointerException as soon as a resource is added, deleted or updated.
All three branches (add / delete / update) are affected, which means
PollingEventSource, PerResourcePollingEventSource and
CachingInboundEventSource all break when used with a generic filter
only.
The existing genericFilteringEvents test missed this because it uses a
filter that returns false: && short-circuits before the null
dereference. Only a generic filter that accepts a resource reaches the
NPE.
Each filter check is now null-safe (an absent filter accepts), which
preserves the previous behaviour whenever the specific filter is set.
Adds three regression tests, one per branch; they fail with
NullPointerException without this change.
Part of #3517