diff --git a/temporal-sdk/src/main/java/io/temporal/client/WorkflowClient.java b/temporal-sdk/src/main/java/io/temporal/client/WorkflowClient.java index fa52b8bb0..1eb12a15b 100644 --- a/temporal-sdk/src/main/java/io/temporal/client/WorkflowClient.java +++ b/temporal-sdk/src/main/java/io/temporal/client/WorkflowClient.java @@ -167,13 +167,13 @@ static WorkflowClient newInstance(WorkflowServiceStubs service, WorkflowClientOp T newWorkflowStub(Class workflowInterface, String workflowId); /** - * Creates workflow client stub for a known execution. Use it to send signals or queries to a - * running workflow. Do not call methods annotated with @WorkflowMethod. + * Creates workflow client stub for a known execution. Use it to send signals, updates, or queries + * to a running workflow. Do not call methods annotated with @WorkflowMethod. * * @param workflowInterface interface that given workflow implements. * @param workflowId Workflow id. * @param runId Run id of the workflow execution. - * @return Stub that implements workflowInterface and can be used to signal or query it. + * @return Stub that implements workflowInterface and can be used to signal, update, or query it. */ T newWorkflowStub(Class workflowInterface, String workflowId, Optional runId); diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateTest.java index 8e8c1b670..9be543336 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateTest.java @@ -21,9 +21,14 @@ package io.temporal.workflow.updateTest; import static org.junit.Assert.*; +import static org.junit.Assume.assumeTrue; import io.temporal.activity.*; import io.temporal.api.common.v1.WorkflowExecution; +import io.temporal.api.enums.v1.ResetReapplyExcludeType; +import io.temporal.api.enums.v1.ResetReapplyType; +import io.temporal.api.workflowservice.v1.ResetWorkflowExecutionRequest; +import io.temporal.api.workflowservice.v1.ResetWorkflowExecutionResponse; import io.temporal.client.*; import io.temporal.failure.ApplicationFailure; import io.temporal.testing.internal.SDKTestOptions; @@ -35,10 +40,7 @@ import io.temporal.workflow.shared.TestWorkflows; import io.temporal.workflow.shared.TestWorkflows.WorkflowWithUpdate; import java.time.Duration; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.UUID; +import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.Future; @@ -143,6 +145,53 @@ public void testUpdateUntyped() throws ExecutionException, InterruptedException assertEquals("Execute-Hello Execute-World", workflowStub.getResult(String.class)); } + @Test + public void testUpdateResets() { + assumeTrue( + "Test Server doesn't support reset workflow", SDKTestWorkflowRule.useExternalService); + String workflowId = UUID.randomUUID().toString(); + WorkflowClient workflowClient = testWorkflowRule.getWorkflowClient(); + WorkflowOptions options = + SDKTestOptions.newWorkflowOptionsWithTimeouts(testWorkflowRule.getTaskQueue()).toBuilder() + .setWorkflowId(workflowId) + .build(); + WorkflowWithUpdate workflow = workflowClient.newWorkflowStub(WorkflowWithUpdate.class, options); + WorkflowExecution execution = WorkflowClient.start(workflow::execute); + + SDKTestWorkflowRule.waitForOKQuery(workflow); + assertEquals("initial", workflow.getState()); + + assertEquals(workflowId, execution.getWorkflowId()); + + assertEquals("Execute-Hello Update", workflow.update(0, "Hello Update")); + + // Reset the workflow + ResetWorkflowExecutionResponse resetResponse = + workflowClient + .getWorkflowServiceStubs() + .blockingStub() + .resetWorkflowExecution( + ResetWorkflowExecutionRequest.newBuilder() + .setNamespace(SDKTestWorkflowRule.NAMESPACE) + .setReason("Integration test") + .setWorkflowExecution(execution) + .setWorkflowTaskFinishEventId(4) + .setRequestId(UUID.randomUUID().toString()) + .setResetReapplyType(ResetReapplyType.RESET_REAPPLY_TYPE_ALL_ELIGIBLE) + .addAllResetReapplyExcludeTypes( + Collections.singletonList( + ResetReapplyExcludeType.RESET_REAPPLY_EXCLUDE_TYPE_SIGNAL)) + .build()); + // Create a new workflow stub with the new run ID + workflow = + workflowClient.newWorkflowStub( + WorkflowWithUpdate.class, workflowId, Optional.of(resetResponse.getRunId())); + assertEquals("Execute-Hello Update 2", workflow.update(0, "Hello Update 2")); + // Complete would throw an exception if the update was not applied to the reset workflow. + workflow.complete(); + assertEquals("Execute-Hello Update Execute-Hello Update 2", workflow.execute()); + } + @Test public void testUpdateHandleNotReturnedUntilCompleteWhenAsked() throws ExecutionException, InterruptedException {