Skip to content

Commit 705e9a5

Browse files
committed
refactor: EventSourceAware -> DeferrableEventSourceHolder, handle errors
1 parent 3772893 commit 705e9a5

File tree

6 files changed

+71
-46
lines changed

6 files changed

+71
-46
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.javaoperatorsdk.operator.api.reconciler.dependent;
2+
3+
import java.util.Optional;
4+
5+
import io.fabric8.kubernetes.api.model.HasMetadata;
6+
import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever;
7+
8+
public interface DeferrableEventSourceHolder<P extends HasMetadata> {
9+
10+
default void useEventSourceWithName(String name) {}
11+
12+
Optional<String> resolveEventSource(EventSourceRetriever<P> eventSourceRetriever);
13+
14+
}

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

-2
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ default Optional<ResourceEventSource<R, P>> eventSource(
4949
return Optional.empty();
5050
}
5151

52-
default void useEventSourceWithName(String name) {}
53-
5452
default Optional<R> getSecondaryResource(P primary, Context<P> context) {
5553
return Optional.empty();
5654
}

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

-10
This file was deleted.

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

+33-20
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package io.javaoperatorsdk.operator.processing;
22

3+
import java.util.ArrayList;
4+
import java.util.HashMap;
5+
import java.util.List;
36
import java.util.Map;
47
import java.util.Optional;
58
import java.util.Set;
@@ -32,7 +35,7 @@
3235
import io.javaoperatorsdk.operator.api.reconciler.Ignore;
3336
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
3437
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
35-
import io.javaoperatorsdk.operator.api.reconciler.dependent.EventSourceAware;
38+
import io.javaoperatorsdk.operator.api.reconciler.dependent.DeferrableEventSourceHolder;
3639
import io.javaoperatorsdk.operator.api.reconciler.dependent.EventSourceProvider;
3740
import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.DefaultManagedDependentResourceContext;
3841
import io.javaoperatorsdk.operator.processing.dependent.workflow.ManagedWorkflow;
@@ -214,25 +217,35 @@ public void initAndRegisterEventSources(EventSourceContext<P> context) {
214217
final var ownSources = provider.prepareEventSources(context);
215218
ownSources.forEach(eventSourceManager::registerEventSource);
216219
}
217-
managedWorkflow
218-
.getDependentResourcesByName().entrySet().stream()
219-
.forEach(drEntry -> {
220-
if (drEntry.getValue() instanceof EventSourceProvider) {
221-
final var provider = (EventSourceProvider) drEntry.getValue();
222-
final var source = provider.initEventSource(context);
223-
eventSourceManager.registerEventSource(drEntry.getKey(), source);
224-
} else {
225-
Optional<ResourceEventSource> eventSource =
226-
drEntry.getValue().eventSource(context);
227-
eventSource.ifPresent(es -> {
228-
eventSourceManager.registerEventSource(drEntry.getKey(), es);
229-
});
230-
}
231-
});
232-
managedWorkflow.getDependentResourcesByName().entrySet().stream().map(Map.Entry::getValue)
233-
.filter(EventSourceAware.class::isInstance)
234-
.forEach(dr -> ((EventSourceAware) dr)
235-
.selectEventSources(eventSourceManager));
220+
221+
// register created event sources
222+
final var dependentResourcesByName = managedWorkflow.getDependentResourcesByName();
223+
final var size = dependentResourcesByName.size();
224+
if (size > 0) {
225+
dependentResourcesByName.forEach((key, value) -> {
226+
if (value instanceof EventSourceProvider) {
227+
final var provider = (EventSourceProvider) value;
228+
final var source = provider.initEventSource(context);
229+
eventSourceManager.registerEventSource(key, source);
230+
} else {
231+
Optional<ResourceEventSource> eventSource = value.eventSource(context);
232+
eventSource.ifPresent(es -> eventSourceManager.registerEventSource(key, es));
233+
}
234+
});
235+
236+
// resolve event sources referenced by name for dependents that reuse an existing event source
237+
final Map<String, List<DeferrableEventSourceHolder>> unresolvable = new HashMap<>(size);
238+
dependentResourcesByName.values().stream()
239+
.filter(DeferrableEventSourceHolder.class::isInstance)
240+
.map(DeferrableEventSourceHolder.class::cast)
241+
.forEach(dr -> ((DeferrableEventSourceHolder<P>) dr)
242+
.resolveEventSource(eventSourceManager).ifPresent(unresolved -> unresolvable
243+
.computeIfAbsent(unresolved, s -> new ArrayList<>()).add(dr)));
244+
if (!unresolvable.isEmpty()) {
245+
throw new IllegalStateException(
246+
"Couldn't resolve referenced EventSources: " + unresolvable);
247+
}
248+
}
236249
}
237250

238251
@Override

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractEventSourceHolderDependentResource.java

+12-13
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import io.fabric8.kubernetes.api.model.HasMetadata;
66
import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext;
77
import io.javaoperatorsdk.operator.api.reconciler.Ignore;
8-
import io.javaoperatorsdk.operator.api.reconciler.dependent.EventSourceAware;
8+
import io.javaoperatorsdk.operator.api.reconciler.dependent.DeferrableEventSourceHolder;
99
import io.javaoperatorsdk.operator.api.reconciler.dependent.RecentOperationCacheFiller;
1010
import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever;
1111
import io.javaoperatorsdk.operator.processing.event.ResourceID;
@@ -17,7 +17,7 @@
1717

1818
@Ignore
1919
public abstract class AbstractEventSourceHolderDependentResource<R, P extends HasMetadata, T extends ResourceEventSource<R, P>>
20-
extends AbstractDependentResource<R, P> implements EventSourceAware<P> {
20+
extends AbstractDependentResource<R, P> implements DeferrableEventSourceHolder<P> {
2121

2222
private T eventSource;
2323
private final Class<R> resourceType;
@@ -32,7 +32,6 @@ protected AbstractEventSourceHolderDependentResource(Class<R> resourceType) {
3232
this.resourceType = resourceType;
3333
}
3434

35-
3635
public Optional<ResourceEventSource<R, P>> eventSource(EventSourceContext<P> context) {
3736
// some sub-classes (e.g. KubernetesDependentResource) can have their event source created
3837
// before this method is called in the managed case, so only create the event source if it
@@ -49,14 +48,20 @@ public Optional<ResourceEventSource<R, P>> eventSource(EventSourceContext<P> con
4948

5049
@SuppressWarnings("unchecked")
5150
@Override
52-
public void selectEventSources(EventSourceRetriever<P> eventSourceRetriever) {
53-
if (eventSourceNameToUse != null) {
54-
setEventSource(
55-
(T) eventSourceRetriever.getResourceEventSourceFor(resourceType(), eventSourceNameToUse));
51+
public Optional<String> resolveEventSource(EventSourceRetriever<P> eventSourceRetriever) {
52+
if (eventSourceNameToUse != null && eventSource == null) {
53+
final var source =
54+
eventSourceRetriever.getResourceEventSourceFor(resourceType(), eventSourceNameToUse);
55+
if (source == null) {
56+
return Optional.of(eventSourceNameToUse);
57+
}
58+
setEventSource((T) source);
5659
}
60+
return Optional.empty();
5761
}
5862

5963
/** To make this backwards compatible even for respect of overriding */
64+
@SuppressWarnings("unchecked")
6065
public T initEventSource(EventSourceContext<P> context) {
6166
return (T) eventSource(context).orElseThrow();
6267
}
@@ -117,10 +122,4 @@ public void setOnUpdateFilter(OnUpdateFilter<R> onUpdateFilter) {
117122
public void setOnDeleteFilter(OnDeleteFilter<R> onDeleteFilter) {
118123
this.onDeleteFilter = onDeleteFilter;
119124
}
120-
121-
public AbstractEventSourceHolderDependentResource<R, P, T> setEventSourceNameToUse(
122-
String eventSourceNameToUse) {
123-
this.eventSourceNameToUse = eventSourceNameToUse;
124-
return this;
125-
}
126125
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/ManagedWorkflowSupport.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import io.javaoperatorsdk.operator.OperatorException;
1515
import io.javaoperatorsdk.operator.api.config.ConfigurationServiceProvider;
1616
import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec;
17+
import io.javaoperatorsdk.operator.api.reconciler.dependent.DeferrableEventSourceHolder;
1718
import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource;
1819
import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.DependentResourceConfigurator;
1920
import io.javaoperatorsdk.operator.api.reconciler.dependent.managed.KubernetesClientAware;
@@ -83,7 +84,17 @@ public DependentResource createAndConfigureFrom(DependentResourceSpec spec,
8384
}
8485

8586
spec.getUseEventSourceWithName()
86-
.ifPresent(esName -> dependentResource.useEventSourceWithName((String) esName));
87+
.ifPresent(esName -> {
88+
final var name = (String) esName;
89+
if (dependentResource instanceof DeferrableEventSourceHolder) {
90+
((DeferrableEventSourceHolder) dependentResource).useEventSourceWithName(name);
91+
} else {
92+
throw new IllegalStateException(
93+
"DependentResource " + spec + " wants to use EventSource named " + name
94+
+ " but doesn't implement support for this feature by implementing "
95+
+ DeferrableEventSourceHolder.class.getSimpleName());
96+
}
97+
});
8798

8899
if (dependentResource instanceof DependentResourceConfigurator) {
89100
final var configurator = (DependentResourceConfigurator) dependentResource;

0 commit comments

Comments
 (0)