Skip to content

Commit 9d27d43

Browse files
committed
mostly removing the parse resource version term
and more of the previous annotation handling Signed-off-by: Steve Hawkins <shawkins@redhat.com>
1 parent 2b755b2 commit 9d27d43

File tree

8 files changed

+47
-99
lines changed

8 files changed

+47
-99
lines changed

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

Lines changed: 5 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
import io.fabric8.kubernetes.api.model.ConfigMap;
2929
import io.fabric8.kubernetes.api.model.HasMetadata;
3030
import io.fabric8.kubernetes.api.model.Secret;
31-
import io.fabric8.kubernetes.api.model.apps.Deployment;
32-
import io.fabric8.kubernetes.api.model.apps.StatefulSet;
3331
import io.fabric8.kubernetes.client.Config;
3432
import io.fabric8.kubernetes.client.ConfigBuilder;
3533
import io.fabric8.kubernetes.client.CustomResource;
@@ -450,45 +448,15 @@ default Set<Class<? extends HasMetadata>> defaultNonSSAResource() {
450448
}
451449

452450
/**
453-
* For dependent resources, the framework can add an annotation to filter out events resulting
454-
* directly from the framework's operation. There are, however, some resources that do not follow
455-
* the Kubernetes API conventions that changes in metadata should not increase the generation of
456-
* the resource (as recorded in the {@code generation} field of the resource's {@code metadata}).
457-
* For these resources, this convention is not respected and results in a new event for the
458-
* framework to process. If that particular case is not handled correctly in the resource matcher,
459-
* the framework will consider that the resource doesn't match the desired state and therefore
460-
* triggers an update, which in turn, will re-add the annotation, thus starting the loop again,
461-
* infinitely.
462-
*
463-
* <p>As a workaround, we automatically skip adding previous annotation for those well-known
464-
* resources. Note that if you are sure that the matcher works for your use case, and it should in
465-
* most instances, you can remove the resource type from the blocklist.
466-
*
467-
* <p>The consequence of adding a resource type to the set is that the framework will not use
468-
* event filtering to prevent events, initiated by changes made by the framework itself as a
469-
* result of its processing of dependent resources, to trigger the associated reconciler again.
470-
*
471-
* <p>Note that this method only takes effect if annotating dependent resources to prevent
472-
* dependent resources events from triggering the associated reconciler again is activated as
473-
* controlled by {@link #previousAnnotationForDependentResourcesEventFiltering()}
474-
*
475-
* @return a Set of resource classes where the previous version annotation won't be used.
476-
*/
477-
default Set<Class<? extends HasMetadata>> withPreviousAnnotationForDependentResourcesBlocklist() {
478-
return Set.of(Deployment.class, StatefulSet.class);
479-
}
480-
481-
/**
482-
* If the event logic should parse the resourceVersion to determine the ordering of dependent
483-
* resource events.
451+
* If the event logic can compare resourceVersions.
484452
*
485453
* <p>Enabled by default as Kubernetes does support this interpretation of resourceVersions.
486-
* Disable only if your api server provides non comparable resource versions..
454+
* Disable only if your api server provides non comparable resource versions.
487455
*
488-
* @return if resource version should be parsed (as integer)
489-
* @since 4.5.0
456+
* @return if resource versions are comparable
457+
* @since 5.3.0
490458
*/
491-
default boolean parseResourceVersionsForEventFilteringAndCaching() {
459+
default boolean comparableResourceVersions() {
492460
return DEFAULT_COMPARABLE_RESOURCE_VERSIONS;
493461
}
494462

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

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,9 @@ public class ConfigurationServiceOverrider {
5151
private Duration reconciliationTerminationTimeout;
5252
private Boolean ssaBasedCreateUpdateMatchForDependentResources;
5353
private Set<Class<? extends HasMetadata>> defaultNonSSAResource;
54-
private Boolean previousAnnotationForDependentResources;
55-
private Boolean parseResourceVersions;
54+
private Boolean comparableResourceVersions;
5655
private Boolean useSSAToPatchPrimaryResource;
5756
private Boolean cloneSecondaryResourcesWhenGettingFromCache;
58-
private Set<Class<? extends HasMetadata>> previousAnnotationUsageBlocklist;
5957

6058
@SuppressWarnings("rawtypes")
6159
private DependentResourceFactory dependentResourceFactory;
@@ -168,28 +166,23 @@ public ConfigurationServiceOverrider withDefaultNonSSAResource(
168166
return this;
169167
}
170168

171-
public ConfigurationServiceOverrider withPreviousAnnotationForDependentResources(boolean value) {
172-
this.previousAnnotationForDependentResources = value;
173-
return this;
174-
}
175-
176169
/**
177170
* @param value true if internal algorithms can use metadata.resourceVersion as a numeric value.
178171
* @return this
179172
*/
180-
public ConfigurationServiceOverrider withParseResourceVersions(boolean value) {
181-
this.parseResourceVersions = value;
173+
public ConfigurationServiceOverrider withComparableResourceVersions(boolean value) {
174+
this.comparableResourceVersions = value;
182175
return this;
183176
}
184177

185178
/**
186-
* @deprecated use withParseResourceVersions
179+
* @deprecated use withComparableResourceVersions
187180
* @param value true if internal algorithms can use metadata.resourceVersion as a numeric value.
188181
* @return this
189182
*/
190183
@Deprecated(forRemoval = true)
191-
public ConfigurationServiceOverrider wihtParseResourceVersions(boolean value) {
192-
this.parseResourceVersions = value;
184+
public ConfigurationServiceOverrider withParseResourceVersions(boolean value) {
185+
this.comparableResourceVersions = value;
193186
return this;
194187
}
195188

@@ -204,12 +197,6 @@ public ConfigurationServiceOverrider withCloneSecondaryResourcesWhenGettingFromC
204197
return this;
205198
}
206199

207-
public ConfigurationServiceOverrider withPreviousAnnotationForDependentResourcesBlocklist(
208-
Set<Class<? extends HasMetadata>> blocklist) {
209-
this.previousAnnotationUsageBlocklist = blocklist;
210-
return this;
211-
}
212-
213200
public ConfigurationService build() {
214201
return new BaseConfigurationService(original.getVersion(), cloner, client) {
215202
@Override
@@ -331,13 +318,6 @@ public Set<Class<? extends HasMetadata>> defaultNonSSAResources() {
331318
defaultNonSSAResource, ConfigurationService::defaultNonSSAResources);
332319
}
333320

334-
@Override
335-
public boolean parseResourceVersionsForEventFilteringAndCaching() {
336-
return overriddenValueOrDefault(
337-
parseResourceVersions,
338-
ConfigurationService::parseResourceVersionsForEventFilteringAndCaching);
339-
}
340-
341321
@Override
342322
public boolean useSSAToPatchPrimaryResource() {
343323
return overriddenValueOrDefault(
@@ -352,11 +332,9 @@ public boolean cloneSecondaryResourcesWhenGettingFromCache() {
352332
}
353333

354334
@Override
355-
public Set<Class<? extends HasMetadata>>
356-
withPreviousAnnotationForDependentResourcesBlocklist() {
335+
public boolean comparableResourceVersions() {
357336
return overriddenValueOrDefault(
358-
previousAnnotationUsageBlocklist,
359-
ConfigurationService::withPreviousAnnotationForDependentResourcesBlocklist);
337+
comparableResourceVersions, ConfigurationService::comparableResourceVersions);
360338
}
361339
};
362340
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/controller/ControllerEventSource.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,7 @@ public ControllerEventSource(Controller<T> controller) {
5151
NAME,
5252
controller.getCRClient(),
5353
controller.getConfiguration(),
54-
controller
55-
.getConfiguration()
56-
.getConfigurationService()
57-
.parseResourceVersionsForEventFilteringAndCaching());
54+
controller.getConfiguration().getConfigurationService().comparableResourceVersions());
5855
this.controller = controller;
5956

6057
final var config = controller.getConfiguration();

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerEventSource.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,15 @@ public InformerEventSource(
9797
private InformerEventSource(
9898
InformerEventSourceConfiguration<R> configuration,
9999
KubernetesClient client,
100-
boolean parseResourceVersions) {
100+
boolean comparableResourceVersions) {
101101
super(
102102
configuration.name(),
103103
configuration
104104
.getGroupVersionKind()
105105
.map(gvk -> client.genericKubernetesResources(gvk.apiVersion(), gvk.getKind()))
106106
.orElseGet(() -> (MixedOperation) client.resources(configuration.getResourceClass())),
107107
configuration,
108-
parseResourceVersions);
108+
comparableResourceVersions);
109109
// If there is a primary to secondary mapper there is no need for primary to secondary index.
110110
primaryToSecondaryMapper = configuration.getPrimaryToSecondaryMapper();
111111
if (useSecondaryToPrimaryIndex()) {

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/ManagedInformerEventSource.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,17 @@ public abstract class ManagedInformerEventSource<
5656

5757
private static final Logger log = LoggerFactory.getLogger(ManagedInformerEventSource.class);
5858
private InformerManager<R, C> cache;
59-
private final boolean parseResourceVersions;
59+
private final boolean comparableResourceVersions;
6060
private ControllerConfiguration<R> controllerConfiguration;
6161
private final C configuration;
6262
private final Map<String, Function<R, List<String>>> indexers = new HashMap<>();
6363
protected TemporaryResourceCache<R> temporaryResourceCache;
6464
protected MixedOperation client;
6565

6666
protected ManagedInformerEventSource(
67-
String name, MixedOperation client, C configuration, boolean parseResourceVersions) {
67+
String name, MixedOperation client, C configuration, boolean comparableResourceVersions) {
6868
super(configuration.getResourceClass(), name);
69-
this.parseResourceVersions = parseResourceVersions;
69+
this.comparableResourceVersions = comparableResourceVersions;
7070
this.client = client;
7171
this.configuration = configuration;
7272
}
@@ -103,7 +103,7 @@ public synchronized void start() {
103103
if (isRunning()) {
104104
return;
105105
}
106-
temporaryResourceCache = new TemporaryResourceCache<>(parseResourceVersions);
106+
temporaryResourceCache = new TemporaryResourceCache<>(comparableResourceVersions);
107107
this.cache = new InformerManager<>(client, configuration, this);
108108
cache.setControllerConfiguration(controllerConfiguration);
109109
cache.addIndexers(indexers);
@@ -135,7 +135,7 @@ public void handleRecentResourceCreate(ResourceID resourceID, R resource) {
135135
public Optional<R> get(ResourceID resourceID) {
136136
var res = cache.get(resourceID);
137137
Optional<R> resource = temporaryResourceCache.getResourceFromCache(resourceID);
138-
if (parseResourceVersions
138+
if (comparableResourceVersions
139139
&& resource.isPresent()
140140
&& res.filter(
141141
r ->

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/TemporaryResourceCache.java

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,17 @@
3333
* a create or update is executed the subsequent getResource operation might not return the
3434
* up-to-date resource from informer cache, since it is not received yet.
3535
*
36-
* <p>Since an update (for create is simpler) was done successfully we can temporarily track
37-
* that resource if its version is later than the events we've processed. We then know that we can skip
38-
* all events that have the same resource version or earlier than the tracked resource. Once we process
39-
* an event that has the same resource version or later, then we know the tracked resource can be removed.
40-
*
41-
* <p>In some cases it is possible for the informer to deliver events prior to the attempt to put the
42-
* resource in the temporal cache. The startModifying/doneModifying methods are used to pause event
43-
* delivery to ensure that temporal cache recognizes the put entry as an event that can be skipped.
44-
*
36+
* <p>Since an update (for create is simpler) was done successfully we can temporarily track that
37+
* resource if its version is later than the events we've processed. We then know that we can skip
38+
* all events that have the same resource version or earlier than the tracked resource. Once we
39+
* process an event that has the same resource version or later, then we know the tracked resource
40+
* can be removed.
41+
*
42+
* <p>In some cases it is possible for the informer to deliver events prior to the attempt to put
43+
* the resource in the temporal cache. The startModifying/doneModifying methods are used to pause
44+
* event delivery to ensure that temporal cache recognizes the put entry as an event that can be
45+
* skipped.
46+
*
4547
* <p>If comparable resource versions are disabled, then this cache is effectively disabled.
4648
*
4749
* @param <T> resource to cache.
@@ -51,16 +53,16 @@ public class TemporaryResourceCache<T extends HasMetadata> {
5153
private static final Logger log = LoggerFactory.getLogger(TemporaryResourceCache.class);
5254

5355
private final Map<ResourceID, T> cache = new ConcurrentHashMap<>();
54-
private final boolean parseResourceVersions;
56+
private final boolean comparableResourceVersions;
5557
private final Map<ResourceID, ReentrantLock> activelyModifying = new ConcurrentHashMap<>();
5658
private String latestResourceVersion;
5759

58-
public TemporaryResourceCache(boolean parseResourceVersions) {
59-
this.parseResourceVersions = parseResourceVersions;
60+
public TemporaryResourceCache(boolean comparableResourceVersions) {
61+
this.comparableResourceVersions = comparableResourceVersions;
6062
}
6163

6264
public void startModifying(ResourceID id) {
63-
if (!parseResourceVersions) {
65+
if (!comparableResourceVersions) {
6466
return;
6567
}
6668
activelyModifying
@@ -77,7 +79,7 @@ public void startModifying(ResourceID id) {
7779
}
7880

7981
public void doneModifying(ResourceID id) {
80-
if (!parseResourceVersions) {
82+
if (!comparableResourceVersions) {
8183
return;
8284
}
8385
activelyModifying.computeIfPresent(
@@ -134,7 +136,7 @@ private boolean onEvent(T resource, boolean unknownState) {
134136

135137
/** put the item into the cache if it's for a later state than what has already been observed. */
136138
public synchronized void putResource(T newResource) {
137-
if (!parseResourceVersions) {
139+
if (!comparableResourceVersions) {
138140
return;
139141
}
140142

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/informer/TemporaryPrimaryResourceCacheTest.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.Map;
1919
import java.util.concurrent.ExecutorService;
2020
import java.util.concurrent.Executors;
21+
import java.util.concurrent.TimeUnit;
2122

2223
import org.junit.jupiter.api.BeforeEach;
2324
import org.junit.jupiter.api.Test;
@@ -108,7 +109,7 @@ void removesResourceFromCache() {
108109
}
109110

110111
@Test
111-
void resourceNoVersionParsing() {
112+
void nonComparableResourceVersionsDisables() {
112113
this.temporaryResourceCache = new TemporaryResourceCache<>(false);
113114

114115
this.temporaryResourceCache.putResource(testResource());
@@ -123,13 +124,16 @@ void lockedEventBeforePut() throws Exception {
123124

124125
temporaryResourceCache.startModifying(ResourceID.fromResource(testResource));
125126

126-
try (ExecutorService ex = Executors.newSingleThreadExecutor()) {
127+
ExecutorService ex = Executors.newSingleThreadExecutor();
128+
try {
127129
var result = ex.submit(() -> temporaryResourceCache.onAddOrUpdateEvent(testResource));
128130

129131
temporaryResourceCache.putResource(testResource);
130132
assertThat(result.isDone()).isFalse();
131133
temporaryResourceCache.doneModifying(ResourceID.fromResource(testResource));
132-
assertThat(result.get()).isTrue();
134+
assertThat(result.get(10, TimeUnit.SECONDS)).isTrue();
135+
} finally {
136+
ex.shutdownNow();
133137
}
134138
}
135139

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,13 @@
2020

2121
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
2222

23-
class PreviousAnnotationDisabledIT {
23+
class ComparableResourceVersionsDisabledIT {
2424

2525
@RegisterExtension
2626
LocallyRunOperatorExtension operator =
2727
LocallyRunOperatorExtension.builder()
2828
.withReconciler(new CreateUpdateEventFilterTestReconciler())
29-
.withConfigurationService(
30-
overrider -> overrider.withPreviousAnnotationForDependentResources(false))
29+
.withConfigurationService(overrider -> overrider.withComparableResourceVersions(false))
3130
.build();
3231

3332
@Test

0 commit comments

Comments
 (0)