Skip to content

Commit 6f996d1

Browse files
authored
Add getParent() API to TaskOrchestrationContext for parent instance support (#284)
1 parent a8b723e commit 6f996d1

10 files changed

Lines changed: 625 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
## Unreleased
2+
* Add `getParentInstance()` API to `TaskOrchestrationContext` for discovering parent orchestration info ([#284](https://github.com/microsoft/durabletask-java/pull/284))
23

34
## v1.9.0
45
* Fix entity locking deserialization and add Jackson support for EntityInstanceId/EntityMetadata ([#281](https://github.com/microsoft/durabletask-java/pull/281))
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
package com.microsoft.durabletask;
4+
5+
import java.util.Objects;
6+
import javax.annotation.Nonnull;
7+
8+
/**
9+
* Represents the parent orchestration of a sub-orchestration.
10+
* This is available via {@link TaskOrchestrationContext#getParentInstance()} when the
11+
* current orchestration was started as a sub-orchestration.
12+
*/
13+
public final class ParentOrchestrationInstance {
14+
private final String name;
15+
private final String instanceId;
16+
17+
/**
18+
* Creates a new ParentOrchestrationInstance.
19+
*
20+
* @param name the name of the parent orchestration
21+
* @param instanceId the instance ID of the parent orchestration
22+
*/
23+
public ParentOrchestrationInstance(@Nonnull String name, @Nonnull String instanceId) {
24+
this.name = Objects.requireNonNull(name, "name");
25+
this.instanceId = Objects.requireNonNull(instanceId, "instanceId");
26+
}
27+
28+
/**
29+
* Gets the name of the parent orchestration.
30+
*
31+
* @return the parent orchestration name
32+
*/
33+
@Nonnull
34+
public String getName() {
35+
return this.name;
36+
}
37+
38+
/**
39+
* Gets the instance ID of the parent orchestration.
40+
*
41+
* @return the parent orchestration instance ID
42+
*/
43+
@Nonnull
44+
public String getInstanceId() {
45+
return this.instanceId;
46+
}
47+
48+
@Override
49+
public String toString() {
50+
return String.format("ParentOrchestrationInstance{name='%s', instanceId='%s'}", name, instanceId);
51+
}
52+
53+
@Override
54+
public boolean equals(Object o) {
55+
if (this == o) return true;
56+
if (!(o instanceof ParentOrchestrationInstance)) return false;
57+
ParentOrchestrationInstance that = (ParentOrchestrationInstance) o;
58+
return Objects.equals(name, that.name) && Objects.equals(instanceId, that.instanceId);
59+
}
60+
61+
@Override
62+
public int hashCode() {
63+
return Objects.hash(name, instanceId);
64+
}
65+
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,19 @@ default Task<AutoCloseable> lockEntities(@Nonnull EntityInstanceId... entityIds)
794794
*/
795795
void clearCustomStatus();
796796

797+
/**
798+
* Gets the parent orchestration instance, or {@code null} if this orchestration
799+
* was not started as a sub-orchestration.
800+
* <p>
801+
* Implementers that wrap or decorate another {@link TaskOrchestrationContext}
802+
* must delegate to the wrapped instance. Returning {@code null} unconditionally
803+
* will incorrectly report sub-orchestrations as standalone.
804+
*
805+
* @return the parent orchestration instance, or {@code null}
806+
*/
807+
@Nullable
808+
ParentOrchestrationInstance getParentInstance();
809+
797810
/**
798811
* Makes a durable HTTP request using the specified {@link DurableHttpRequest} and returns a {@link Task}
799812
* that completes when the HTTP call completes.

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ private class ContextImplTask implements TaskOrchestrationContext {
146146
private boolean preserveUnprocessedEvents;
147147
private Object customStatus;
148148
private TraceContext parentTraceContext;
149+
private ParentOrchestrationInstance parentInstance;
149150

150151
// Entity integration state (Phase 4)
151152
private String executionId;
@@ -207,6 +208,12 @@ public String getInstanceId() {
207208
return this.instanceId;
208209
}
209210

211+
@Override
212+
@Nullable
213+
public ParentOrchestrationInstance getParentInstance() {
214+
return this.parentInstance;
215+
}
216+
210217
private void setInstanceId(String instanceId) {
211218
// TODO: Throw if instance ID is not null
212219
this.instanceId = instanceId;
@@ -1705,6 +1712,16 @@ private void processEvent(HistoryEvent e) {
17051712
} else {
17061713
this.parentTraceContext = null;
17071714
}
1715+
if (startedEvent.hasParentInstance()) {
1716+
ParentInstanceInfo parentInfo = startedEvent.getParentInstance();
1717+
String parentName = parentInfo.hasName() ? parentInfo.getName().getValue() : "";
1718+
String parentInstanceId = parentInfo.hasOrchestrationInstance()
1719+
? parentInfo.getOrchestrationInstance().getInstanceId()
1720+
: "";
1721+
this.parentInstance = new ParentOrchestrationInstance(parentName, parentInstanceId);
1722+
} else {
1723+
this.parentInstance = null;
1724+
}
17081725
TaskOrchestrationFactory factory = TaskOrchestrationExecutor.this.orchestrationFactories.get(name);
17091726
if (factory == null) {
17101727
// Try getting the default orchestrator

client/src/test/java/com/microsoft/durabletask/EntityProxyTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ static class RecordingContext implements TaskOrchestrationContext {
128128
@Override
129129
public String getInstanceId() { return "test-instance"; }
130130

131+
@Override
132+
public ParentOrchestrationInstance getParentInstance() { return null; }
133+
131134
@Override
132135
public Instant getCurrentInstant() { return Instant.now(); }
133136

0 commit comments

Comments
 (0)