Skip to content

Commit 3cd0c07

Browse files
committed
Merge branch 'main' into vabachu/entities
2 parents 4a0ac42 + b446edf commit 3cd0c07

File tree

13 files changed

+629
-8
lines changed

13 files changed

+629
-8
lines changed

.github/workflows/build-validation.yml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ on:
1414
pull_request:
1515
branches: [ main ]
1616

17+
permissions:
18+
contents: read
19+
1720
jobs:
1821
build:
1922

@@ -156,8 +159,8 @@ jobs:
156159
- name: Archive test report
157160
uses: actions/upload-artifact@v4
158161
with:
159-
name: Integration test report
160-
path: client/build/reports/tests/endToEndTest
162+
name: E2E test report
163+
path: endtoendtests/build/reports/tests/endToEndTest
161164

162165
functions-sample-tests:
163166

@@ -195,5 +198,5 @@ jobs:
195198
- name: Archive test report
196199
uses: actions/upload-artifact@v4
197200
with:
198-
name: Integration test report
199-
path: client/build/reports/tests/endToEndTest
201+
name: Functions Sample test report
202+
path: samples-azure-functions/build/reports/tests/sampleTest

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
## Unreleased
22

3+
* Adding rewind client API ([#253](https://github.com/microsoft/durabletask-java/pull/253)). Note: orchestration processing for rewind is supported with Azure Functions but not with the standalone `GrpcDurableTaskWorker`.
4+
5+
## v1.7.0
6+
* Add descriptive error when orchestration type is not registered ([#261](https://github.com/microsoft/durabletask-java/pull/261))
7+
* Update all dependencies to latest versions ([#260](https://github.com/microsoft/durabletask-java/pull/260))
8+
39
## v1.6.3
410
* Add DurableTaskGrpcClientFactory ([#256](https://github.com/microsoft/durabletask-java/pull/256))
511
* Add support for running GitHub workflows manually and update flaky tests ([#258](https://github.com/microsoft/durabletask-java/pull/258))

azurefunctions/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ plugins {
66
}
77

88
group 'com.microsoft'
9-
version = '1.6.3'
9+
version = '1.7.0'
1010
archivesBaseName = 'durabletask-azure-functions'
1111

1212
def protocVersion = '3.25.8'

azurefunctions/src/main/java/com/microsoft/durabletask/azurefunctions/HttpManagementPayload.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public class HttpManagementPayload {
1313
private final String id;
1414
private final String purgeHistoryDeleteUri;
1515
private final String restartPostUri;
16+
private final String rewindPostUri;
1617
private final String sendEventPostUri;
1718
private final String statusQueryGetUri;
1819
private final String terminatePostUri;
@@ -33,6 +34,7 @@ public HttpManagementPayload(
3334
this.id = instanceId;
3435
this.purgeHistoryDeleteUri = instanceStatusURL + "?" + requiredQueryStringParameters;
3536
this.restartPostUri = instanceStatusURL + "/restart?" + requiredQueryStringParameters;
37+
this.rewindPostUri = instanceStatusURL + "/rewind?reason={text}&" + requiredQueryStringParameters;
3638
this.sendEventPostUri = instanceStatusURL + "/raiseEvent/{eventName}?" + requiredQueryStringParameters;
3739
this.statusQueryGetUri = instanceStatusURL + "?" + requiredQueryStringParameters;
3840
this.terminatePostUri = instanceStatusURL + "/terminate?reason={text}&" + requiredQueryStringParameters;
@@ -94,4 +96,13 @@ public String getRestartPostUri() {
9496
return restartPostUri;
9597
}
9698

99+
/**
100+
* Gets the HTTP POST instance rewind endpoint.
101+
*
102+
* @return The HTTP URL for posting instance rewind commands.
103+
*/
104+
public String getRewindPostUri() {
105+
return rewindPostUri;
106+
}
107+
97108
}

azuremanaged/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ plugins {
1717

1818
archivesBaseName = 'durabletask-azuremanaged'
1919
group 'com.microsoft'
20-
version = '1.6.3'
20+
version = '1.7.0'
2121

2222
def grpcVersion = '1.78.0'
2323
def azureCoreVersion = '1.57.1'

client/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ plugins {
1010
}
1111

1212
group 'com.microsoft'
13-
version = '1.6.3'
13+
version = '1.7.0'
1414
archivesBaseName = 'durabletask-client'
1515

1616
def grpcVersion = '1.78.0'

client/src/main/java/com/microsoft/durabletask/DurableTaskClient.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,41 @@ public abstract OrchestrationMetadata waitForInstanceCompletion(
292292
*/
293293
public abstract String restartInstance(String instanceId, boolean restartWithNewInstanceId);
294294

295+
/**
296+
* Rewinds a failed orchestration instance to the last known good state and replays from there.
297+
* <p>
298+
* This method can only be used on orchestration instances that are in a <code>Failed</code> state.
299+
* When rewound, the orchestration instance will restart from the point of failure as if the failure
300+
* never occurred. It rewinds the orchestration by replaying any
301+
* Failed Activities and Failed suborchestrations that themselves have Failed Activities
302+
* <p>
303+
* <b>Note:</b> Rewind requires a backend that supports it. When using Azure Functions with the
304+
* Durable Task extension, rewind is fully supported. The standalone {@code GrpcDurableTaskWorker}
305+
* does not currently support orchestration processing for rewind.
306+
*
307+
* @param instanceId the ID of the orchestration instance to rewind
308+
*/
309+
public void rewindInstance(String instanceId) {
310+
this.rewindInstance(instanceId, null);
311+
}
312+
313+
/**
314+
* Rewinds a failed orchestration instance to the last known good state and replays from there.
315+
* <p>
316+
* This method can only be used on orchestration instances that are in a <code>Failed</code> state.
317+
* When rewound, the orchestration instance will restart from the point of failure as if the failure
318+
* never occurred. It rewinds the orchestration by replaying any
319+
* Failed Activities and Failed suborchestrations that themselves have Failed Activities
320+
* <p>
321+
* <b>Note:</b> Rewind requires a backend that supports it. When using Azure Functions with the
322+
* Durable Task extension, rewind is fully supported. The standalone {@code GrpcDurableTaskWorker}
323+
* does not currently support orchestration processing for rewind.
324+
*
325+
* @param instanceId the ID of the orchestration instance to rewind
326+
* @param reason the reason for rewinding the orchestration instance
327+
*/
328+
public abstract void rewindInstance(String instanceId, @Nullable String reason);
329+
295330
/**
296331
* Suspends a running orchestration instance.
297332
* @param instanceId the ID of the orchestration instance to suspend

client/src/main/java/com/microsoft/durabletask/DurableTaskGrpcClient.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,29 @@ public void resumeInstance(String instanceId, @Nullable String reason) {
366366
this.sidecarClient.resumeInstance(resumeRequestBuilder.build());
367367
}
368368

369+
@Override
370+
public void rewindInstance(String instanceId, @Nullable String reason) {
371+
Helpers.throwIfArgumentNull(instanceId, "instanceId");
372+
RewindInstanceRequest.Builder rewindRequestBuilder = RewindInstanceRequest.newBuilder();
373+
rewindRequestBuilder.setInstanceId(instanceId);
374+
if (reason != null) {
375+
rewindRequestBuilder.setReason(StringValue.of(reason));
376+
}
377+
try {
378+
this.sidecarClient.rewindInstance(rewindRequestBuilder.build());
379+
} catch (StatusRuntimeException e) {
380+
if (e.getStatus().getCode() == Status.Code.NOT_FOUND) {
381+
throw new IllegalArgumentException(
382+
"No orchestration instance with ID '" + instanceId + "' was found.", e);
383+
}
384+
if (e.getStatus().getCode() == Status.Code.FAILED_PRECONDITION) {
385+
throw new IllegalStateException(
386+
"Orchestration instance '" + instanceId + "' is not in a failed state and cannot be rewound.", e);
387+
}
388+
throw e;
389+
}
390+
}
391+
369392
@Override
370393
public String restartInstance(String instanceId, boolean restartWithNewInstanceId) {
371394
OrchestrationMetadata metadata = this.getInstanceMetadata(instanceId, true);

0 commit comments

Comments
 (0)