Skip to content

Commit 9986c1e

Browse files
csvirishawkins
andcommitted
feat: ReconcileUtils for strongly consistent updates (#3106)
- Adds utility that provides methods to update resources using comparable resource versions - Integrates this utility to the core of the framework (thus simplifying `ReconciliationDispatcher`) - note that this introduces a change in the behavior for the `UpdateControl.patchStatus` (and others), since it won't trigger the reconiliation for the event in that update. - Renames former `ReconcilerUtils` to `ReconcilerUtilsInternal`, this is breaking but that utils was never advertised for non-internal usage - Includes also fixes for ControllerEventSource event filtering - Improves TemporaryResourceCache event filtering algorithm Signed-off-by: Attila Mészáros <a_meszaros@apple.com> Signed-off-by: Steve Hawkins <shawkins@redhat.com> Co-authored-by: Steve Hawkins <shawkins@redhat.com>
1 parent c7b4f8b commit 9986c1e

File tree

65 files changed

+2041
-649
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+2041
-649
lines changed

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ public <P extends HasMetadata> RegisteredController<P> register(
263263
"Cannot register reconciler with name "
264264
+ reconciler.getClass().getCanonicalName()
265265
+ " reconciler named "
266-
+ ReconcilerUtils.getNameFor(reconciler)
266+
+ ReconcilerUtilsInternal.getNameFor(reconciler)
267267
+ " because its configuration cannot be found.\n"
268268
+ " Known reconcilers are: "
269269
+ configurationService.getKnownReconcilerNames());

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ReconcilerUtils.java renamed to operator-framework-core/src/main/java/io/javaoperatorsdk/operator/ReconcilerUtilsInternal.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
3535

3636
@SuppressWarnings("rawtypes")
37-
public class ReconcilerUtils {
37+
public class ReconcilerUtilsInternal {
3838

3939
private static final String FINALIZER_NAME_SUFFIX = "/finalizer";
4040
protected static final String MISSING_GROUP_SUFFIX = ".javaoperatorsdk.io";
@@ -46,7 +46,7 @@ public class ReconcilerUtils {
4646
Pattern.compile(".*http(s?)://[^/]*/api(s?)/(\\S*).*"); // NOSONAR: input is controlled
4747

4848
// prevent instantiation of util class
49-
private ReconcilerUtils() {}
49+
private ReconcilerUtilsInternal() {}
5050

5151
public static boolean isFinalizerValid(String finalizer) {
5252
return HasMetadata.validateFinalizer(finalizer);

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
import io.fabric8.kubernetes.api.model.HasMetadata;
2424
import io.fabric8.kubernetes.client.KubernetesClient;
25-
import io.javaoperatorsdk.operator.ReconcilerUtils;
25+
import io.javaoperatorsdk.operator.ReconcilerUtilsInternal;
2626
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
2727

2828
/**
@@ -145,7 +145,7 @@ private String getReconcilersNameMessage() {
145145
}
146146

147147
protected <R extends HasMetadata> String keyFor(Reconciler<R> reconciler) {
148-
return ReconcilerUtils.getNameFor(reconciler);
148+
return ReconcilerUtilsInternal.getNameFor(reconciler);
149149
}
150150

151151
@SuppressWarnings("unused")

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/BaseConfigurationService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
import io.fabric8.kubernetes.api.model.HasMetadata;
3030
import io.fabric8.kubernetes.client.KubernetesClient;
31-
import io.javaoperatorsdk.operator.ReconcilerUtils;
31+
import io.javaoperatorsdk.operator.ReconcilerUtilsInternal;
3232
import io.javaoperatorsdk.operator.api.config.Utils.Configurator;
3333
import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceConfigurationResolver;
3434
import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec;
@@ -265,7 +265,7 @@ private <P extends HasMetadata> ResolvedControllerConfiguration<P> controllerCon
265265
io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration annotation) {
266266
final var resourceClass = getResourceClassResolver().getPrimaryResourceClass(reconcilerClass);
267267

268-
final var name = ReconcilerUtils.getNameFor(reconcilerClass);
268+
final var name = ReconcilerUtilsInternal.getNameFor(reconcilerClass);
269269
final var generationAware =
270270
valueOrDefaultFromAnnotation(
271271
annotation,

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfiguration.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import java.util.Set;
2121

2222
import io.fabric8.kubernetes.api.model.HasMetadata;
23-
import io.javaoperatorsdk.operator.ReconcilerUtils;
23+
import io.javaoperatorsdk.operator.ReconcilerUtilsInternal;
2424
import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec;
2525
import io.javaoperatorsdk.operator.api.config.workflow.WorkflowSpec;
2626
import io.javaoperatorsdk.operator.api.reconciler.MaxReconciliationInterval;
@@ -42,16 +42,18 @@ default String getName() {
4242
}
4343

4444
default String getFinalizerName() {
45-
return ReconcilerUtils.getDefaultFinalizerName(getResourceClass());
45+
return ReconcilerUtilsInternal.getDefaultFinalizerName(getResourceClass());
4646
}
4747

4848
static String ensureValidName(String name, String reconcilerClassName) {
49-
return name != null ? name : ReconcilerUtils.getDefaultReconcilerName(reconcilerClassName);
49+
return name != null
50+
? name
51+
: ReconcilerUtilsInternal.getDefaultReconcilerName(reconcilerClassName);
5052
}
5153

5254
static String ensureValidFinalizerName(String finalizer, String resourceTypeName) {
5355
if (finalizer != null && !finalizer.isBlank()) {
54-
if (ReconcilerUtils.isFinalizerValid(finalizer)) {
56+
if (ReconcilerUtilsInternal.isFinalizerValid(finalizer)) {
5557
return finalizer;
5658
} else {
5759
throw new IllegalArgumentException(
@@ -61,7 +63,7 @@ static String ensureValidFinalizerName(String finalizer, String resourceTypeName
6163
+ " for details");
6264
}
6365
} else {
64-
return ReconcilerUtils.getDefaultFinalizerName(resourceTypeName);
66+
return ReconcilerUtilsInternal.getDefaultFinalizerName(resourceTypeName);
6567
}
6668
}
6769

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/informer/InformerConfiguration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import io.fabric8.kubernetes.api.model.HasMetadata;
2626
import io.fabric8.kubernetes.client.informers.cache.ItemStore;
2727
import io.javaoperatorsdk.operator.OperatorException;
28-
import io.javaoperatorsdk.operator.ReconcilerUtils;
28+
import io.javaoperatorsdk.operator.ReconcilerUtilsInternal;
2929
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
3030
import io.javaoperatorsdk.operator.api.config.Utils;
3131
import io.javaoperatorsdk.operator.api.reconciler.Constants;
@@ -92,7 +92,7 @@ private InformerConfiguration(Class<R> resourceClass) {
9292
// controller
9393
// where GenericKubernetesResource now does not apply
9494
? GenericKubernetesResource.class.getSimpleName()
95-
: ReconcilerUtils.getResourceTypeName(resourceClass);
95+
: ReconcilerUtilsInternal.getResourceTypeName(resourceClass);
9696
}
9797

9898
@SuppressWarnings({"rawtypes", "unchecked"})

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,53 @@
2121

2222
public abstract class BaseControl<T extends BaseControl<T>> {
2323

24+
public static final Long INSTANT_RESCHEDULE = 0L;
25+
2426
private Long scheduleDelay = null;
2527

28+
/**
29+
* Schedules a reconciliation to occur after the specified delay in milliseconds.
30+
*
31+
* @param delay the delay in milliseconds after which to reschedule
32+
* @return this control instance for fluent chaining
33+
*/
2634
public T rescheduleAfter(long delay) {
2735
rescheduleAfter(Duration.ofMillis(delay));
2836
return (T) this;
2937
}
3038

39+
/**
40+
* Schedules a reconciliation to occur after the specified delay.
41+
*
42+
* @param delay the {@link Duration} after which to reschedule
43+
* @return this control instance for fluent chaining
44+
*/
3145
public T rescheduleAfter(Duration delay) {
3246
this.scheduleDelay = delay.toMillis();
3347
return (T) this;
3448
}
3549

50+
/**
51+
* Schedules a reconciliation to occur after the specified delay using the given time unit.
52+
*
53+
* @param delay the delay value
54+
* @param timeUnit the time unit of the delay
55+
* @return this control instance for fluent chaining
56+
*/
3657
public T rescheduleAfter(long delay, TimeUnit timeUnit) {
3758
return rescheduleAfter(timeUnit.toMillis(delay));
3859
}
3960

61+
/**
62+
* Schedules an instant reconciliation. The reconciliation will be triggered as soon as possible.
63+
*
64+
* @return this control instance for fluent chaining
65+
*/
66+
public T reschedule() {
67+
this.scheduleDelay = INSTANT_RESCHEDULE;
68+
return (T) this;
69+
}
70+
4071
public Optional<Long> getScheduleDelay() {
4172
return Optional.ofNullable(scheduleDelay);
4273
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@
4545
* caches the updated resource from the response in an overlay cache on top of the Informer cache.
4646
* If the update fails, it reads the primary resource from the cluster, applies the modifications
4747
* again and retries the update.
48+
*
49+
* @deprecated Use {@link ReconcileUtils} that contains the more efficient up-to-date versions of
50+
* the target utils.
4851
*/
52+
@Deprecated(forRemoval = true)
4953
public class PrimaryUpdateAndCacheUtils {
5054

5155
public static final int DEFAULT_MAX_RETRY = 10;

0 commit comments

Comments
 (0)