Skip to content

Commit a173dbe

Browse files
Fix Dynamic Update Handler return type (#2210)
1 parent add6c4e commit a173dbe

File tree

2 files changed

+117
-1
lines changed

2 files changed

+117
-1
lines changed

temporal-sdk/src/main/java/io/temporal/workflow/DynamicUpdateHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public interface DynamicUpdateHandler {
3939

4040
default void handleValidate(String updateName, EncodedValues args) {}
4141

42-
EncodedValues handleExecute(String updateName, EncodedValues args);
42+
Object handleExecute(String updateName, EncodedValues args);
4343

4444
/** Returns the actions taken if a workflow exits with a running instance of this handler. */
4545
default HandlerUnfinishedPolicy getUnfinishedPolicy(String updateName) {
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Copyright (C) 2022 Temporal Technologies, Inc. All Rights Reserved.
3+
*
4+
* Copyright (C) 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this material except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
21+
package io.temporal.workflow.updateTest;
22+
23+
import static org.junit.Assert.assertEquals;
24+
25+
import io.temporal.api.common.v1.WorkflowExecution;
26+
import io.temporal.client.*;
27+
import io.temporal.common.converter.EncodedValues;
28+
import io.temporal.testing.internal.SDKTestOptions;
29+
import io.temporal.testing.internal.SDKTestWorkflowRule;
30+
import io.temporal.workflow.CompletablePromise;
31+
import io.temporal.workflow.DynamicUpdateHandler;
32+
import io.temporal.workflow.Workflow;
33+
import io.temporal.workflow.shared.TestWorkflows;
34+
import java.util.ArrayList;
35+
import java.util.List;
36+
import java.util.Optional;
37+
import java.util.UUID;
38+
import java.util.concurrent.ExecutionException;
39+
import org.junit.Assert;
40+
import org.junit.Rule;
41+
import org.junit.Test;
42+
43+
public class DynamicUpdateTest {
44+
@Rule
45+
public SDKTestWorkflowRule testWorkflowRule =
46+
SDKTestWorkflowRule.newBuilder()
47+
.setWorkflowTypes(TestDynamicUpdateWorkflowImpl.class)
48+
.build();
49+
50+
@Test
51+
public void dynamicUpdate() throws ExecutionException, InterruptedException {
52+
String workflowId = UUID.randomUUID().toString();
53+
WorkflowClient workflowClient = testWorkflowRule.getWorkflowClient();
54+
WorkflowOptions options =
55+
SDKTestOptions.newWorkflowOptionsWithTimeouts(testWorkflowRule.getTaskQueue()).toBuilder()
56+
.setWorkflowId(workflowId)
57+
.build();
58+
TestWorkflows.TestWorkflow1 workflow =
59+
workflowClient.newWorkflowStub(TestWorkflows.TestWorkflow1.class, options);
60+
// To execute workflow client.execute() would do. But we want to start workflow and immediately
61+
// return.
62+
WorkflowExecution execution = WorkflowClient.start(workflow::execute, "input");
63+
WorkflowStub stub = WorkflowStub.fromTyped(workflow);
64+
65+
assertEquals(
66+
"update:update input",
67+
stub.startUpdate("update", WorkflowUpdateStage.COMPLETED, String.class, "update input")
68+
.getResultAsync()
69+
.get());
70+
71+
Assert.assertThrows(
72+
WorkflowUpdateException.class,
73+
() ->
74+
stub.startUpdate("reject", WorkflowUpdateStage.COMPLETED, String.class, "update input")
75+
.getResultAsync());
76+
77+
stub.startUpdate("complete", WorkflowUpdateStage.COMPLETED, Void.class).getResultAsync().get();
78+
79+
String result =
80+
testWorkflowRule
81+
.getWorkflowClient()
82+
.newUntypedWorkflowStub(execution, Optional.empty())
83+
.getResult(String.class);
84+
assertEquals(" update complete", result);
85+
}
86+
87+
public static class TestDynamicUpdateWorkflowImpl implements TestWorkflows.TestWorkflow1 {
88+
CompletablePromise<Void> promise = Workflow.newPromise();
89+
List<String> updates = new ArrayList<>();
90+
91+
@Override
92+
public String execute(String input) {
93+
Workflow.registerListener(
94+
new DynamicUpdateHandler() {
95+
@Override
96+
public void handleValidate(String updateName, EncodedValues args) {
97+
if (updateName.equals("reject")) {
98+
throw new IllegalArgumentException("simulated failure");
99+
}
100+
}
101+
102+
@Override
103+
public Object handleExecute(String updateName, EncodedValues args) {
104+
updates.add(updateName);
105+
if (updateName.equals("complete")) {
106+
promise.complete(null);
107+
return null;
108+
}
109+
return "update:" + args.get(0, String.class);
110+
}
111+
});
112+
promise.get();
113+
return updates.stream().reduce("", (a, b) -> a + " " + b);
114+
}
115+
}
116+
}

0 commit comments

Comments
 (0)