Skip to content

feat: explicit node configuration in WorkflowBuilder #2511

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

Merged
merged 2 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,50 +17,25 @@ public class WorkflowBuilder<P extends HasMetadata> {
private final Map<String, DependentResourceNode<?, P>> dependentResourceNodes =
new HashMap<>();
private boolean throwExceptionAutomatically = THROW_EXCEPTION_AUTOMATICALLY_DEFAULT;
private DependentResourceNode currentNode;
private boolean isCleaner = false;

public WorkflowBuilder<P> addDependentResource(DependentResource dependentResource) {
currentNode = new DependentResourceNode<>(dependentResource);
isCleaner = isCleaner || dependentResource.isDeletable();
final var actualName = dependentResource.name();
dependentResourceNodes.put(actualName, currentNode);
return this;
}

public WorkflowBuilder<P> dependsOn(Set<DependentResource> dependentResources) {
for (var dependentResource : dependentResources) {
var dependsOn = getNodeByDependentResource(dependentResource);
currentNode.addDependsOnRelation(dependsOn);
}
return this;
}

public WorkflowBuilder<P> dependsOn(DependentResource... dependentResources) {
if (dependentResources != null) {
return dependsOn(new HashSet<>(Arrays.asList(dependentResources)));
}
return this;
public WorkflowNodeConfigurationBuilder addDependentResourceAndConfigure(
DependentResource dependentResource) {
final var currentNode = doAddDependentResource(dependentResource);
return new WorkflowNodeConfigurationBuilder(currentNode);
}

public WorkflowBuilder<P> withReconcilePrecondition(Condition reconcilePrecondition) {
currentNode.setReconcilePrecondition(reconcilePrecondition);
return this;
}

public WorkflowBuilder<P> withReadyPostcondition(Condition readyPostcondition) {
currentNode.setReadyPostcondition(readyPostcondition);
return this;
}

public WorkflowBuilder<P> withDeletePostcondition(Condition deletePostcondition) {
currentNode.setDeletePostcondition(deletePostcondition);
public WorkflowBuilder<P> addDependentResource(DependentResource dependentResource) {
doAddDependentResource(dependentResource);
return this;
}

public WorkflowBuilder<P> withActivationCondition(Condition activationCondition) {
currentNode.setActivationCondition(activationCondition);
return this;
private DependentResourceNode doAddDependentResource(DependentResource dependentResource) {
final var currentNode = new DependentResourceNode<>(dependentResource);
isCleaner = isCleaner || dependentResource.isDeletable();
final var actualName = dependentResource.name();
dependentResourceNodes.put(actualName, currentNode);
return currentNode;
}

DependentResourceNode getNodeByDependentResource(DependentResource<?, ?> dependentResource) {
Expand Down Expand Up @@ -89,4 +64,70 @@ DefaultWorkflow<P> buildAsDefaultWorkflow() {
return new DefaultWorkflow(new HashSet<>(dependentResourceNodes.values()),
throwExceptionAutomatically, isCleaner);
}

public class WorkflowNodeConfigurationBuilder {
private final DependentResourceNode currentNode;

private WorkflowNodeConfigurationBuilder(DependentResourceNode currentNode) {
this.currentNode = currentNode;
}

public WorkflowBuilder<P> addDependentResource(DependentResource<?, ?> dependentResource) {
return WorkflowBuilder.this.addDependentResource(dependentResource);
}

public WorkflowNodeConfigurationBuilder addDependentResourceAndConfigure(
DependentResource<?, ?> dependentResource) {
final var currentNode = WorkflowBuilder.this.doAddDependentResource(dependentResource);
return new WorkflowNodeConfigurationBuilder(currentNode);
}

public Workflow<P> build() {
return WorkflowBuilder.this.build();
}

DefaultWorkflow<P> buildAsDefaultWorkflow() {
return WorkflowBuilder.this.buildAsDefaultWorkflow();
}

public WorkflowBuilder<P> withThrowExceptionFurther(boolean throwExceptionFurther) {
return WorkflowBuilder.this.withThrowExceptionFurther(throwExceptionFurther);
}

public WorkflowNodeConfigurationBuilder toDependOn(Set<DependentResource> dependentResources) {
for (var dependentResource : dependentResources) {
var dependsOn = getNodeByDependentResource(dependentResource);
currentNode.addDependsOnRelation(dependsOn);
}
return this;
}

public WorkflowNodeConfigurationBuilder toDependOn(DependentResource... dependentResources) {
if (dependentResources != null) {
return toDependOn(new HashSet<>(Arrays.asList(dependentResources)));
}
return this;
}

public WorkflowNodeConfigurationBuilder withReconcilePrecondition(
Condition reconcilePrecondition) {
currentNode.setReconcilePrecondition(reconcilePrecondition);
return this;
}

public WorkflowNodeConfigurationBuilder withReadyPostcondition(Condition readyPostcondition) {
currentNode.setReadyPostcondition(readyPostcondition);
return this;
}

public WorkflowNodeConfigurationBuilder withDeletePostcondition(Condition deletePostcondition) {
currentNode.setDeletePostcondition(deletePostcondition);
return this;
}

public WorkflowNodeConfigurationBuilder withActivationCondition(Condition activationCondition) {
currentNode.setActivationCondition(activationCondition);
return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ void setup() {
void cleanUpDiamondWorkflow() {
var workflow = new WorkflowBuilder<TestCustomResource>()
.addDependentResource(dd1)
.addDependentResource(dr1).dependsOn(dd1)
.addDependentResource(dd2).dependsOn(dd1)
.addDependentResource(dd3).dependsOn(dr1, dd2)
.addDependentResourceAndConfigure(dr1).toDependOn(dd1)
.addDependentResourceAndConfigure(dd2).toDependOn(dd1)
.addDependentResourceAndConfigure(dd3).toDependOn(dr1, dd2)
.build();

var res = workflow.cleanup(new TestCustomResource(), mockContext);
Expand All @@ -73,9 +73,9 @@ void cleanUpDiamondWorkflow() {
void dontDeleteIfDependentErrored() {
var workflow = new WorkflowBuilder<TestCustomResource>()
.addDependentResource(dd1)
.addDependentResource(dd2).dependsOn(dd1)
.addDependentResource(dd3).dependsOn(dd2)
.addDependentResource(errorDD).dependsOn(dd2)
.addDependentResourceAndConfigure(dd2).toDependOn(dd1)
.addDependentResourceAndConfigure(dd3).toDependOn(dd2)
.addDependentResourceAndConfigure(errorDD).toDependOn(dd2)
.withThrowExceptionFurther(false)
.build();

Expand All @@ -95,7 +95,8 @@ void dontDeleteIfDependentErrored() {
void cleanupConditionTrivialCase() {
var workflow = new WorkflowBuilder<TestCustomResource>()
.addDependentResource(dd1)
.addDependentResource(dd2).dependsOn(dd1).withDeletePostcondition(notMetCondition)
.addDependentResourceAndConfigure(dd2).toDependOn(dd1)
.withDeletePostcondition(notMetCondition)
.build();

var res = workflow.cleanup(new TestCustomResource(), mockContext);
Expand All @@ -110,7 +111,7 @@ void cleanupConditionTrivialCase() {
void cleanupConditionMet() {
var workflow = new WorkflowBuilder<TestCustomResource>()
.addDependentResource(dd1)
.addDependentResource(dd2).dependsOn(dd1).withDeletePostcondition(metCondition)
.addDependentResourceAndConfigure(dd2).toDependOn(dd1).withDeletePostcondition(metCondition)
.build();

var res = workflow.cleanup(new TestCustomResource(), mockContext);
Expand All @@ -126,9 +127,10 @@ void cleanupConditionMet() {
void cleanupConditionDiamondWorkflow() {
var workflow = new WorkflowBuilder<TestCustomResource>()
.addDependentResource(dd1)
.addDependentResource(dd2).dependsOn(dd1)
.addDependentResource(dd3).dependsOn(dd1).withDeletePostcondition(notMetCondition)
.addDependentResource(dd4).dependsOn(dd2, dd3)
.addDependentResourceAndConfigure(dd2).toDependOn(dd1)
.addDependentResourceAndConfigure(dd3).toDependOn(dd1)
.withDeletePostcondition(notMetCondition)
.addDependentResourceAndConfigure(dd4).toDependOn(dd2, dd3)
.build();

var res = workflow.cleanup(new TestCustomResource(), mockContext);
Expand Down Expand Up @@ -162,10 +164,10 @@ void dontDeleteIfGarbageCollected() {
void ifDependentActiveDependentNormallyDeleted() {
var workflow = new WorkflowBuilder<TestCustomResource>()
.addDependentResource(dd1)
.addDependentResource(dd2).dependsOn(dd1)
.addDependentResource(dd3).dependsOn(dd1)
.addDependentResourceAndConfigure(dd2).toDependOn(dd1)
.addDependentResourceAndConfigure(dd3).toDependOn(dd1)
.withActivationCondition(metCondition)
.addDependentResource(dd4).dependsOn(dd2, dd3)
.addDependentResourceAndConfigure(dd4).toDependOn(dd2, dd3)
.build();

var res = workflow.cleanup(new TestCustomResource(), mockContext);
Expand All @@ -182,11 +184,11 @@ void ifDependentActiveDependentNormallyDeleted() {
void ifDependentActiveDeletePostConditionIsChecked() {
var workflow = new WorkflowBuilder<TestCustomResource>()
.addDependentResource(dd1)
.addDependentResource(dd2).dependsOn(dd1)
.addDependentResource(dd3).dependsOn(dd1)
.addDependentResourceAndConfigure(dd2).toDependOn(dd1)
.addDependentResourceAndConfigure(dd3).toDependOn(dd1)
.withDeletePostcondition(notMetCondition)
.withActivationCondition(metCondition)
.addDependentResource(dd4).dependsOn(dd2, dd3)
.addDependentResourceAndConfigure(dd4).toDependOn(dd2, dd3)
.build();

var res = workflow.cleanup(new TestCustomResource(), mockContext);
Expand All @@ -206,10 +208,10 @@ void ifDependentActiveDeletePostConditionIsChecked() {
void ifDependentInactiveDeleteIsNotCalled() {
var workflow = new WorkflowBuilder<TestCustomResource>()
.addDependentResource(dd1)
.addDependentResource(dd2).dependsOn(dd1)
.addDependentResource(dd3).dependsOn(dd1)
.addDependentResourceAndConfigure(dd2).toDependOn(dd1)
.addDependentResourceAndConfigure(dd3).toDependOn(dd1)
.withActivationCondition(notMetCondition)
.addDependentResource(dd4).dependsOn(dd2, dd3)
.addDependentResourceAndConfigure(dd4).toDependOn(dd2, dd3)
.build();

var res = workflow.cleanup(new TestCustomResource(), mockContext);
Expand All @@ -225,11 +227,11 @@ void ifDependentInactiveDeleteIsNotCalled() {
void ifDependentInactiveDeletePostConditionNotChecked() {
var workflow = new WorkflowBuilder<TestCustomResource>()
.addDependentResource(dd1)
.addDependentResource(dd2).dependsOn(dd1)
.addDependentResource(dd3).dependsOn(dd1)
.addDependentResourceAndConfigure(dd2).toDependOn(dd1)
.addDependentResourceAndConfigure(dd3).toDependOn(dd1)
.withDeletePostcondition(notMetCondition)
.withActivationCondition(notMetCondition)
.addDependentResource(dd4).dependsOn(dd2, dd3)
.addDependentResourceAndConfigure(dd4).toDependOn(dd2, dd3)
.build();

var res = workflow.cleanup(new TestCustomResource(), mockContext);
Expand All @@ -243,7 +245,7 @@ void ifDependentInactiveDeletePostConditionNotChecked() {
@Test
void singleInactiveDependent() {
var workflow = new WorkflowBuilder<TestCustomResource>()
.addDependentResource(dd1)
.addDependentResourceAndConfigure(dd1)
.withActivationCondition(notMetCondition)
.build();

Expand Down
Loading
Loading