Skip to content

Commit 1086e72

Browse files
committed
feat(core): pause/resume protocol with ExecutionPhase lifecycle
Clean up code Resolve: #71 Signed-off-by: Aleksandr Suvorov <asuvorov@hensu.io>
1 parent a6d952b commit 1086e72

3 files changed

Lines changed: 13 additions & 18 deletions

File tree

hensu-server/src/main/java/io/hensu/server/workflow/WorkflowService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.hensu.server.workflow;
22

3+
import io.hensu.core.resume.ResumeInput;
34
import jakarta.enterprise.context.ApplicationScoped;
45
import jakarta.inject.Inject;
56
import java.util.List;
@@ -44,8 +45,7 @@ public ExecutionStartResult startExecution(
4445
return executionService.startExecution(tenantId, workflowId, context);
4546
}
4647

47-
public void resumeExecution(
48-
String tenantId, String executionId, io.hensu.core.resume.ResumeInput resumeInput) {
48+
public void resumeExecution(String tenantId, String executionId, ResumeInput resumeInput) {
4949
stateService.resumeExecution(tenantId, executionId, resumeInput);
5050
}
5151

hensu-server/src/test/java/io/hensu/server/api/ExecutionResourceTest.java

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import static org.mockito.Mockito.verify;
1010
import static org.mockito.Mockito.when;
1111

12+
import io.hensu.core.resume.ResumeInput;
1213
import io.hensu.server.security.RequestTenantResolver;
1314
import io.hensu.server.workflow.ExecutionNotFoundException;
1415
import io.hensu.server.workflow.ExecutionOutput;
@@ -88,11 +89,9 @@ void shouldResumeWithApproveDecision() {
8889
assertThat(response.getStatus()).isEqualTo(200);
8990
}
9091

91-
ArgumentCaptor<io.hensu.core.resume.ResumeInput> captor =
92-
ArgumentCaptor.forClass(io.hensu.core.resume.ResumeInput.class);
92+
ArgumentCaptor<ResumeInput> captor = ArgumentCaptor.forClass(ResumeInput.class);
9393
verify(workflowService).resumeExecution(eq("tenant-1"), eq("exec-1"), captor.capture());
94-
assertThat(captor.getValue())
95-
.isInstanceOf(io.hensu.core.resume.ResumeInput.ApplyReview.class);
94+
assertThat(captor.getValue()).isInstanceOf(ResumeInput.ApplyReview.class);
9695
}
9796

9897
@Test
@@ -105,11 +104,9 @@ void shouldResumeWithContextEdits() {
105104
assertThat(response.getStatus()).isEqualTo(200);
106105
}
107106

108-
ArgumentCaptor<io.hensu.core.resume.ResumeInput> captor =
109-
ArgumentCaptor.forClass(io.hensu.core.resume.ResumeInput.class);
107+
ArgumentCaptor<ResumeInput> captor = ArgumentCaptor.forClass(ResumeInput.class);
110108
verify(workflowService).resumeExecution(eq("tenant-1"), eq("exec-1"), captor.capture());
111-
assertThat(captor.getValue())
112-
.isInstanceOf(io.hensu.core.resume.ResumeInput.ApplyContextEdits.class);
109+
assertThat(captor.getValue()).isInstanceOf(ResumeInput.ApplyContextEdits.class);
113110
}
114111

115112
@Test
@@ -118,10 +115,9 @@ void shouldResumeWithNullRequestAsNone() {
118115
assertThat(response.getStatus()).isEqualTo(200);
119116
}
120117

121-
ArgumentCaptor<io.hensu.core.resume.ResumeInput> captor =
122-
ArgumentCaptor.forClass(io.hensu.core.resume.ResumeInput.class);
118+
ArgumentCaptor<ResumeInput> captor = ArgumentCaptor.forClass(ResumeInput.class);
123119
verify(workflowService).resumeExecution(eq("tenant-1"), eq("exec-1"), captor.capture());
124-
assertThat(captor.getValue()).isInstanceOf(io.hensu.core.resume.ResumeInput.None.class);
120+
assertThat(captor.getValue()).isInstanceOf(ResumeInput.None.class);
125121
}
126122

127123
@Test

hensu-server/src/test/java/io/hensu/server/integration/StatePersistenceIntegrationTest.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static org.assertj.core.api.Assertions.assertThat;
44

5+
import io.hensu.core.resume.ResumeInput;
56
import io.hensu.core.state.HensuSnapshot;
67
import io.hensu.core.workflow.Workflow;
78
import io.hensu.server.workflow.ExecutionStartResult;
@@ -55,7 +56,7 @@ void shouldPauseAndResumeOnDifferentInstance() {
5556
// Phase 2: Resume — simulates a different server instance by using the
5657
// persisted snapshot. The TestPauseHandler returns SUCCESS on second call.
5758
workflowService.resumeExecution(
58-
TEST_TENANT, pausedSnapshot.executionId(), io.hensu.core.resume.ResumeInput.NONE);
59+
TEST_TENANT, pausedSnapshot.executionId(), ResumeInput.NONE);
5960

6061
// Verify final snapshot shows completion with both step outputs.
6162
// The repository stores one snapshot per execution ID — the completed
@@ -83,8 +84,7 @@ void shouldPreserveExecutionIdAcrossResume() {
8384
assertThat(paused.get().checkpointReason()).isEqualTo("paused");
8485

8586
// Resume
86-
workflowService.resumeExecution(
87-
TEST_TENANT, result.executionId(), io.hensu.core.resume.ResumeInput.NONE);
87+
workflowService.resumeExecution(TEST_TENANT, result.executionId(), ResumeInput.NONE);
8888

8989
// The completed snapshot should preserve the same workflow ID
9090
List<HensuSnapshot> snapshots =
@@ -106,8 +106,7 @@ void shouldApplyResumeModifications() {
106106
workflowService.resumeExecution(
107107
TEST_TENANT,
108108
result.executionId(),
109-
new io.hensu.core.resume.ResumeInput.ApplyContextEdits(
110-
Map.of("extra", "injected-value")));
109+
new ResumeInput.ApplyContextEdits(Map.of("extra", "injected-value")));
111110

112111
// Verify the injected key is present in the final state
113112
List<HensuSnapshot> snapshots =

0 commit comments

Comments
 (0)