@@ -5,14 +5,98 @@ author: >-
55 [Attila Mészáros](https://github.com/csviri)
66---
77
8- We're pleased to announce the release of Java Operator SDK v5.5.0!
8+ We're pleased to announce the release of Java Operator SDK v5.5.0! This minor version reworks how
9+ the framework filters the events caused by a controller's own writes, making it more correct and
10+ more efficient, and exposes a richer, matcher-aware ` ResourceOperations ` API. There are ** no
11+ breaking API changes** , but there is one behavioral change around ` UpdateControl ` — see the
12+ migration notes.
913
1014## Key Features
1115
16+ ### Matcher-based updates in ` ResourceOperations `
17+
18+ ` ResourceOperations ` (available from the reconciliation ` Context ` via ` context.resourceOperations() ` )
19+ now offers a complete, consistent family of update/patch/create methods for every write strategy —
20+ ** server-side apply, update (PUT), JSON Patch (RFC 6902) and JSON Merge Patch (RFC 7386)** — each
21+ available for the whole resource and the ` status ` subresource, and with dedicated ` primary `
22+ variants.
23+
24+ Every method comes in two flavors: a default one, and one taking an ` Options ` argument that controls
25+ how the resulting own event is handled:
26+
27+ ``` java
28+ public UpdateControl<WebPage > reconcile(WebPage webPage, Context<WebPage > context) {
29+ makeStatusChanges(webPage);
30+ // updates the status, filters the own event, and skips the write entirely if nothing changed
31+ context. resourceOperations(). serverSideApplyPrimaryStatus(webPage);
32+ return UpdateControl . noUpdate();
33+ }
34+ ```
35+
36+ By default these operations ** match the desired state against the actual (cached) state before
37+ writing** : if they already match, the write is skipped; otherwise the write is performed and its own
38+ event is filtered. This is the most efficient option — it covers full event filtering * and* avoids a
39+ request to the Kubernetes API server when nothing changed. Default matchers are provided for every
40+ operation type; when one does not fit, supply your own via ` Options.matchAndFilter(matcher) ` .
41+
42+ ` Options ` exposes the available strategies:
43+
44+ - ` matchAndFilter(...) ` / ` matchAndFilterWithDefaultMatcher(...) ` — match, then write-and-filter only
45+ if needed (the default).
46+ - ` filterIfOptimisticLocking() ` — filter the own event only when the write uses optimistic locking,
47+ otherwise just cache the response.
48+ - ` cacheOnly() ` — only cache the response (read-cache-after-write consistency), no filtering.
49+ - ` forceFilterEvents() ` — always filter (mostly internal usage).
50+
51+ > ** Correctness note** : filtering an own event is only safe if the framework can tell an own write
52+ > apart from a concurrent third-party write. This requires ** either** a matcher ** or** optimistic
53+ > locking; otherwise a concurrent external update inside the filter window may be missed until the
54+ > next resync.
55+
56+ ### More correct own-event filtering (no-op update edge case)
57+
58+ The read-cache-after-write own-event filter has been reworked to fix an edge case where a legitimate
59+ external change could be filtered out together with a controller's own ** no-op** update — for
60+ example, when the spec was changed externally while the controller patched its status and that status
61+ patch turned out to be a no-op. The new matcher-based operations avoid issuing such no-op writes in
62+ the first place, and the filtering itself is now correct in these concurrent scenarios.
63+
1264## Additional Improvements
1365
66+ - ** ` GenericKubernetesResourceMatcher.matchStatus(...) ` ** : a status-only counterpart to ` match(...) `
67+ that compares just the ` /status ` subtree.
68+ - ** New ` Matcher ` SPI** : ` io.javaoperatorsdk.operator.api.reconciler.matcher.Matcher ` lets you plug a
69+ custom matching strategy into ` Options.matchAndFilter(...) ` .
70+ - Extensive integration tests covering every ` ResourceOperations ` update/patch operation (primary,
71+ status, and secondary resources) against a real cluster.
72+
1473## Migration Notes
1574
75+ There are ** no breaking API changes** ; existing code compiles and runs unchanged. However:
76+
77+ ### ` UpdateControl ` no longer filters own events by default
78+
79+ Returning an ` UpdateControl ` (or ` ErrorStatusUpdateControl ` ) still updates the resource and keeps the
80+ cache read-after-write consistent, but it ** no longer filters the resulting own event by default** —
81+ so the write may cause an additional (idempotent) reconciliation. This change fixes correctness edge
82+ cases where an event that should have propagated was previously swallowed.
83+
84+ If you relied on the previous filtering, perform the update through ` ResourceOperations ` and return
85+ ` UpdateControl.noUpdate() ` :
86+
87+ ``` java
88+ // before (v5.4)
89+ resource. setStatus(new MyStatus (). setReady(true ));
90+ return UpdateControl . patchStatus(resource);
91+
92+ // after (v5.5) — filter the own event explicitly
93+ resource. setStatus(new MyStatus (). setReady(true ));
94+ context. resourceOperations(). serverSideApplyPrimaryStatus(resource);
95+ return UpdateControl . noUpdate();
96+ ```
97+
98+ See the [ migration guide] ( /docs/migration/v5-5-migration ) for details.
99+
16100## Getting Started
17101
18102``` xml
0 commit comments