Skip to content

Commit 295e907

Browse files
committed
impl
1 parent a65efc7 commit 295e907

File tree

5 files changed

+112
-21
lines changed

5 files changed

+112
-21
lines changed

docs/_sass/uikit/components/grid-masonry.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ $grid-gap-large: $global-large-gutter !default;
6161
/* Item Span
6262
========================================================================== */
6363

64-
// TODO Fix implicit tracks if span is too large
6564
.uk-grid-item-span-2 { grid-column-start: span 2; }
6665
.uk-grid-item-span-3 { grid-column-start: span 3; }
6766
.uk-grid-item-span-4 { grid-column-start: span 4; }

docs/assets/js/uikit.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8223,7 +8223,6 @@
82238223

82248224
};
82258225

8226-
// TODO improve isToggled handling
82278226
function isToggled(target, cls) {
82288227
return cls
82298228
? hasClass(target, cls.split(' ')[0])

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/UpdateControl.java

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,21 @@ public static <T extends HasMetadata> UpdateControl<T> updateResourceIfChanged(T
5353
* "https://github.com/fabric8io/kubernetes-client/issues/4158">https://github.com/fabric8io/kubernetes-client/issues/4158</a>
5454
*
5555
* @param <T> resource type
56-
* @param customResource the custom resource with target status
56+
* @param customResource the resource with target status
5757
* @return UpdateControl instance
5858
*/
5959
public static <T extends HasMetadata> UpdateControl<T> patchStatus(T customResource) {
6060
return new UpdateControl<>(customResource, true, false, true, false);
6161
}
6262

63+
/**
64+
* Patches status only if it not equals to original status. It uses equals method to compare the
65+
* two. Only for custom resources.
66+
*
67+
* @param customResource the resource with target status
68+
* @param <T> resource type
69+
* @return UpdateControl instance
70+
*/
6371
public static <T extends HasMetadata> UpdateControl<T> patchStatusIfChanged(T customResource) {
6472
return new UpdateControl<>(customResource, true, false, true, true);
6573
}
@@ -80,8 +88,16 @@ public static <T extends HasMetadata> UpdateControl<T> updateStatus(T customReso
8088
return new UpdateControl<>(customResource, true, false, false, false);
8189
}
8290

91+
/**
92+
* Updates status only if it not equals to original status. It uses equals method to compare the
93+
* two. Only for custom resources.
94+
*
95+
* @param <T> resource type
96+
* @param customResource the custom resource with target status
97+
* @return UpdateControl instance
98+
*/
8399
public static <T extends HasMetadata> UpdateControl<T> updateStatusIfChanged(T customResource) {
84-
return new UpdateControl<>(customResource, true, false, false, false);
100+
return new UpdateControl<>(customResource, true, false, false, true);
85101
}
86102

87103
/**
@@ -97,16 +113,58 @@ public static <T extends HasMetadata> UpdateControl<T> updateResourceAndStatus(
97113
return new UpdateControl<>(customResource, true, true, false, false);
98114
}
99115

116+
/**
117+
* Same as updateResourceAndStatus, only does the update requests if resource are changed.
118+
* Resources are compared using equals method. Only for custom resources.
119+
*
120+
* @param <T> resource type
121+
* @param customResource - custom resource to use in both API calls
122+
* @return UpdateControl instance
123+
*/
100124
public static <T extends HasMetadata> UpdateControl<T> updateResourceAndStatusIfChanged(
101125
T customResource) {
102126
return new UpdateControl<>(customResource, true, true, false, true);
103127
}
104128

129+
/**
130+
* As a results of this there will be two call to K8S API. First the custom resource will be
131+
* updated then the status sub-resource patched. The patch does not use optimistic locking.
132+
*
133+
* @param <T> resource type
134+
* @param customResource - custom resource to use in both API calls
135+
* @return UpdateControl instance
136+
*/
137+
@Deprecated(forRemoval = true)
105138
public static <T extends HasMetadata> UpdateControl<T> patchResourceAndStatus(
106139
T customResource) {
107140
return new UpdateControl<>(customResource, true, true, true, false);
108141
}
109142

143+
/**
144+
* As a results of this there will be two call to K8S API. First the custom resource will be
145+
* patched then the status sub-resource. The patch does not use optimistic locking.
146+
*
147+
* @param <T> resource type
148+
* @param customResource - custom resource to use in both API calls
149+
* @return UpdateControl instance
150+
*/
151+
public static <T extends HasMetadata> UpdateControl<T> updateResourceAndPatchStatus(
152+
T customResource) {
153+
return new UpdateControl<>(customResource, true, true, true, false);
154+
}
155+
156+
/**
157+
* Same as patchResourceAndStatus, only does the update requests if resource are changed.
158+
* Resources are compared using equals method. Only for custom resources.
159+
*
160+
* @param <T> resource type
161+
* @param customResource - custom resource to use in both API calls
162+
* @return UpdateControl instance
163+
*/
164+
public static <T extends HasMetadata> UpdateControl<T> updateResourceAndPatchStatusIfChanged(
165+
T customResource) {
166+
return new UpdateControl<>(customResource, true, true, true, true);
167+
}
110168

111169
public static <T extends HasMetadata> UpdateControl<T> noUpdate() {
112170
return new UpdateControl<>(null, false, false, false, false);
@@ -136,7 +194,7 @@ public boolean isUpdateResourceAndStatus() {
136194
return updateResource && updateStatus;
137195
}
138196

139-
public boolean isOnlyOnChange() {
197+
public boolean onlyOnChange() {
140198
return onlyOnChange;
141199
}
142200
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcher.java

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.javaoperatorsdk.operator.processing.event;
22

3+
import java.util.Optional;
34
import org.slf4j.Logger;
45
import org.slf4j.LoggerFactory;
56

@@ -128,35 +129,39 @@ private PostExecutionControl<R> reconcileExecution(ExecutionScope<R> executionSc
128129
executionScope);
129130

130131
UpdateControl<R> updateControl = controller.reconcile(resourceForExecution, context);
131-
R updatedCustomResource = null;
132+
Optional<R> updatedCustomResource = Optional.empty();
132133
if (updateControl.isUpdateResourceAndStatus()) {
133134
updatedCustomResource =
134-
updateCustomResource(updateControl.getResource());
135-
updateControl
135+
updateCustomResource(updateControl.getResource(), originalResource,
136+
updateControl.onlyOnChange());
137+
updatedCustomResource.ifPresent(cr -> updateControl
136138
.getResource()
137139
.getMetadata()
138-
.setResourceVersion(updatedCustomResource.getMetadata().getResourceVersion());
140+
.setResourceVersion(cr.getMetadata().getResourceVersion()));
139141
updatedCustomResource =
140142
updateStatusGenerationAware(updateControl.getResource(), originalResource,
141-
updateControl.isPatch());
143+
updateControl.isPatch(), updateControl.onlyOnChange());
142144
} else if (updateControl.isUpdateStatus()) {
143145
updatedCustomResource =
144146
updateStatusGenerationAware(updateControl.getResource(), originalResource,
145-
updateControl.isPatch());
147+
updateControl.isPatch(), updateControl.onlyOnChange());
146148
} else if (updateControl.isUpdateResource()) {
147149
updatedCustomResource =
148-
updateCustomResource(updateControl.getResource());
149-
if (shouldUpdateObservedGenerationAutomatically(updatedCustomResource)) {
150+
updateCustomResource(updateControl.getResource(), originalResource,
151+
updateControl.onlyOnChange());
152+
if (shouldUpdateObservedGenerationAutomatically(
153+
updatedCustomResource.orElse(updateControl.getResource()))) {
150154
updatedCustomResource =
151155
updateStatusGenerationAware(updateControl.getResource(), originalResource,
152-
updateControl.isPatch());
156+
updateControl.isPatch(), updateControl.onlyOnChange());
153157
}
154158
} else if (updateControl.isNoUpdate()
155159
&& shouldUpdateObservedGenerationAutomatically(resourceForExecution)) {
156160
updatedCustomResource =
157-
updateStatusGenerationAware(originalResource, originalResource, updateControl.isPatch());
161+
updateStatusGenerationAware(originalResource, originalResource, updateControl.isPatch(),
162+
updateControl.onlyOnChange());
158163
}
159-
return createPostExecutionControl(updatedCustomResource, updateControl);
164+
return createPostExecutionControl(updatedCustomResource.orElse(null), updateControl);
160165
}
161166

162167
@SuppressWarnings("unchecked")
@@ -207,12 +212,17 @@ private boolean isErrorStatusHandlerPresent() {
207212
return controller.getReconciler() instanceof ErrorStatusHandler;
208213
}
209214

210-
private R updateStatusGenerationAware(R resource, R originalResource, boolean patch) {
215+
private Optional<R> updateStatusGenerationAware(R resource, R originalResource, boolean patch,
216+
boolean onlyIfChanged) {
211217
updateStatusObservedGenerationIfRequired(resource);
218+
// todo unit test order
219+
if (onlyIfChanged && statusEqual(resource, originalResource)) {
220+
return Optional.empty();
221+
}
212222
if (patch) {
213-
return customResourceFacade.patchStatus(resource, originalResource);
223+
return Optional.of(customResourceFacade.patchStatus(resource, originalResource));
214224
} else {
215-
return customResourceFacade.updateStatus(resource);
225+
return Optional.of(customResourceFacade.updateStatus(resource));
216226
}
217227
}
218228

@@ -305,10 +315,14 @@ private R updateCustomResourceWithFinalizer(R resource) {
305315
return customResourceFacade.replaceResourceWithLock(resource);
306316
}
307317

308-
private R updateCustomResource(R resource) {
318+
private Optional<R> updateCustomResource(R resource, R originalResource, boolean onlyOnChange) {
319+
if (onlyOnChange && !specAndMetaEqual(resource, originalResource)) {
320+
return Optional.empty();
321+
}
322+
309323
log.debug("Updating resource: {} with version: {}", getUID(resource), getVersion(resource));
310324
log.trace("Resource before update: {}", resource);
311-
return customResourceFacade.replaceResourceWithLock(resource);
325+
return Optional.of(customResourceFacade.replaceResourceWithLock(resource));
312326
}
313327

314328
ControllerConfiguration<R> configuration() {
@@ -346,6 +360,25 @@ public R removeFinalizer(R resource, String finalizer) {
346360
}
347361
}
348362

363+
@SuppressWarnings("rawtypes")
364+
private boolean statusEqual(R resource, R originalResource) {
365+
if (!(resource instanceof CustomResource)) {
366+
return false;
367+
}
368+
return ((CustomResource) resource).getStatus()
369+
.equals(((CustomResource) originalResource).getStatus());
370+
}
371+
372+
@SuppressWarnings("rawtypes")
373+
private boolean specAndMetaEqual(R resource, R originalResource) {
374+
if (!(resource instanceof CustomResource)) {
375+
return false;
376+
}
377+
return ((CustomResource) resource).getSpec()
378+
.equals(((CustomResource) originalResource).getSpec()) &&
379+
resource.getMetadata().equals(originalResource.getMetadata());
380+
}
381+
349382
// created to support unit testing
350383
static class CustomResourceFacade<R extends HasMetadata> {
351384

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcherTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,13 +396,15 @@ public boolean isLastAttempt() {
396396
@Test
397397
void setReScheduleToPostExecutionControlFromUpdateControl() {
398398
testCustomResource.addFinalizer(DEFAULT_FINALIZER);
399+
when(customResourceFacade.patchStatus(any(), any())).thenReturn(testCustomResource);
399400

400401
reconciler.reconcile =
401402
(r, c) -> UpdateControl.patchStatus(testCustomResource).rescheduleAfter(1000L);
402403

403404
PostExecutionControl control =
404405
reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource));
405406

407+
406408
assertThat(control.getReScheduleDelay().orElseGet(() -> fail("Missing optional")))
407409
.isEqualTo(1000L);
408410
}

0 commit comments

Comments
 (0)