Skip to content

Commit 67f0f4a

Browse files
committed
adding duration and zoneddatetime examples
Signed-off-by: salaboy <[email protected]>
1 parent af9dc3f commit 67f0f4a

File tree

6 files changed

+252
-0
lines changed

6 files changed

+252
-0
lines changed

spring-boot-examples/workflows/src/main/java/io/dapr/springboot/examples/wfp/WorkflowPatternsRestController.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,14 @@
2424
import io.dapr.springboot.examples.wfp.fanoutin.Result;
2525
import io.dapr.springboot.examples.wfp.remoteendpoint.Payload;
2626
import io.dapr.springboot.examples.wfp.remoteendpoint.RemoteEndpointWorkflow;
27+
<<<<<<< HEAD
2728
import io.dapr.springboot.examples.wfp.suspendresume.SuspendResumeWorkflow;
29+
=======
30+
//import io.dapr.springboot.examples.wfp.suspendresume.SuspendResumeWorkflow;
31+
import io.dapr.springboot.examples.wfp.timer.DurationTimerWorkflow;
32+
import io.dapr.springboot.examples.wfp.timer.ZonedDateTimeTimerWorkflow;
33+
34+
>>>>>>> 9575b410 (adding duration and zoneddatetime examples)
2835
import io.dapr.workflows.client.DaprWorkflowClient;
2936
import io.dapr.workflows.client.WorkflowInstanceStatus;
3037
import org.slf4j.Logger;
@@ -189,4 +196,16 @@ public Decision suspendResumeContinue(@RequestParam("orderId") String orderId, @
189196
.waitForInstanceCompletion(instanceId, null, true);
190197
return workflowInstanceStatus.readOutputAs(Decision.class);
191198
}
199+
200+
@PostMapping("wfp/durationtimer")
201+
public String durationTimerWorkflow() {
202+
return daprWorkflowClient.scheduleNewWorkflow(DurationTimerWorkflow.class);
203+
}
204+
205+
@PostMapping("wfp/zoneddatetimetimer")
206+
public String zonedDateTimeTimerWorkflow() {
207+
return daprWorkflowClient.scheduleNewWorkflow(ZonedDateTimeTimerWorkflow.class);
208+
}
209+
192210
}
211+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2025 The Dapr Authors
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package io.dapr.springboot.examples.wfp.timer;
15+
16+
import io.dapr.workflows.Workflow;
17+
import io.dapr.workflows.WorkflowStub;
18+
import org.springframework.stereotype.Component;
19+
20+
import java.time.Duration;
21+
import java.util.Date;
22+
23+
@Component
24+
public class DurationTimerWorkflow implements Workflow {
25+
@Override
26+
public WorkflowStub create() {
27+
return ctx -> {
28+
ctx.getLogger().info("Starting Workflow: {}, instanceId: {}", ctx.getName(), ctx.getInstanceId());
29+
30+
ctx.getLogger().info("Let's call the first LogActivity at {}", new Date());
31+
ctx.callActivity(LogActivity.class.getName()).await();
32+
33+
ctx.getLogger().info("Let's schedule a 10 seconds timer at {}", new Date());
34+
ctx.createTimer(Duration.ofSeconds(10)).await();
35+
36+
ctx.getLogger().info("Let's call the second LogActivity at {}", new Date());
37+
ctx.callActivity(LogActivity.class.getName()).await();
38+
39+
ctx.complete(true);
40+
ctx.getLogger().info("Workflow completed at {}", new Date());
41+
};
42+
}
43+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2025 The Dapr Authors
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package io.dapr.springboot.examples.wfp.timer;
15+
16+
import io.dapr.workflows.WorkflowActivity;
17+
import io.dapr.workflows.WorkflowActivityContext;
18+
import org.slf4j.Logger;
19+
import org.slf4j.LoggerFactory;
20+
import org.springframework.beans.factory.annotation.Autowired;
21+
import org.springframework.stereotype.Component;
22+
23+
import java.util.Date;
24+
25+
@Component
26+
public class LogActivity implements WorkflowActivity {
27+
28+
@Autowired
29+
private TimerLogService logService;
30+
31+
@Override
32+
public Object run(WorkflowActivityContext ctx) {
33+
Logger logger = LoggerFactory.getLogger(LogActivity.class);
34+
Date now = new Date();
35+
logger.info("Running Activity: {} at {}", ctx.getName(), now);
36+
logService.logDate(now);
37+
return true;
38+
}
39+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2025 The Dapr Authors
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
package io.dapr.springboot.examples.wfp.timer;
14+
15+
import org.springframework.stereotype.Component;
16+
17+
import java.util.ArrayList;
18+
import java.util.Date;
19+
import java.util.List;
20+
21+
@Component
22+
public class TimerLogService {
23+
private final List<Date> logDates = new ArrayList<>();
24+
25+
public void logDate(Date date){
26+
logDates.add(date);
27+
}
28+
29+
public void clearLog(){
30+
logDates.clear();
31+
}
32+
33+
public List<Date> getLogDates(){
34+
return logDates;
35+
}
36+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2025 The Dapr Authors
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package io.dapr.springboot.examples.wfp.timer;
15+
16+
import io.dapr.workflows.Workflow;
17+
import io.dapr.workflows.WorkflowStub;
18+
import org.springframework.stereotype.Component;
19+
20+
import java.time.ZonedDateTime;
21+
import java.util.Date;
22+
23+
@Component
24+
public class ZonedDateTimeTimerWorkflow implements Workflow {
25+
@Override
26+
public WorkflowStub create() {
27+
return ctx -> {
28+
ctx.getLogger().info("Starting Workflow: {}, instanceId: {}", ctx.getName(), ctx.getInstanceId());
29+
30+
ctx.getLogger().info("Let's call the first LogActivity at {}", new Date());
31+
ctx.callActivity(LogActivity.class.getName()).await();
32+
33+
ZonedDateTime now = ZonedDateTime.now();
34+
//Let's create a ZonedDateTime 10 seconds in the future
35+
ZonedDateTime inTheFuture = now.plusSeconds(10);
36+
ctx.getLogger().info("Creating a timer that due {} at: {}", inTheFuture, new Date());
37+
ctx.createTimer(inTheFuture).await();
38+
ctx.getLogger().info("The timer fired at: {}", new Date());
39+
40+
ctx.getLogger().info("Let's call the second LogActivity at {}", new Date());
41+
ctx.callActivity(LogActivity.class.getName()).await();
42+
43+
ctx.complete(true);
44+
ctx.getLogger().info("Workflow completed at {}", new Date());
45+
};
46+
}
47+
}

spring-boot-examples/workflows/src/test/java/io/dapr/springboot/examples/wfp/WorkflowPatternsAppTests.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import io.dapr.springboot.DaprAutoConfiguration;
1717
import io.dapr.springboot.examples.wfp.continueasnew.CleanUpLog;
1818
import io.dapr.springboot.examples.wfp.remoteendpoint.Payload;
19+
import io.dapr.springboot.examples.wfp.timer.TimerLogService;
1920
import io.dapr.workflows.client.WorkflowRuntimeStatus;
2021
import io.github.microcks.testcontainers.MicrocksContainersEnsemble;
2122
import io.restassured.RestAssured;
@@ -25,10 +26,13 @@
2526
import org.springframework.beans.factory.annotation.Autowired;
2627
import org.springframework.boot.test.context.SpringBootTest;
2728

29+
import java.time.Duration;
2830
import java.util.Arrays;
2931
import java.util.List;
32+
import java.util.concurrent.TimeUnit;
3033

3134
import static io.restassured.RestAssured.given;
35+
import static org.awaitility.Awaitility.await;
3236
import static org.hamcrest.CoreMatchers.containsString;
3337
import static org.hamcrest.Matchers.equalTo;
3438
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -42,10 +46,14 @@ class WorkflowPatternsAppTests {
4246
@Autowired
4347
private MicrocksContainersEnsemble ensemble;
4448

49+
@Autowired
50+
private TimerLogService logService;
51+
4552
@BeforeEach
4653
void setUp() {
4754
RestAssured.baseURI = "http://localhost:" + 8080;
4855
org.testcontainers.Testcontainers.exposeHostPorts(8080);
56+
logService.clearLog();
4957
}
5058

5159

@@ -201,4 +209,64 @@ void testSuspendResume() {
201209

202210
}
203211

212+
@Test
213+
void testDurationTimer() throws InterruptedException {
214+
215+
String instanceId = given()
216+
.when()
217+
.post("/wfp/durationtimer")
218+
.then()
219+
.statusCode(200).extract().asString();
220+
221+
assertNotNull(instanceId);
222+
223+
// Check that the workflow completed successfully
224+
await().atMost(Duration.ofSeconds(30))
225+
.pollDelay(500, TimeUnit.MILLISECONDS)
226+
.pollInterval(500, TimeUnit.MILLISECONDS)
227+
.until(() -> {
228+
System.out.println("Log Size: " + logService.getLogDates().size());
229+
if( logService.getLogDates().size() == 2 ) {
230+
long diffInMillis = Math.abs(logService.getLogDates().get(1).getTime() - logService.getLogDates().get(0).getTime());
231+
long diff = TimeUnit.SECONDS.convert(diffInMillis, TimeUnit.MILLISECONDS);
232+
System.out.println("First Log at: " + logService.getLogDates().get(0));
233+
System.out.println("Second Log at: " + logService.getLogDates().get(1));
234+
System.out.println("Diff in seconds: " + diff);
235+
// The updated time differences should be between 9 and 11 seconds
236+
return diff >= 9 && diff <= 11;
237+
}
238+
return false;
239+
});
240+
}
241+
242+
@Test
243+
void testZonedDateTimeTimer() throws InterruptedException {
244+
245+
String instanceId = given()
246+
.when()
247+
.post("/wfp/zoneddatetimetimer")
248+
.then()
249+
.statusCode(200).extract().asString();
250+
251+
assertNotNull(instanceId);
252+
253+
// Check that the workflow completed successfully
254+
await().atMost(Duration.ofSeconds(30))
255+
.pollDelay(500, TimeUnit.MILLISECONDS)
256+
.pollInterval(500, TimeUnit.MILLISECONDS)
257+
.until(() -> {
258+
System.out.println("Log Size: " + logService.getLogDates().size());
259+
if( logService.getLogDates().size() == 2 ) {
260+
long diffInMillis = Math.abs(logService.getLogDates().get(1).getTime() - logService.getLogDates().get(0).getTime());
261+
long diff = TimeUnit.SECONDS.convert(diffInMillis, TimeUnit.MILLISECONDS);
262+
System.out.println("First Log at: " + logService.getLogDates().get(0));
263+
System.out.println("Second Log at: " + logService.getLogDates().get(1));
264+
System.out.println("Diff in seconds: " + diff);
265+
// The updated time differences should be between 9 and 11 seconds
266+
return diff >= 9 && diff <= 11;
267+
}
268+
return false;
269+
});
270+
}
271+
204272
}

0 commit comments

Comments
 (0)