Skip to content

Commit b195bdc

Browse files
committed
feat: Workflow extracted to a separate annotation (#2274)
Signed-off-by: Attila Mészáros <[email protected]>
1 parent d2ae028 commit b195bdc

File tree

52 files changed

+318
-313
lines changed

Some content is hidden

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

52 files changed

+318
-313
lines changed

Diff for: bootstrapper-maven-plugin/src/main/resources/templates/Reconciler.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@
1111
import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext;
1212
import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration;
1313
import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent;
14+
import io.javaoperatorsdk.operator.api.reconciler.Workflow;
1415
import io.javaoperatorsdk.operator.processing.event.source.EventSource;
1516
import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource;
1617

1718
import java.util.Map;
1819
import java.util.Optional;
1920

20-
@ControllerConfiguration(dependents = {@Dependent(type = ConfigMapDependentResource.class)})
21+
@Workflow(dependents = {@Dependent(type = ConfigMapDependentResource.class)})
22+
@ControllerConfiguration
2123
public class {{artifactClassId}}Reconciler implements Reconciler<{{artifactClassId}}CustomResource> {
2224

2325
public UpdateControl<{{artifactClassId}}CustomResource> reconcile({{artifactClassId}}CustomResource primary,

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

+16-8
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
import io.javaoperatorsdk.operator.ReconcilerUtils;
2020
import io.javaoperatorsdk.operator.api.config.Utils.Configurator;
2121
import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec;
22+
import io.javaoperatorsdk.operator.api.config.workflow.WorkflowSpec;
2223
import io.javaoperatorsdk.operator.api.reconciler.Constants;
2324
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
25+
import io.javaoperatorsdk.operator.api.reconciler.Workflow;
2426
import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent;
2527
import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource;
2628
import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition;
@@ -97,6 +99,7 @@ public <R extends HasMetadata> ControllerConfiguration<R> getConfigurationFor(
9799
protected <P extends HasMetadata> ControllerConfiguration<P> configFor(Reconciler<P> reconciler) {
98100
final var annotation = reconciler.getClass().getAnnotation(
99101
io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration.class);
102+
100103
if (annotation == null) {
101104
throw new OperatorException(
102105
"Missing mandatory @"
@@ -161,21 +164,26 @@ protected <P extends HasMetadata> ControllerConfiguration<P> configFor(Reconcile
161164
Utils.instantiate(annotation.itemStore(), ItemStore.class, context), dependentFieldManager,
162165
this, informerListLimit);
163166

164-
List<DependentResourceSpec> specs = dependentResources(annotation, config);
165-
config.setDependentResources(specs);
167+
168+
final var workflowAnnotation = reconciler.getClass().getAnnotation(
169+
io.javaoperatorsdk.operator.api.reconciler.Workflow.class);
170+
if (workflowAnnotation != null) {
171+
List<DependentResourceSpec> specs = dependentResources(workflowAnnotation, config);
172+
WorkflowSpec workflowSpec = new WorkflowSpec(specs);
173+
config.setWorkflowSpec(workflowSpec);
174+
}
166175

167176
return config;
168177
}
169178

170179
@SuppressWarnings({"unchecked", "rawtypes"})
171180
private static List<DependentResourceSpec> dependentResources(
172-
io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration annotation,
181+
Workflow annotation,
173182
ControllerConfiguration<?> parent) {
174-
final var dependents =
175-
valueOrDefault(annotation,
176-
io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::dependents,
177-
new Dependent[] {});
178-
if (dependents.length == 0) {
183+
final var dependents = annotation.dependents();
184+
185+
186+
if (dependents == null || dependents.length == 0) {
179187
return Collections.emptyList();
180188
}
181189

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

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
package io.javaoperatorsdk.operator.api.config;
22

33
import java.time.Duration;
4-
import java.util.Collections;
5-
import java.util.List;
64
import java.util.Optional;
75
import java.util.Set;
86

97
import io.fabric8.kubernetes.api.model.HasMetadata;
108
import io.javaoperatorsdk.operator.ReconcilerUtils;
11-
import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec;
9+
import io.javaoperatorsdk.operator.api.config.workflow.WorkflowSpec;
1210
import io.javaoperatorsdk.operator.api.reconciler.MaxReconciliationInterval;
1311
import io.javaoperatorsdk.operator.processing.event.rate.LinearRateLimiter;
1412
import io.javaoperatorsdk.operator.processing.event.rate.RateLimiter;
@@ -65,9 +63,8 @@ default RateLimiter getRateLimiter() {
6563
return DEFAULT_RATE_LIMITER;
6664
}
6765

68-
@SuppressWarnings("rawtypes")
69-
default List<DependentResourceSpec> getDependentResources() {
70-
return Collections.emptyList();
66+
default Optional<WorkflowSpec> getWorkflowSpec() {
67+
return Optional.empty();
7168
}
7269

7370
default Optional<Duration> maxReconciliationInterval() {

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverrider.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import io.fabric8.kubernetes.api.model.HasMetadata;
1111
import io.fabric8.kubernetes.client.informers.cache.ItemStore;
1212
import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec;
13+
import io.javaoperatorsdk.operator.api.config.workflow.WorkflowSpec;
1314
import io.javaoperatorsdk.operator.processing.event.rate.RateLimiter;
1415
import io.javaoperatorsdk.operator.processing.event.source.filter.GenericFilter;
1516
import io.javaoperatorsdk.operator.processing.event.source.filter.OnAddFilter;
@@ -38,6 +39,7 @@ public class ControllerConfigurationOverrider<R extends HasMetadata> {
3839
private String name;
3940
private String fieldManager;
4041
private Long informerListLimit;
42+
private WorkflowSpec workflowSpec;
4143

4244
private ControllerConfigurationOverrider(ControllerConfiguration<R> original) {
4345
this.finalizer = original.getFinalizerName();
@@ -55,6 +57,7 @@ private ControllerConfigurationOverrider(ControllerConfiguration<R> original) {
5557
this.fieldManager = original.fieldManager();
5658
this.informerListLimit = original.getInformerListLimit().orElse(null);
5759
this.itemStore = original.getItemStore().orElse(null);
60+
this.workflowSpec = original.getWorkflowSpec().orElse(null);
5861
}
5962

6063
public ControllerConfigurationOverrider<R> withFinalizer(String finalizer) {
@@ -175,7 +178,7 @@ public ControllerConfigurationOverrider<R> withInformerListLimit(
175178
public ControllerConfigurationOverrider<R> replacingNamedDependentResourceConfig(String name,
176179
Object dependentResourceConfig) {
177180

178-
final var specs = original.getDependentResources();
181+
final var specs = original.getWorkflowSpec().orElseThrow().getDependentResourceSpecs();
179182
final var spec = specs.stream()
180183
.filter(drs -> drs.getName().equals(name)).findFirst()
181184
.orElseThrow(
@@ -193,9 +196,9 @@ public ControllerConfiguration<R> build() {
193196
name,
194197
generationAware, original.getAssociatedReconcilerClassName(), retry, rateLimiter,
195198
reconciliationMaxInterval, onAddFilter, onUpdateFilter, genericFilter,
196-
original.getDependentResources(),
197199
namespaces, finalizer, labelSelector, configurations, itemStore, fieldManager,
198-
original.getConfigurationService(), informerListLimit);
200+
original.getConfigurationService(), informerListLimit,
201+
original.getWorkflowSpec().orElse(null));
199202
}
200203

201204
public static <R extends HasMetadata> ControllerConfigurationOverrider<R> override(

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ResolvedControllerConfiguration.java

+13-12
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import io.fabric8.kubernetes.client.informers.cache.ItemStore;
99
import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceConfigurationProvider;
1010
import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec;
11+
import io.javaoperatorsdk.operator.api.config.workflow.WorkflowSpec;
1112
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
1213
import io.javaoperatorsdk.operator.processing.event.rate.RateLimiter;
1314
import io.javaoperatorsdk.operator.processing.event.source.filter.GenericFilter;
@@ -32,20 +33,19 @@ public class ResolvedControllerConfiguration<P extends HasMetadata>
3233
private final ItemStore<P> itemStore;
3334
private final ConfigurationService configurationService;
3435
private final String fieldManager;
35-
36-
private List<DependentResourceSpec> dependentResources;
36+
private WorkflowSpec workflowSpec;
3737

3838
public ResolvedControllerConfiguration(Class<P> resourceClass, ControllerConfiguration<P> other) {
3939
this(resourceClass, other.getName(), other.isGenerationAware(),
4040
other.getAssociatedReconcilerClassName(), other.getRetry(), other.getRateLimiter(),
4141
other.maxReconciliationInterval().orElse(null),
4242
other.onAddFilter().orElse(null), other.onUpdateFilter().orElse(null),
4343
other.genericFilter().orElse(null),
44-
other.getDependentResources(), other.getNamespaces(),
44+
other.getNamespaces(),
4545
other.getFinalizerName(), other.getLabelSelector(), Collections.emptyMap(),
4646
other.getItemStore().orElse(null), other.fieldManager(),
4747
other.getConfigurationService(),
48-
other.getInformerListLimit().orElse(null));
48+
other.getInformerListLimit().orElse(null), other.getWorkflowSpec().orElse(null));
4949
}
5050

5151
public static Duration getMaxReconciliationInterval(long interval, TimeUnit timeUnit) {
@@ -70,16 +70,16 @@ public ResolvedControllerConfiguration(Class<P> resourceClass, String name,
7070
RateLimiter rateLimiter, Duration maxReconciliationInterval,
7171
OnAddFilter<? super P> onAddFilter, OnUpdateFilter<? super P> onUpdateFilter,
7272
GenericFilter<? super P> genericFilter,
73-
List<DependentResourceSpec> dependentResources,
7473
Set<String> namespaces, String finalizer, String labelSelector,
7574
Map<DependentResourceSpec, Object> configurations, ItemStore<P> itemStore,
7675
String fieldManager,
77-
ConfigurationService configurationService, Long informerListLimit) {
76+
ConfigurationService configurationService, Long informerListLimit,
77+
WorkflowSpec workflowSpec) {
7878
this(resourceClass, name, generationAware, associatedReconcilerClassName, retry, rateLimiter,
7979
maxReconciliationInterval, onAddFilter, onUpdateFilter, genericFilter,
8080
namespaces, finalizer, labelSelector, configurations, itemStore, fieldManager,
8181
configurationService, informerListLimit);
82-
setDependentResources(dependentResources);
82+
setWorkflowSpec(workflowSpec);
8383
}
8484

8585
protected ResolvedControllerConfiguration(Class<P> resourceClass, String name,
@@ -105,6 +105,7 @@ protected ResolvedControllerConfiguration(Class<P> resourceClass, String name,
105105
this.finalizer =
106106
ControllerConfiguration.ensureValidFinalizerName(finalizer, getResourceTypeName());
107107
this.fieldManager = fieldManager;
108+
this.workflowSpec = workflowSpec;
108109
}
109110

110111
protected ResolvedControllerConfiguration(Class<P> resourceClass, String name,
@@ -144,14 +145,14 @@ public RateLimiter getRateLimiter() {
144145
return rateLimiter;
145146
}
146147

148+
147149
@Override
148-
public List<DependentResourceSpec> getDependentResources() {
149-
return dependentResources;
150+
public Optional<WorkflowSpec> getWorkflowSpec() {
151+
return Optional.ofNullable(workflowSpec);
150152
}
151153

152-
protected void setDependentResources(List<DependentResourceSpec> dependentResources) {
153-
this.dependentResources = dependentResources == null ? Collections.emptyList()
154-
: Collections.unmodifiableList(dependentResources);
154+
public void setWorkflowSpec(WorkflowSpec workflowSpec) {
155+
this.workflowSpec = workflowSpec;
155156
}
156157

157158
@Override
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.javaoperatorsdk.operator.api.config.workflow;
2+
3+
import java.util.List;
4+
5+
import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec;
6+
7+
public class WorkflowSpec {
8+
9+
@SuppressWarnings("rawtypes")
10+
private final List<DependentResourceSpec> dependentResourceSpecs;
11+
12+
public WorkflowSpec(List<DependentResourceSpec> dependentResourceSpecs) {
13+
this.dependentResourceSpecs = dependentResourceSpecs;
14+
}
15+
16+
public List<DependentResourceSpec> getDependentResourceSpecs() {
17+
return dependentResourceSpecs;
18+
}
19+
}

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ControllerConfiguration.java

-10
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import java.lang.annotation.Target;
88

99
import io.fabric8.kubernetes.client.informers.cache.ItemStore;
10-
import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent;
1110
import io.javaoperatorsdk.operator.processing.event.rate.LinearRateLimiter;
1211
import io.javaoperatorsdk.operator.processing.event.rate.RateLimiter;
1312
import io.javaoperatorsdk.operator.processing.event.source.cache.BoundedItemStore;
@@ -93,15 +92,6 @@
9392
MaxReconciliationInterval maxReconciliationInterval() default @MaxReconciliationInterval(
9493
interval = MaxReconciliationInterval.DEFAULT_INTERVAL);
9594

96-
97-
/**
98-
* Optional list of {@link Dependent} configurations which associate a resource type to a
99-
* {@link io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource} implementation
100-
*
101-
* @return the array of {@link Dependent} configurations
102-
*/
103-
Dependent[] dependents() default {};
104-
10595
/**
10696
* Optional {@link Retry} implementation for the associated controller to use.
10797
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.javaoperatorsdk.operator.api.reconciler;
2+
3+
import java.lang.annotation.*;
4+
5+
import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent;
6+
7+
@Inherited
8+
@Retention(RetentionPolicy.RUNTIME)
9+
@Target({ElementType.TYPE})
10+
public @interface Workflow {
11+
12+
Dependent[] dependents();
13+
14+
}

Diff for: operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/ManagedWorkflowFactory.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
package io.javaoperatorsdk.operator.processing.dependent.workflow;
22

3+
import java.util.Optional;
4+
35
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
6+
import io.javaoperatorsdk.operator.api.config.workflow.WorkflowSpec;
47

58
public interface ManagedWorkflowFactory<C extends ControllerConfiguration<?>> {
69

710
@SuppressWarnings({"rawtypes", "unchecked"})
811
ManagedWorkflowFactory DEFAULT = (configuration) -> {
9-
final var dependentResourceSpecs = configuration.getDependentResources();
10-
if (dependentResourceSpecs == null || dependentResourceSpecs.isEmpty()) {
12+
final Optional<WorkflowSpec> workflowSpec = configuration.getWorkflowSpec();
13+
if (workflowSpec.isEmpty()) {
1114
return (ManagedWorkflow) (client, configuration1) -> new DefaultWorkflow(null);
1215
}
1316
ManagedWorkflowSupport support = new ManagedWorkflowSupport();
14-
return support.createWorkflow(dependentResourceSpecs);
17+
return support.createWorkflow(workflowSpec.orElseThrow());
1518
};
1619

1720
@SuppressWarnings("rawtypes")

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import io.fabric8.kubernetes.api.model.HasMetadata;
1313
import io.javaoperatorsdk.operator.OperatorException;
1414
import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec;
15+
import io.javaoperatorsdk.operator.api.config.workflow.WorkflowSpec;
1516

1617
@SuppressWarnings({"rawtypes", "unchecked"})
1718
class ManagedWorkflowSupport {
@@ -38,10 +39,10 @@ public void checkForNameDuplication(List<DependentResourceSpec> dependentResourc
3839
}
3940
}
4041

41-
4242
public <P extends HasMetadata> ManagedWorkflow<P> createWorkflow(
43-
List<DependentResourceSpec> dependentResourceSpecs) {
44-
return createAsDefault(dependentResourceSpecs);
43+
WorkflowSpec workflowSpec) {
44+
45+
return createAsDefault(workflowSpec.getDependentResourceSpecs());
4546
}
4647

4748
<P extends HasMetadata> DefaultManagedWorkflow<P> createAsDefault(

0 commit comments

Comments
 (0)