Skip to content

Commit 0ec51e0

Browse files
authored
fix: cover informer automatic start case (#662)
1 parent 450a1cc commit 0ec51e0

File tree

2 files changed

+29
-12
lines changed

2 files changed

+29
-12
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
public abstract class AbstractEventSource implements EventSource {
44

5-
protected EventHandler eventHandler;
5+
protected volatile EventHandler eventHandler;
66

77
@Override
88
public void setEventHandler(EventHandler eventHandler) {

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

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
import java.util.Set;
55
import java.util.function.Function;
66

7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
710
import io.fabric8.kubernetes.api.model.HasMetadata;
811
import io.fabric8.kubernetes.client.KubernetesClient;
912
import io.fabric8.kubernetes.client.informers.ResourceEventHandler;
@@ -16,35 +19,42 @@
1619

1720
public class InformerEventSource<T extends HasMetadata> extends AbstractEventSource {
1821

22+
private static final Logger log = LoggerFactory.getLogger(InformerEventSource.class);
23+
1924
private final SharedInformer<T> sharedInformer;
20-
private final Function<T, Set<CustomResourceID>> resourceToUIDs;
25+
private final Function<T, Set<CustomResourceID>> resourceToCustomResourceIDSet;
2126
private final Function<HasMetadata, T> associatedWith;
2227
private final boolean skipUpdateEventPropagationIfNoChange;
2328

2429
public InformerEventSource(SharedInformer<T> sharedInformer,
25-
Function<T, Set<CustomResourceID>> resourceToUIDs) {
26-
this(sharedInformer, resourceToUIDs, null, true);
30+
Function<T, Set<CustomResourceID>> resourceToCustomResourceIDSet) {
31+
this(sharedInformer, resourceToCustomResourceIDSet, null, true);
2732
}
2833

2934
public InformerEventSource(KubernetesClient client, Class<T> type,
30-
Function<T, Set<CustomResourceID>> resourceToUIDs) {
31-
this(client, type, resourceToUIDs, false);
35+
Function<T, Set<CustomResourceID>> resourceToCustomResourceIDSet) {
36+
this(client, type, resourceToCustomResourceIDSet, false);
3237
}
3338

3439
InformerEventSource(KubernetesClient client, Class<T> type,
35-
Function<T, Set<CustomResourceID>> resourceToUIDs,
40+
Function<T, Set<CustomResourceID>> resourceToCustomResourceIDSet,
3641
boolean skipUpdateEventPropagationIfNoChange) {
37-
this(client.informers().sharedIndexInformerFor(type, 0), resourceToUIDs, null,
42+
this(client.informers().sharedIndexInformerFor(type, 0), resourceToCustomResourceIDSet, null,
3843
skipUpdateEventPropagationIfNoChange);
3944
}
4045

4146
public InformerEventSource(SharedInformer<T> sharedInformer,
42-
Function<T, Set<CustomResourceID>> resourceToUIDs,
47+
Function<T, Set<CustomResourceID>> resourceToCustomResourceIDSet,
4348
Function<HasMetadata, T> associatedWith,
4449
boolean skipUpdateEventPropagationIfNoChange) {
4550
this.sharedInformer = sharedInformer;
46-
this.resourceToUIDs = resourceToUIDs;
51+
this.resourceToCustomResourceIDSet = resourceToCustomResourceIDSet;
4752
this.skipUpdateEventPropagationIfNoChange = skipUpdateEventPropagationIfNoChange;
53+
if (sharedInformer.isRunning()) {
54+
log.warn(
55+
"Informer is already running on event source creation, this is not desirable and may " +
56+
"lead to non deterministic behavior.");
57+
}
4858

4959
this.associatedWith = Objects.requireNonNullElseGet(associatedWith, () -> cr -> {
5060
final var metadata = cr.getMetadata();
@@ -76,13 +86,20 @@ public void onDelete(T t, boolean b) {
7686
}
7787

7888
private void propagateEvent(T object) {
79-
var uids = resourceToUIDs.apply(object);
89+
var uids = resourceToCustomResourceIDSet.apply(object);
8090
if (uids.isEmpty()) {
8191
return;
8292
}
8393
uids.forEach(uid -> {
8494
Event event = new Event(CustomResourceID.fromResource(object));
85-
this.eventHandler.handleEvent(event);
95+
/*
96+
* In fabric8 client for certain cases informers can be created on in a way that they are
97+
* automatically started, what would cause a NullPointerException here, since an event might
98+
* be received between creation and registration.
99+
*/
100+
if (eventHandler != null) {
101+
this.eventHandler.handleEvent(event);
102+
}
86103
});
87104
}
88105

0 commit comments

Comments
 (0)