88import com .microsoft .azure .functions .annotation .FunctionName ;
99import com .microsoft .azure .functions .annotation .HttpTrigger ;
1010import com .microsoft .durabletask .DurableTaskClient ;
11+ import com .microsoft .durabletask .OrchestrationMetadata ;
1112import com .microsoft .durabletask .TaskOrchestrationContext ;
1213import com .microsoft .durabletask .azurefunctions .DurableActivityTrigger ;
1314import com .microsoft .durabletask .azurefunctions .DurableClientContext ;
1415import com .microsoft .durabletask .azurefunctions .DurableClientInput ;
1516import com .microsoft .durabletask .azurefunctions .DurableOrchestrationTrigger ;
1617
18+ import java .time .Duration ;
1719import java .util .Optional ;
20+ import java .util .concurrent .TimeoutException ;
1821import java .util .concurrent .atomic .AtomicBoolean ;
1922
2023/**
@@ -30,7 +33,9 @@ public class RewindTest {
3033 private static final AtomicBoolean shouldSubFail = new AtomicBoolean (true );
3134
3235 /**
33- * HTTP trigger to start the rewindable orchestration.
36+ * HTTP trigger that starts a rewindable orchestration, waits for it to fail,
37+ * then rewinds it using client.rewindInstance(). Returns the check status response
38+ * so the caller can poll for the orchestration to complete after the rewind.
3439 */
3540 @ FunctionName ("StartRewindableOrchestration" )
3641 public HttpResponseMessage startRewindableOrchestration (
@@ -45,6 +50,59 @@ public HttpResponseMessage startRewindableOrchestration(
4550 DurableTaskClient client = durableContext .getClient ();
4651 String instanceId = client .scheduleNewOrchestrationInstance ("RewindableOrchestration" );
4752 context .getLogger ().info ("Created new Java orchestration with instance ID = " + instanceId );
53+
54+ // Wait for the orchestration to reach a terminal state (expected: Failed)
55+ try {
56+ OrchestrationMetadata metadata = client .waitForInstanceCompletion (instanceId , Duration .ofSeconds (30 ), false );
57+ context .getLogger ().info ("Orchestration reached terminal state: " + metadata .getRuntimeStatus ());
58+ } catch (TimeoutException e ) {
59+ context .getLogger ().severe ("Orchestration did not reach terminal state in time." );
60+ return request .createResponseBuilder (com .microsoft .azure .functions .HttpStatus .INTERNAL_SERVER_ERROR )
61+ .body ("Orchestration did not fail within the expected time." )
62+ .build ();
63+ }
64+
65+ // Rewind the failed orchestration using the client method
66+ client .rewindInstance (instanceId , "Testing rewind functionality" );
67+ context .getLogger ().info ("Rewind request sent for instance: " + instanceId );
68+
69+ return durableContext .createCheckStatusResponse (request , instanceId );
70+ }
71+
72+ /**
73+ * HTTP trigger that starts a non-failing orchestration, waits for it to complete,
74+ * then attempts to rewind it using client.rewindInstance(). Returns the check status
75+ * response so the caller can verify the orchestration remains in the Completed state.
76+ */
77+ @ FunctionName ("StartRewindNonFailedOrchestration" )
78+ public HttpResponseMessage startRewindNonFailedOrchestration (
79+ @ HttpTrigger (name = "req" , methods = {HttpMethod .GET , HttpMethod .POST }, authLevel = AuthorizationLevel .ANONYMOUS ) HttpRequestMessage <Optional <String >> request ,
80+ @ DurableClientInput (name = "durableContext" ) DurableClientContext durableContext ,
81+ final ExecutionContext context ) {
82+ context .getLogger ().info ("Starting non-failing orchestration for rewind test." );
83+
84+ // Ensure the activity will NOT fail
85+ shouldFail .set (false );
86+
87+ DurableTaskClient client = durableContext .getClient ();
88+ String instanceId = client .scheduleNewOrchestrationInstance ("RewindableOrchestration" );
89+ context .getLogger ().info ("Created orchestration with instance ID = " + instanceId );
90+
91+ // Wait for the orchestration to complete successfully
92+ try {
93+ client .waitForInstanceCompletion (instanceId , Duration .ofSeconds (30 ), false );
94+ context .getLogger ().info ("Orchestration completed successfully." );
95+ } catch (TimeoutException e ) {
96+ context .getLogger ().severe ("Orchestration did not complete in time." );
97+ return request .createResponseBuilder (com .microsoft .azure .functions .HttpStatus .INTERNAL_SERVER_ERROR )
98+ .body ("Orchestration did not complete within the expected time." )
99+ .build ();
100+ }
101+
102+ // Attempt to rewind the non-failed orchestration using the client method
103+ client .rewindInstance (instanceId , "Testing rewind on non-failed orchestration" );
104+ context .getLogger ().info ("Rewind request sent for non-failed instance: " + instanceId );
105+
48106 return durableContext .createCheckStatusResponse (request , instanceId );
49107 }
50108
@@ -93,7 +151,9 @@ public HttpResponseMessage resetRewindFailureFlag(
93151 // --- Sub-orchestration rewind test functions ---
94152
95153 /**
96- * HTTP trigger to start the parent orchestration for sub-orchestration rewind test.
154+ * HTTP trigger that starts a parent orchestration with a failing sub-orchestration,
155+ * waits for it to fail, then rewinds it using client.rewindInstance().
156+ * Returns the check status response so the caller can poll for completion.
97157 */
98158 @ FunctionName ("StartRewindableSubOrchestration" )
99159 public HttpResponseMessage startRewindableSubOrchestration (
@@ -108,6 +168,22 @@ public HttpResponseMessage startRewindableSubOrchestration(
108168 DurableTaskClient client = durableContext .getClient ();
109169 String instanceId = client .scheduleNewOrchestrationInstance ("RewindableParentOrchestration" );
110170 context .getLogger ().info ("Created parent orchestration with instance ID = " + instanceId );
171+
172+ // Wait for the parent orchestration to reach a terminal state (expected: Failed)
173+ try {
174+ OrchestrationMetadata metadata = client .waitForInstanceCompletion (instanceId , Duration .ofSeconds (30 ), false );
175+ context .getLogger ().info ("Parent orchestration reached terminal state: " + metadata .getRuntimeStatus ());
176+ } catch (TimeoutException e ) {
177+ context .getLogger ().severe ("Parent orchestration did not reach terminal state in time." );
178+ return request .createResponseBuilder (com .microsoft .azure .functions .HttpStatus .INTERNAL_SERVER_ERROR )
179+ .body ("Parent orchestration did not fail within the expected time." )
180+ .build ();
181+ }
182+
183+ // Rewind the failed parent orchestration using the client method
184+ client .rewindInstance (instanceId , "Testing rewind with sub-orchestration failure" );
185+ context .getLogger ().info ("Rewind request sent for parent instance: " + instanceId );
186+
111187 return durableContext .createCheckStatusResponse (request , instanceId );
112188 }
113189
0 commit comments