Skip to content

Commit d5c5c8b

Browse files
committed
chore(docs): document ResultCondition and how to use it
Signed-off-by: Chris Laprun <claprun@redhat.com>
1 parent a64b290 commit d5c5c8b

File tree

5 files changed

+77
-9
lines changed

5 files changed

+77
-9
lines changed

docs/content/en/docs/workflows/_index.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,26 @@ reconciliation process.
4949
See related [integration test](https://github.com/operator-framework/java-operator-sdk/blob/ba5e33527bf9e3ea0bd33025ccb35e677f9d44b4/operator-framework/src/test/java/io/javaoperatorsdk/operator/CRDPresentActivationConditionIT.java).
5050

5151
To have multiple resources of same type with an activation condition is a bit tricky, since you
52-
don't want to have multiple `InformerEvetnSource` for the same type, you have to explicitly
52+
don't want to have multiple `InformerEventSource` for the same type, you have to explicitly
5353
name the informer for the Dependent Resource (`@KubernetesDependent(informerConfig = @InformerConfig(name = "configMapInformer"))`)
5454
for all resource of same type with activation condition. This will make sure that only one is registered.
5555
See details at [low level api](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventSourceRetriever.java#L20-L52).
5656

57+
### Result conditions
58+
59+
While simple conditions are usually enough, it might happen you want to convey extra information as a result of the
60+
evaluation of the conditions (e.g., to report error messages or because the result of the condition evaluation might be
61+
interesting for other purposes). In this situation, you should implement `ResultCondition` instead of `Condition` and
62+
provide an implementation of the `detailedIsMet` method, which allows you to return a more detailed `Result` object via
63+
which you can provide extra information. The `ResultCondition.Result` interface provides factory method for your
64+
convenience but you can also provide your own implementation if required.
65+
66+
You can access the results for conditions from the `WorkflowResult` instance that is returned whenever a workflow is
67+
evaluated. You can access that result from the `ManagedWorkflowAndDependentResourceContext` accessible from the
68+
reconciliation `Context`. You can then access individual condition results using the `
69+
getDependentConditionResult` methods. You can see an example of this
70+
in [this integration test](https://github.com/operator-framework/java-operator-sdk/blob/fd0e92c0de55c47d5df50658cf4e147ee5e6102d/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/workflowallfeature/WorkflowAllFeatureReconciler.java#L44-L49).
71+
5772
## Defining Workflows
5873

5974
Similarly to dependent resources, there are two ways to define workflows, in managed and standalone

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public DefaultResult(boolean success, T result) {
1010
}
1111

1212
@Override
13-
public T getResult() {
13+
public T getDetail() {
1414
return result;
1515
}
1616

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

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,87 @@
44
import io.javaoperatorsdk.operator.api.reconciler.Context;
55
import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource;
66

7+
/**
8+
* A condition that can return extra information in addition of whether it is met or not.
9+
*
10+
* @param <R> the resource type this condition applies to
11+
* @param <P> the primary resource type associated with the dependent workflow this condition is
12+
* part of
13+
* @param <T> the type of the extra information returned by the condition
14+
*/
715
public interface ResultCondition<R, P extends HasMetadata, T> extends Condition<R, P> {
16+
17+
/**
18+
* Checks whether a condition holds true for the specified {@link DependentResource}, returning
19+
* additional information as needed.
20+
*
21+
* @param dependentResource the {@link DependentResource} for which we want to check the condition
22+
* @param primary the primary resource being considered
23+
* @param context the current reconciliation {@link Context}
24+
* @return a {@link Result} instance containing the result of the evaluation of the condition as
25+
* well as additional detail
26+
* @see Condition#isMet(DependentResource, HasMetadata, Context)
27+
*/
828
Result<T> detailedIsMet(DependentResource<R, P> dependentResource, P primary, Context<P> context);
929

1030
@Override
1131
default boolean isMet(DependentResource<R, P> dependentResource, P primary, Context<P> context) {
1232
return detailedIsMet(dependentResource, primary, context).isSuccess();
1333
}
1434

35+
/**
36+
* Holds a more detailed {@link Condition} result.
37+
*
38+
* @param <T> the type of the extra information provided in condition evaluation
39+
*/
1540
@SuppressWarnings({"rawtypes", "unchecked"})
1641
interface Result<T> {
42+
/**
43+
* A result expressing a condition has been met without extra information
44+
*/
1745
ResultCondition.Result metWithoutResult = new DefaultResult(true, null);
1846

47+
/**
48+
* A result expressing a condition has not been met without extra information
49+
*/
1950
ResultCondition.Result unmetWithoutResult = new DefaultResult(false, null);
2051

52+
/**
53+
* Creates a {@link Result} without extra information
54+
*
55+
* @param success whether or not the condition has been met
56+
* @return a {@link Result} without extra information
57+
*/
2158
static Result withoutResult(boolean success) {
2259
return success ? metWithoutResult : unmetWithoutResult;
2360
}
2461

25-
static <T> Result<T> withResult(boolean success, T result) {
26-
return new DefaultResult<>(success, result);
62+
/**
63+
* Creates a {@link Result} with the specified condition evaluation result and extra information
64+
*
65+
* @param success whether or not the condition has been met
66+
* @param detail the extra information that the condition provided during its evaluation
67+
* @return a {@link Result} with the specified condition evaluation result and extra information
68+
* @param <T> the type of the extra information provided by the condition
69+
*/
70+
static <T> Result<T> withResult(boolean success, T detail) {
71+
return new DefaultResult<>(success, detail);
2772
}
2873

2974
default String asString() {
30-
return "Result: " + getResult() + " met: " + isSuccess();
75+
return "Detail: " + getDetail() + " met: " + isSuccess();
3176
}
3277

33-
T getResult();
78+
/**
79+
* The extra information provided by the associated {@link ResultCondition} during its evaluation
80+
* @return extra information provided by the associated {@link ResultCondition} during its evaluation or {@code null} if none was provided
81+
*/
82+
T getDetail();
3483

84+
/**
85+
* Whether the associated condition held true
86+
* @return {@code true} if the associated condition was met, {@code false} otherwise
87+
*/
3588
boolean isSuccess();
3689
}
3790
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public <T> Optional<T> getDependentConditionResult(DependentResource dependentRe
9090
try {
9191
return Optional.ofNullable(results().get(dependentResource))
9292
.flatMap(detail -> detail.getResultForConditionWithType(conditionType))
93-
.map(r -> result[0] = r.getResult())
93+
.map(r -> result[0] = r.getDetail())
9494
.map(expectedResultType::cast);
9595
} catch (Exception e) {
9696
throw new IllegalArgumentException("Condition " +

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutorTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ public Result<Object> detailedIsMet(DependentResource<Object, HasMetadata> depen
600600
HasMetadata primary, Context<HasMetadata> context) {
601601
return new Result<>() {
602602
@Override
603-
public Object getResult() {
603+
public Object getDetail() {
604604
return result;
605605
}
606606

@@ -630,7 +630,7 @@ public Result<Object> detailedIsMet(DependentResource<Object, HasMetadata> depen
630630
HasMetadata primary, Context<HasMetadata> context) {
631631
return new Result<>() {
632632
@Override
633-
public Object getResult() {
633+
public Object getDetail() {
634634
return result;
635635
}
636636

0 commit comments

Comments
 (0)