Skip to content

Commit 6eeb8e1

Browse files
committed
HelloSignalWithStartAndWorkflowInit sample
Signed-off-by: Tihomir Surdilovic <[email protected]>
1 parent 11bbbbe commit 6eeb8e1

File tree

3 files changed

+211
-1
lines changed

3 files changed

+211
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ See the README.md file in each main sample directory for cut/paste Gradle comman
8080
- [**HelloSignalWithTimer**](/core/src/main/java/io/temporal/samples/hello/HelloSignalWithTimer.java): Demonstrates how to use collect signals for certain amount of time and then process last one.
8181
- [**HelloWorkflowTimer**](/core/src/main/java/io/temporal/samples/hello/HelloWorkflowTimer.java): Demonstrates how we can use workflow timer to restrict duration of workflow execution instead of workflow run/execution timeouts.
8282
- [**Auto-Heartbeating**](/core/src/main/java/io/temporal/samples/autoheartbeat/): Demonstrates use of Auto-heartbeating utility via activity interceptor.
83-
83+
- [**HelloSignalWithStartAndWorkflowInit**](/core/src/main/java/io/temporal/samples/hello): Demonstrates how WorkflowInit can be useful with SignalWithStart to initialize workflow variables.
8484

8585
#### Scenario-based samples
8686

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
package io.temporal.samples.hello;
2+
3+
import io.temporal.activity.ActivityInterface;
4+
import io.temporal.activity.ActivityOptions;
5+
import io.temporal.client.WorkflowClient;
6+
import io.temporal.client.WorkflowFailedException;
7+
import io.temporal.client.WorkflowOptions;
8+
import io.temporal.client.WorkflowStub;
9+
import io.temporal.serviceclient.WorkflowServiceStubs;
10+
import io.temporal.worker.Worker;
11+
import io.temporal.worker.WorkerFactory;
12+
import io.temporal.worker.WorkflowImplementationOptions;
13+
import io.temporal.workflow.*;
14+
import java.time.Duration;
15+
import java.util.ArrayList;
16+
import java.util.List;
17+
import org.apache.commons.lang.StringUtils;
18+
19+
/**
20+
* Sample Temporal workflow that demonstrates how to use WorkflowInit with clients starting
21+
* execution using SignalWithStart
22+
*/
23+
public class HelloSignalWithStartAndWorkflowInit {
24+
static final String TASK_QUEUE = "HelloWithInitTaskQueue";
25+
static final String WORKFLOW_ID = "HelloWithInitWorkflowId";
26+
27+
public interface MyWorkflow {
28+
@WorkflowMethod
29+
String greet(Person person);
30+
31+
@SignalMethod
32+
void addGreeting(Person person);
33+
}
34+
35+
@WorkflowInterface
36+
public interface MyWorkflowWithInit extends MyWorkflow {}
37+
38+
@WorkflowInterface
39+
public interface MyWorkflowNoInit extends MyWorkflow {}
40+
41+
public static class WithInitMyWorkflowImpl implements MyWorkflowWithInit {
42+
// We dont initialize peopleToGreet on purpose
43+
private List<Person> peopleToGreet;
44+
private MyGreetingActivities activities =
45+
Workflow.newActivityStub(
46+
MyGreetingActivities.class,
47+
ActivityOptions.newBuilder().setStartToCloseTimeout(Duration.ofSeconds(2)).build());
48+
49+
@WorkflowInit
50+
public WithInitMyWorkflowImpl(Person person) {
51+
peopleToGreet = new ArrayList<>();
52+
}
53+
54+
@Override
55+
public String greet(Person person) {
56+
peopleToGreet.add(person);
57+
List<String> greetings = new ArrayList<>();
58+
59+
while (!peopleToGreet.isEmpty()) {
60+
// run activity...
61+
greetings.add(activities.greet(peopleToGreet.get(0)));
62+
peopleToGreet.remove(0);
63+
}
64+
return StringUtils.join(greetings, ",");
65+
}
66+
67+
@Override
68+
public void addGreeting(Person person) {
69+
peopleToGreet.add(person);
70+
}
71+
}
72+
73+
public static class WithoutInitMyWorkflowImpl implements MyWorkflowNoInit {
74+
// We dont initialize peopleToGreet on purpose
75+
private List<Person> peopleToGreet;
76+
private MyGreetingActivities activities =
77+
Workflow.newActivityStub(
78+
MyGreetingActivities.class,
79+
ActivityOptions.newBuilder().setStartToCloseTimeout(Duration.ofSeconds(2)).build());
80+
81+
@Override
82+
public String greet(Person person) {
83+
peopleToGreet.add(person);
84+
List<String> greetings = new ArrayList<>();
85+
86+
while (!peopleToGreet.isEmpty()) {
87+
// run activity...
88+
greetings.add(activities.greet(peopleToGreet.get(0)));
89+
peopleToGreet.remove(0);
90+
}
91+
return StringUtils.join(greetings, ",");
92+
}
93+
94+
@Override
95+
public void addGreeting(Person person) {
96+
peopleToGreet.add(person);
97+
}
98+
}
99+
100+
@ActivityInterface
101+
public interface MyGreetingActivities {
102+
public String greet(Person person);
103+
}
104+
105+
public static class MyGreetingActivitiesImpl implements MyGreetingActivities {
106+
@Override
107+
public String greet(Person person) {
108+
return "Hello " + person.firstName + " " + person.lastName;
109+
}
110+
}
111+
112+
public static class Person {
113+
String firstName;
114+
String lastName;
115+
int age;
116+
117+
public Person() {}
118+
119+
public Person(String firstName, String lastName, int age) {
120+
this.firstName = firstName;
121+
this.lastName = lastName;
122+
this.age = age;
123+
}
124+
125+
public String getFirstName() {
126+
return firstName;
127+
}
128+
129+
public void setFirstName(String firstName) {
130+
this.firstName = firstName;
131+
}
132+
133+
public String getLastName() {
134+
return lastName;
135+
}
136+
137+
public void setLastName(String lastName) {
138+
this.lastName = lastName;
139+
}
140+
141+
public int getAge() {
142+
return age;
143+
}
144+
145+
public void setAge(int age) {
146+
this.age = age;
147+
}
148+
}
149+
150+
public static void main(String[] args) {
151+
WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs();
152+
WorkflowClient client = WorkflowClient.newInstance(service);
153+
WorkerFactory factory = WorkerFactory.newInstance(client);
154+
Worker worker = factory.newWorker(TASK_QUEUE);
155+
156+
worker.registerWorkflowImplementationTypes(WithInitMyWorkflowImpl.class);
157+
// We explicitly want to fail this workflow on NPE as thats what we expect without WorkflowInit
158+
// As we didnt initialize peopleToGreet on purpose
159+
worker.registerWorkflowImplementationTypes(
160+
WorkflowImplementationOptions.newBuilder()
161+
.setFailWorkflowExceptionTypes(NullPointerException.class)
162+
.build(),
163+
WithoutInitMyWorkflowImpl.class);
164+
worker.registerActivitiesImplementations(new MyGreetingActivitiesImpl());
165+
166+
factory.start();
167+
168+
MyWorkflowWithInit withInitStub =
169+
client.newWorkflowStub(
170+
MyWorkflowWithInit.class,
171+
WorkflowOptions.newBuilder()
172+
.setWorkflowId("with-init")
173+
.setTaskQueue(TASK_QUEUE)
174+
.build());
175+
// Start with init workflow which is expected to succeed
176+
// As WorkflowInit will initialize peopleToGreet before signal handler is invoked
177+
WorkflowStub.fromTyped(withInitStub)
178+
.signalWithStart(
179+
"addGreeting",
180+
new Object[] {new Person("Michael", "Jordan", 55)},
181+
new Object[] {new Person("John", "Stockton", 57)});
182+
183+
String result = WorkflowStub.fromTyped(withInitStub).getResult(String.class);
184+
System.out.println("Result: " + result);
185+
186+
// Start without init, this execution is expected to fail as we set
187+
// NullPointerException as a workflow failure type
188+
// NPE is caused because we did not initialize peopleToGreet array
189+
MyWorkflowNoInit noInitStub =
190+
client.newWorkflowStub(
191+
MyWorkflowNoInit.class,
192+
WorkflowOptions.newBuilder()
193+
.setWorkflowId("with-init")
194+
.setTaskQueue(TASK_QUEUE)
195+
.build());
196+
WorkflowStub.fromTyped(noInitStub)
197+
.signalWithStart(
198+
"addGreeting",
199+
new Object[] {new Person("Michael", "Jordan", 55)},
200+
new Object[] {new Person("John", "Stockton", 57)});
201+
try {
202+
WorkflowStub.fromTyped(noInitStub).getResult(String.class);
203+
} catch (WorkflowFailedException e) {
204+
System.out.println("Expected workflow failure: " + e.getMessage());
205+
}
206+
207+
System.exit(0);
208+
}
209+
}

core/src/main/java/io/temporal/samples/hello/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,5 @@ To run each hello world sample, use one of the following commands:
3434
./gradlew -q execute -PmainClass=io.temporal.samples.hello.HelloSideEffect
3535
./gradlew -q execute -PmainClass=io.temporal.samples.hello.HelloUpdate
3636
./gradlew -q execute -PmainClass=io.temporal.samples.hello.HelloSignalWithTimer
37+
./gradlew -q execute -PmainClass=io.temporal.samples.hello.HelloSignalWithStartAndWorkflowInit
3738
```

0 commit comments

Comments
 (0)