@@ -88,18 +88,18 @@ TOKYO, LONDON, SEATTLE
88
88
In the application output you should see the workflow activities being executed.
89
89
90
90
``` bash
91
- 2025-05-16T09:59:22.176+01:00 INFO 8360 --- [pool-3-thread-1] io.dapr.workflows.WorkflowContext : Starting Workflow: io.dapr.springboot.examples.wfp.chain.ChainWorkflow
92
- 2025-05-16T09:59:22.194+01:00 INFO 8360 --- [nio-8080-exec-2] i.d.s.e.w.WorkflowPatternsRestController : Workflow instance 7625b4af-8c04-408a-93dc-bad753466e43 started
93
- 2025-05-16T09:59:22.195+01:00 INFO 8360 --- [pool-3-thread-2] i.d.s.e.wfp.chain.ToUpperCaseActivity : Starting Activity: io.dapr.springboot.examples.wfp.chain.ToUpperCaseActivity
94
- 2025-05-16T09:59:22.196+01:00 INFO 8360 --- [pool-3-thread-2] i.d.s.e.wfp.chain.ToUpperCaseActivity : Message Received from input: Tokyo
95
- 2025-05-16T09:59:22.197+01:00 INFO 8360 --- [pool-3-thread-2] i.d.s.e.wfp.chain.ToUpperCaseActivity : Sending message to output: TOKYO
96
- 2025-05-16T09:59:22.210+01:00 INFO 8360 --- [pool-3-thread-1] i.d.s.e.wfp.chain.ToUpperCaseActivity : Starting Activity: io.dapr.springboot.examples.wfp.chain.ToUpperCaseActivity
97
- 2025-05-16T09:59:22.210+01:00 INFO 8360 --- [pool-3-thread-1] i.d.s.e.wfp.chain.ToUpperCaseActivity : Message Received from input: London
98
- 2025-05-16T09:59:22.210+01:00 INFO 8360 --- [pool-3-thread-1] i.d.s.e.wfp.chain.ToUpperCaseActivity : Sending message to output: LONDON
99
- 2025-05-16T09:59:22.216+01:00 INFO 8360 --- [pool-3-thread-3] i.d.s.e.wfp.chain.ToUpperCaseActivity : Starting Activity: io.dapr.springboot.examples.wfp.chain.ToUpperCaseActivity
100
- 2025-05-16T09:59:22.216+01:00 INFO 8360 --- [pool-3-thread-3] i.d.s.e.wfp.chain.ToUpperCaseActivity : Message Received from input: Seattle
101
- 2025-05-16T09:59:22.216+01:00 INFO 8360 --- [pool-3-thread-3] i.d.s.e.wfp.chain.ToUpperCaseActivity : Sending message to output: SEATTLE
102
- 2025-05-16T09:59:22.219+01:00 INFO 8360 --- [pool-3-thread-1] io.dapr.workflows.WorkflowContext : Workflow finished with result: TOKYO, LONDON, SEATTLE
91
+ io.dapr.workflows.WorkflowContext : Starting Workflow: io.dapr.springboot.examples.wfp.chain.ChainWorkflow
92
+ i.d.s.e.w.WorkflowPatternsRestController : Workflow instance 7625b4af-8c04-408a-93dc-bad753466e43 started
93
+ i.d.s.e.wfp.chain.ToUpperCaseActivity : Starting Activity: io.dapr.springboot.examples.wfp.chain.ToUpperCaseActivity
94
+ i.d.s.e.wfp.chain.ToUpperCaseActivity : Message Received from input: Tokyo
95
+ i.d.s.e.wfp.chain.ToUpperCaseActivity : Sending message to output: TOKYO
96
+ i.d.s.e.wfp.chain.ToUpperCaseActivity : Starting Activity: io.dapr.springboot.examples.wfp.chain.ToUpperCaseActivity
97
+ i.d.s.e.wfp.chain.ToUpperCaseActivity : Message Received from input: London
98
+ i.d.s.e.wfp.chain.ToUpperCaseActivity : Sending message to output: LONDON
99
+ i.d.s.e.wfp.chain.ToUpperCaseActivity : Starting Activity: io.dapr.springboot.examples.wfp.chain.ToUpperCaseActivity
100
+ i.d.s.e.wfp.chain.ToUpperCaseActivity : Message Received from input: Seattle
101
+ i.d.s.e.wfp.chain.ToUpperCaseActivity : Sending message to output: SEATTLE
102
+ io.dapr.workflows.WorkflowContext : Workflow finished with result: TOKYO, LONDON, SEATTLE
103
103
```
104
104
105
105
### Parent / Child Workflows example
@@ -136,7 +136,6 @@ graph LR
136
136
137
137
To start the parent workflow you can run:
138
138
139
-
140
139
<!-- STEP
141
140
name: Start Parent/Child Workflow
142
141
match_order: none
@@ -167,27 +166,237 @@ As result from executing the request you should see:
167
166
In the application output you should see the workflow activities being executed.
168
167
169
168
``` bash
170
- 2025-05-16T10:27:01.845+01:00 INFO 9855 --- [pool-3-thread-1] io.dapr.workflows.WorkflowContext : Starting Workflow: io.dapr.springboot.examples.wfp.child.ParentWorkflow
171
- 2025-05-16T10:27:01.845+01:00 INFO 9855 --- [pool-3-thread-1] io.dapr.workflows.WorkflowContext : calling childworkflow with input: Hello Dapr Workflow!
172
- 2025-05-16T10:27:01.865+01:00 INFO 9855 --- [nio-8080-exec-1] i.d.s.e.w.WorkflowPatternsRestController : Workflow instance f3ec9566-a0fc-4d28-8912-3f3ded3cd8a9 started
173
- 2025-05-16T10:27:01.866+01:00 INFO 9855 --- [pool-3-thread-2] io.dapr.workflows.WorkflowContext : Starting ChildWorkflow: io.dapr.springboot.examples.wfp.child.ChildWorkflow
174
- 2025-05-16T10:27:01.868+01:00 INFO 9855 --- [pool-3-thread-2] io.dapr.workflows.WorkflowContext : ChildWorkflow received input: Hello Dapr Workflow!
175
- 2025-05-16T10:27:01.868+01:00 INFO 9855 --- [pool-3-thread-2] io.dapr.workflows.WorkflowContext : ChildWorkflow is calling Activity: io.dapr.springboot.examples.wfp.child.ReverseActivity
176
- 2025-05-16T10:27:01.874+01:00 INFO 9855 --- [pool-3-thread-3] i.d.s.e.wfp.child.ReverseActivity : Starting Activity: io.dapr.springboot.examples.wfp.child.ReverseActivity
177
- 2025-05-16T10:27:01.874+01:00 INFO 9855 --- [pool-3-thread-3] i.d.s.e.wfp.child.ReverseActivity : Message Received from input: Hello Dapr Workflow!
178
- 2025-05-16T10:27:01.874+01:00 INFO 9855 --- [pool-3-thread-3] i.d.s.e.wfp.child.ReverseActivity : Sending message to output: ! wolfkroW rpaD olleH
179
- 2025-05-16T10:27:01.882+01:00 INFO 9855 --- [pool-3-thread-1] io.dapr.workflows.WorkflowContext : ChildWorkflow finished with: ! wolfkroW rpaD olleH
180
- 2025-05-16T10:27:01.892+01:00 INFO 9855 --- [pool-3-thread-2] io.dapr.workflows.WorkflowContext : childworkflow finished with: ! wolfkroW rpaD olleH
169
+ io.dapr.workflows.WorkflowContext : Starting Workflow: io.dapr.springboot.examples.wfp.child.ParentWorkflow
170
+ io.dapr.workflows.WorkflowContext : calling childworkflow with input: Hello Dapr Workflow!
171
+ i.d.s.e.w.WorkflowPatternsRestController : Workflow instance f3ec9566-a0fc-4d28-8912-3f3ded3cd8a9 started
172
+ io.dapr.workflows.WorkflowContext : Starting ChildWorkflow: io.dapr.springboot.examples.wfp.child.ChildWorkflow
173
+ io.dapr.workflows.WorkflowContext : ChildWorkflow received input: Hello Dapr Workflow!
174
+ io.dapr.workflows.WorkflowContext : ChildWorkflow is calling Activity: io.dapr.springboot.examples.wfp.child.ReverseActivity
175
+ i.d.s.e.wfp.child.ReverseActivity : Starting Activity: io.dapr.springboot.examples.wfp.child.ReverseActivity
176
+ i.d.s.e.wfp.child.ReverseActivity : Message Received from input: Hello Dapr Workflow!
177
+ i.d.s.e.wfp.child.ReverseActivity : Sending message to output: ! wolfkroW rpaD olleH
178
+ io.dapr.workflows.WorkflowContext : ChildWorkflow finished with: ! wolfkroW rpaD olleH
179
+ io.dapr.workflows.WorkflowContext : childworkflow finished with: ! wolfkroW rpaD olleH
181
180
```
182
181
183
182
### ContinueAsNew Workflows example
184
183
184
+ In this example we start a workflow that every 3 seconds schedule a new workflow consistently. This workflow executes
185
+ one activity called CleanUpActivity that takes 2 seconds to complete. This loops repeat consistently for 5 times.
186
+
187
+ To start the workflow you can run:
188
+
189
+ <!-- STEP
190
+ name: Start ContinueAsNew Workflow
191
+ match_order: none
192
+ output_match_mode: substring
193
+ expected_stdout_lines:
194
+ - '{"cleanUpTimes":5}'
195
+ background: true
196
+ sleep: 1
197
+ timeout_seconds: 2
198
+ -->
199
+ <!-- Timeout for above service must be more than sleep + timeout for the client-->
200
+
201
+ To start the workflow you can run:
202
+
203
+ ``` sh
204
+ curl -X POST localhost:8080/wfp/continueasnew -H ' Content-Type: application/json'
205
+ ```
206
+
207
+ <!-- END_STEP -->
208
+
209
+ As result from executing the request you should see:
210
+
211
+ ``` bash
212
+ {" cleanUpTimes" :5}
213
+ ````
214
+
215
+ In the application output you should see the workflow activities being executed.
216
+
217
+ ` ` ` bash
218
+ io.dapr.workflows.WorkflowContext : Starting Workflow: io.dapr.springboot.examples.wfp.continueasnew.ContinueAsNewWorkflow
219
+ io.dapr.workflows.WorkflowContext : call CleanUpActivity to do the clean up
220
+ i.d.s.e.w.WorkflowPatternsRestController : Workflow instance b808e7d6-ab47-4eba-8188-dc9ff8780764 started
221
+ i.d.s.e.w.continueasnew.CleanUpActivity : Starting Activity: io.dapr.springboot.examples.wfp.continueasnew.CleanUpActivity
222
+ i.d.s.e.w.continueasnew.CleanUpActivity : start clean up work, it may take few seconds to finish... Time:10:48:45
223
+ io.dapr.workflows.WorkflowContext : CleanUpActivity finished
224
+ io.dapr.workflows.WorkflowContext : wait 5 seconds for next clean up
225
+ io.dapr.workflows.WorkflowContext : Let' s do more cleaning.
226
+ io.dapr.workflows.WorkflowContext : Starting Workflow: io.dapr.springboot.examples.wfp.continueasnew.ContinueAsNewWorkflow
227
+ io.dapr.workflows.WorkflowContext : call CleanUpActivity to do the clean up
228
+ i.d.s.e.w.continueasnew.CleanUpActivity : Starting Activity: io.dapr.springboot.examples.wfp.continueasnew.CleanUpActivity
229
+ i.d.s.e.w.continueasnew.CleanUpActivity : start clean up work, it may take few seconds to finish... Time:10:48:50
230
+ io.dapr.workflows.WorkflowContext : CleanUpActivity finished
231
+ io.dapr.workflows.WorkflowContext : wait 5 seconds for next clean up
232
+ io.dapr.workflows.WorkflowContext : Let' s do more cleaning.
233
+ io.dapr.workflows.WorkflowContext : Starting Workflow: io.dapr.springboot.examples.wfp.continueasnew.ContinueAsNewWorkflow
234
+ io.dapr.workflows.WorkflowContext : call CleanUpActivity to do the clean up
235
+ i.d.s.e.w.continueasnew.CleanUpActivity : Starting Activity: io.dapr.springboot.examples.wfp.continueasnew.CleanUpActivity
236
+ i.d.s.e.w.continueasnew.CleanUpActivity : start clean up work, it may take few seconds to finish... Time:10:48:55
237
+ io.dapr.workflows.WorkflowContext : CleanUpActivity finished
238
+ io.dapr.workflows.WorkflowContext : wait 5 seconds for next clean up
239
+ io.dapr.workflows.WorkflowContext : Let' s do more cleaning.
240
+ io.dapr.workflows.WorkflowContext : Starting Workflow: io.dapr.springboot.examples.wfp.continueasnew.ContinueAsNewWorkflow
241
+ io.dapr.workflows.WorkflowContext : call CleanUpActivity to do the clean up
242
+ i.d.s.e.w.continueasnew.CleanUpActivity : Starting Activity: io.dapr.springboot.examples.wfp.continueasnew.CleanUpActivity
243
+ i.d.s.e.w.continueasnew.CleanUpActivity : start clean up work, it may take few seconds to finish... Time:10:49:0
244
+ io.dapr.workflows.WorkflowContext : CleanUpActivity finished
245
+ io.dapr.workflows.WorkflowContext : wait 5 seconds for next clean up
246
+ io.dapr.workflows.WorkflowContext : Let' s do more cleaning.
247
+ io.dapr.workflows.WorkflowContext : Starting Workflow: io.dapr.springboot.examples.wfp.continueasnew.ContinueAsNewWorkflow
248
+ io.dapr.workflows.WorkflowContext : call CleanUpActivity to do the clean up
249
+ i.d.s.e.w.continueasnew.CleanUpActivity : Starting Activity: io.dapr.springboot.examples.wfp.continueasnew.CleanUpActivity
250
+ i.d.s.e.w.continueasnew.CleanUpActivity : start clean up work, it may take few seconds to finish... Time:10:49:5
251
+ io.dapr.workflows.WorkflowContext : CleanUpActivity finished
252
+ io.dapr.workflows.WorkflowContext : wait 5 seconds for next clean up
253
+ io.dapr.workflows.WorkflowContext : We did enough cleaning
254
+ ` ` `
185
255
186
256
# ## External Event Workflow example
187
257
258
+ In this example we start a workflow that as part of its execution waits for an external event to continue. To correlate
259
+ workflows and events we use the parameter ` orderId`
260
+
261
+ To start the workflow you can run:
262
+
263
+ < ! -- STEP
264
+ name: Start External Event Workflow
265
+ match_order: none
266
+ output_match_mode: substring
267
+ background: true
268
+ sleep: 1
269
+ timeout_seconds: 2
270
+ -->
271
+ < ! -- Timeout for above service must be more than sleep + timeout for the client-->
272
+
273
+ To start the workflow you can run:
274
+
275
+ ` ` ` sh
276
+ curl -X POST " localhost:8080/wfp/externalevent?orderId=123" -H ' Content-Type: application/json'
277
+ ` ` `
278
+
279
+ < ! -- END_STEP -->
280
+
281
+
282
+ In the application output you should see the workflow activities being executed.
283
+
284
+ ` ` ` bash
285
+ io.dapr.workflows.WorkflowContext : Starting Workflow: io.dapr.springboot.examples.wfp.externalevent.ExternalEventWorkflow
286
+ io.dapr.workflows.WorkflowContext : Waiting for approval...
287
+ i.d.s.e.w.WorkflowPatternsRestController : Workflow instance 8a55cf6d-9059-49b1-8c83-fbe17567a02e started
288
+ ` ` `
289
+
290
+ You should see the Workflow ID that was created, in this example you don' t need to remember this id,
291
+ as you can use the orderId to find the right instance.
292
+ When you are ready to approve the order you can send the following request:
293
+
294
+ <!-- STEP
295
+ name: Send External Event
296
+ match_order: none
297
+ output_match_mode: substring
298
+ expected_stdout_lines:
299
+ - ' {" approved" :true}'
300
+ background: true
301
+ sleep: 1
302
+ timeout_seconds: 2
303
+ -->
304
+ <!-- Timeout for above service must be more than sleep + timeout for the client-->
305
+
306
+ To send the event you can run:
307
+
308
+ ```sh
309
+ curl -X POST "localhost:8080/wfp/externalevent-continue?orderId=123&decision=true" -H ' Content-Type: application/json'
310
+ ```
311
+
312
+ <!-- END_STEP -->
313
+
314
+ ```bash
315
+ {"approved":true}
316
+ ```
317
+
318
+ In the application output you should see the workflow activities being executed.
319
+
320
+ ```bash
321
+ i.d.s.e.w.WorkflowPatternsRestController : Workflow instance e86bc464-6166-434d-8c91-d99040d6f54e continue
322
+ io.dapr.workflows.WorkflowContext : approval granted - do the approved action
323
+ i.d.s.e.w.externalevent.ApproveActivity : Starting Activity: io.dapr.springboot.examples.wfp.externalevent.ApproveActivity
324
+ i.d.s.e.w.externalevent.ApproveActivity : Running approval activity...
325
+ io.dapr.workflows.WorkflowContext : approval-activity finished
326
+ ```
188
327
189
328
### Fan Out/In Workflow example
190
329
330
+ In this example we start a workflow that takes an ArrayList of strings and calls one activity per item in the ArrayList. The activities
331
+ are executed and the workflow waits for all of them to complete to aggregate the results.
332
+
333
+ ```mermaid
334
+ graph LR
335
+ SW((Start
336
+ Workflow))
337
+ subgraph for each word in the input
338
+ GWL[GetWordLength]
339
+ end
340
+ ALL[Wait until all tasks
341
+ are completed]
342
+ EW((End
343
+ Workflow))
344
+ SW --> GWL
345
+ GWL --> ALL
346
+ ALL --> EW
347
+ ```
348
+
349
+ To start the workflow you can run:
350
+
351
+ <!-- STEP
352
+ name: Start Parent/Child Workflow
353
+ match_order: none
354
+ output_match_mode: substring
355
+ expected_stdout_lines:
356
+ - ' {" wordCount" :60}'
357
+ background: true
358
+ sleep: 1
359
+ timeout_seconds: 2
360
+ -->
361
+ <!-- Timeout for above service must be more than sleep + timeout for the client-->
362
+
363
+ To start the workflow you can run:
364
+
365
+ ```sh
366
+ curl -X POST localhost:8080/wfp/fanoutin -H ' Content-Type: application/json' -d @body.json
367
+ ```
368
+
369
+ <!-- END_STEP -->
370
+
371
+ As result from executing the request you should see:
372
+
373
+ ```bash
374
+ {"wordCount":60}
375
+ ```
376
+
377
+ In the application output you should see the workflow activities being executed.
378
+
379
+ ```bash
380
+ io.dapr.workflows.WorkflowContext : Starting Workflow: io.dapr.springboot.examples.wfp.fanoutin.FanOutInWorkflow
381
+ i.d.s.e.w.WorkflowPatternsRestController : Workflow instance a771a7ba-f9fb-4399-aaee-a2fb0b102e5d started
382
+ i.d.s.e.wfp.fanoutin.CountWordsActivity : Starting Activity: io.dapr.springboot.examples.wfp.fanoutin.CountWordsActivity
383
+ i.d.s.e.wfp.fanoutin.CountWordsActivity : Starting Activity: io.dapr.springboot.examples.wfp.fanoutin.CountWordsActivity
384
+ i.d.s.e.wfp.fanoutin.CountWordsActivity : Starting Activity: io.dapr.springboot.examples.wfp.fanoutin.CountWordsActivity
385
+ i.d.s.e.wfp.fanoutin.CountWordsActivity : Activity returned: 2.
386
+ i.d.s.e.wfp.fanoutin.CountWordsActivity : Activity finished
387
+ i.d.s.e.wfp.fanoutin.CountWordsActivity : Activity returned: 11.
388
+ i.d.s.e.wfp.fanoutin.CountWordsActivity : Activity returned: 17.
389
+ i.d.s.e.wfp.fanoutin.CountWordsActivity : Activity finished
390
+ i.d.s.e.wfp.fanoutin.CountWordsActivity : Activity finished
391
+ i.d.s.e.wfp.fanoutin.CountWordsActivity : Starting Activity: io.dapr.springboot.examples.wfp.fanoutin.CountWordsActivity
392
+ i.d.s.e.wfp.fanoutin.CountWordsActivity : Activity returned: 21.
393
+ i.d.s.e.wfp.fanoutin.CountWordsActivity : Activity finished
394
+ i.d.s.e.wfp.fanoutin.CountWordsActivity : Starting Activity: io.dapr.springboot.examples.wfp.fanoutin.CountWordsActivity
395
+ i.d.s.e.wfp.fanoutin.CountWordsActivity : Activity returned: 9.
396
+ i.d.s.e.wfp.fanoutin.CountWordsActivity : Activity finished
397
+ io.dapr.workflows.WorkflowContext : Workflow finished with result: 60
398
+ ```
399
+
191
400
192
401
## Testing workflow executions
193
402
0 commit comments