-
Notifications
You must be signed in to change notification settings - Fork 219
feat: introduce @Workflow annotation #2209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
dd9dbfd
4887d6c
acdc0c8
a68f96c
b9e55bd
c85b9e0
a264b2a
e636956
51526e0
76cde32
0bc24ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
--- | ||
title: Migrating from v4.7 to v5.0 | ||
description: Migrating from v4.7 to v5.0 | ||
layout: docs | ||
permalink: /docs/v5-0-migration | ||
--- | ||
|
||
# Migrating from v4.7 to v5.0 | ||
|
||
## API Tweaks | ||
|
||
1. [Result of managed dependent resources](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceContext.java#L55-L57) | ||
is not `Optional` anymore. In case you use this result, simply use the result | ||
objects directly. | ||
|
||
2. Workflow is now explicit for managed dependent resources: | ||
So instead (from WebPage sample): | ||
|
||
```java | ||
|
||
@ControllerConfiguration( | ||
dependents = { | ||
@Dependent(type = ConfigMapDependentResource.class), | ||
@Dependent(type = DeploymentDependentResource.class), | ||
@Dependent(type = ServiceDependentResource.class), | ||
@Dependent(type = IngressDependentResource.class, | ||
reconcilePrecondition = ExposedIngressCondition.class) | ||
})) | ||
// Omitted code | ||
``` | ||
|
||
|
||
Now the following structure is used: | ||
|
||
```java | ||
@ControllerConfiguration( | ||
workflow = @Workflow(dependents = { | ||
@Dependent(type = ConfigMapDependentResource.class), | ||
@Dependent(type = DeploymentDependentResource.class), | ||
@Dependent(type = ServiceDependentResource.class), | ||
@Dependent(type = IngressDependentResource.class, | ||
reconcilePrecondition = ExposedIngressCondition.class) | ||
})) | ||
// Omitted code | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,8 +25,6 @@ | |
import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource; | ||
import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition; | ||
import io.javaoperatorsdk.operator.processing.event.rate.RateLimiter; | ||
import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilter; | ||
import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEventFilters; | ||
import io.javaoperatorsdk.operator.processing.event.source.filter.GenericFilter; | ||
import io.javaoperatorsdk.operator.processing.event.source.filter.OnAddFilter; | ||
import io.javaoperatorsdk.operator.processing.event.source.filter.OnUpdateFilter; | ||
|
@@ -163,47 +161,19 @@ protected <P extends HasMetadata> ControllerConfiguration<P> configFor(Reconcile | |
Utils.instantiate(annotation.itemStore(), ItemStore.class, context), dependentFieldManager, | ||
this, informerListLimit); | ||
|
||
ResourceEventFilter<P> answer = deprecatedEventFilter(annotation); | ||
config.setEventFilter(answer != null ? answer : ResourceEventFilters.passthrough()); | ||
|
||
List<DependentResourceSpec> specs = dependentResources(annotation, config); | ||
config.setDependentResources(specs); | ||
|
||
return config; | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
private static <P extends HasMetadata> ResourceEventFilter<P> deprecatedEventFilter( | ||
io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration annotation) { | ||
ResourceEventFilter<P> answer = null; | ||
|
||
Class<ResourceEventFilter<P>>[] filterTypes = | ||
(Class<ResourceEventFilter<P>>[]) valueOrDefault(annotation, | ||
io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::eventFilters, | ||
new Object[] {}); | ||
for (var filterType : filterTypes) { | ||
try { | ||
ResourceEventFilter<P> filter = filterType.getConstructor().newInstance(); | ||
|
||
if (answer == null) { | ||
answer = filter; | ||
} else { | ||
answer = answer.and(filter); | ||
} | ||
} catch (Exception e) { | ||
throw new IllegalArgumentException(e); | ||
} | ||
} | ||
return answer; | ||
} | ||
|
||
@SuppressWarnings({"unchecked", "rawtypes"}) | ||
private static List<DependentResourceSpec> dependentResources( | ||
io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration annotation, | ||
ControllerConfiguration<?> parent) { | ||
final var dependents = | ||
valueOrDefault(annotation, | ||
io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration::dependents, | ||
c -> c.workflow().dependents(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will crash if there is no workflow annotation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a default workflow annotation, with empty dependents. To my understanding that never happens. |
||
new Dependent[] {}); | ||
if (dependents.length == 0) { | ||
return Collections.emptyList(); | ||
|
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH, I'm not convinced that this improves anything. This is more verbose and will require quite a bit of change in lots of places for non-obvious benefits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is required also for this issue:
#1898
That is why it is not just a simple rename.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't follow how this is required for explicit invocation of workflows. There's an implicit workflow being created already so adding an annotation doesn't bring much unless we would like to have data specifically associated with the workflow. That said, even workflow data could be added to the ControllerConfiguration annotation. Adding a new annotation would only make sense if we envisioned to have lots of data associated with workflows and/or if we wanted to have several workflows with different data set, which I don't think we should in either cases.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are multiple aspects of this, why I think this is really beneficial:
what is probably less important is just better domain language, when talking to devs usually they don't get that in the background there is this Workflow that is executes the Dependent resources, so would be nice to have both in the domain language.
Features like this:
In the mentioned link, this is closely related to the workflow, and how it is invoked. It is much nicer to have such configs / feature options put there since its is coupled with the workflow not the controller configuration directly.
I expect that more of such will come in the future, so it is kinda future compatibility also.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if there is no flag like mentioned how can the controller know if the workflow should be executed before
reconcile
method is invoked or it will be invoked manually / explicitly.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By simply having an
explicitWorkflowInvocation
attribute on theControllerConfiguration
annotation without the need for an intermediate annotation.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure but this could be addressed by better documentation 😄
What other attributes would we be adding to the workflow configuration? I don't think that we should be adding complexity just for the sake of potential future features which might never materialize.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see also: #2238 (comment)
It is much nicer and descriptive to have these coupled.
Not sure what is wrong with an intermediate annotation. It is much nicer domain modeling, if we have hierachical structure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we all agree if it is much better if the user does not have to dive into docs, just understands the code based how it is structured.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the explicit domain objects reduce cognitive burden imo, as mentioned, users will create a
@Workflow
and will see what are the related properties and config options. So they don't have to search for (and potintially miss it) in@ControllerConfiguratio