Skip to content

Commit d3a8623

Browse files
Add high-level workflow describe
1 parent 74022f1 commit d3a8623

File tree

11 files changed

+195
-1
lines changed

11 files changed

+195
-1
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (C) 2022 Temporal Technologies, Inc. All Rights Reserved.
3+
*
4+
* Copyright (C) 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this material except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
21+
package io.temporal.client;
22+
23+
import io.temporal.api.workflowservice.v1.DescribeWorkflowExecutionResponse;
24+
import io.temporal.common.converter.DataConverter;
25+
import javax.annotation.Nonnull;
26+
27+
/** Contains information about a workflow execution. */
28+
public class WorkflowExecutionDescription extends WorkflowExecutionMetadata {
29+
private final @Nonnull DescribeWorkflowExecutionResponse response;
30+
31+
public WorkflowExecutionDescription(
32+
@Nonnull DescribeWorkflowExecutionResponse response, @Nonnull DataConverter dataConverter) {
33+
super(response.getWorkflowExecutionInfo(), dataConverter);
34+
this.response = response;
35+
}
36+
37+
/** Returns the raw response from the Temporal service. */
38+
public DescribeWorkflowExecutionResponse getRawDescription() {
39+
return response;
40+
}
41+
}

temporal-sdk/src/main/java/io/temporal/client/WorkflowStub.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,16 @@ <R> CompletableFuture<R> getResultAsync(
382382
*/
383383
void terminate(@Nullable String reason, Object... details);
384384

385+
/**
386+
* Get the current description of this workflow.
387+
*
388+
* @throws WorkflowNotFoundException if the workflow execution doesn't exist
389+
* @throws WorkflowServiceException for all other failures including networking and service
390+
* availability issues
391+
* @return the current description of this workflow
392+
*/
393+
WorkflowExecutionDescription describe();
394+
385395
Optional<WorkflowOptions> getOptions();
386396

387397
/**

temporal-sdk/src/main/java/io/temporal/client/WorkflowStubImpl.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,21 @@ public void terminate(@Nullable String reason, Object... details) {
446446
}
447447
}
448448

449+
@Override
450+
public WorkflowExecutionDescription describe() {
451+
checkStarted();
452+
WorkflowExecution targetExecution = execution.get();
453+
try {
454+
WorkflowClientCallsInterceptor.DescribeWorkflowOutput result =
455+
workflowClientInvoker.describe(
456+
new WorkflowClientCallsInterceptor.DescribeWorkflowInput(targetExecution));
457+
return result.getDescription();
458+
} catch (Exception e) {
459+
Throwable failure = throwAsWorkflowFailureException(e, targetExecution);
460+
throw new WorkflowServiceException(targetExecution, workflowType.orElse(null), failure);
461+
}
462+
}
463+
449464
@Override
450465
public Optional<WorkflowOptions> getOptions() {
451466
return Optional.ofNullable(options);

temporal-sdk/src/main/java/io/temporal/common/interceptors/WorkflowClientCallsInterceptor.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ public interface WorkflowClientCallsInterceptor {
9494

9595
TerminateOutput terminate(TerminateInput input);
9696

97+
DescribeWorkflowOutput describe(DescribeWorkflowInput input);
98+
9799
final class WorkflowStartInput {
98100
private final String workflowId;
99101
private final String workflowType;
@@ -601,4 +603,28 @@ public Object[] getDetails() {
601603
}
602604

603605
final class TerminateOutput {}
606+
607+
final class DescribeWorkflowInput {
608+
private final WorkflowExecution workflowExecution;
609+
610+
public DescribeWorkflowInput(WorkflowExecution workflowExecution) {
611+
this.workflowExecution = workflowExecution;
612+
}
613+
614+
public WorkflowExecution getWorkflowExecution() {
615+
return workflowExecution;
616+
}
617+
}
618+
619+
final class DescribeWorkflowOutput {
620+
private final WorkflowExecutionDescription description;
621+
622+
public DescribeWorkflowOutput(WorkflowExecutionDescription description) {
623+
this.description = description;
624+
}
625+
626+
public WorkflowExecutionDescription getDescription() {
627+
return description;
628+
}
629+
}
604630
}

temporal-sdk/src/main/java/io/temporal/common/interceptors/WorkflowClientCallsInterceptorBase.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,9 @@ public CancelOutput cancel(CancelInput input) {
8787
public TerminateOutput terminate(TerminateInput input) {
8888
return next.terminate(input);
8989
}
90+
91+
@Override
92+
public DescribeWorkflowOutput describe(DescribeWorkflowInput input) {
93+
return next.describe(input);
94+
}
9095
}

temporal-sdk/src/main/java/io/temporal/internal/client/RootWorkflowClientInvoker.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,26 @@ public TerminateOutput terminate(TerminateInput input) {
693693
return new TerminateOutput();
694694
}
695695

696+
@Override
697+
public DescribeWorkflowOutput describe(DescribeWorkflowInput input) {
698+
DescribeWorkflowExecutionResponse response =
699+
genericClient.describeWorkflowExecution(
700+
DescribeWorkflowExecutionRequest.newBuilder()
701+
.setNamespace(clientOptions.getNamespace())
702+
.setExecution(input.getWorkflowExecution())
703+
.build());
704+
705+
DataConverter dataConverterWithWorkflowContext =
706+
clientOptions
707+
.getDataConverter()
708+
.withContext(
709+
new WorkflowSerializationContext(
710+
clientOptions.getNamespace(), input.getWorkflowExecution().getWorkflowId()));
711+
712+
return new DescribeWorkflowOutput(
713+
new WorkflowExecutionDescription(response, dataConverterWithWorkflowContext));
714+
}
715+
696716
private static <R> R convertResultPayloads(
697717
Optional<Payloads> resultValue,
698718
Class<R> resultClass,

temporal-sdk/src/main/java/io/temporal/internal/client/external/GenericWorkflowClient.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ CompletableFuture<ListWorkflowExecutionsResponse> listWorkflowExecutionsAsync(
7878

7979
DescribeScheduleResponse describeSchedule(DescribeScheduleRequest request);
8080

81+
DescribeWorkflowExecutionResponse describeWorkflowExecution(
82+
DescribeWorkflowExecutionRequest request);
83+
8184
@Experimental
8285
UpdateWorkerBuildIdCompatibilityResponse updateWorkerBuildIdCompatability(
8386
UpdateWorkerBuildIdCompatibilityRequest request);

temporal-sdk/src/main/java/io/temporal/internal/client/external/GenericWorkflowClientImpl.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,18 @@ public DescribeScheduleResponse describeSchedule(DescribeScheduleRequest request
303303
grpcRetryerOptions);
304304
}
305305

306+
@Override
307+
public DescribeWorkflowExecutionResponse describeWorkflowExecution(
308+
DescribeWorkflowExecutionRequest request) {
309+
return grpcRetryer.retryWithResult(
310+
() ->
311+
service
312+
.blockingStub()
313+
.withOption(METRICS_TAGS_CALL_OPTIONS_KEY, metricsScope)
314+
.describeWorkflowExecution(request),
315+
grpcRetryerOptions);
316+
}
317+
306318
private static <T> CompletableFuture<T> toCompletableFuture(
307319
ListenableFuture<T> listenableFuture) {
308320
CompletableFuture<T> result = new CompletableFuture<>();
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (C) 2022 Temporal Technologies, Inc. All Rights Reserved.
3+
*
4+
* Copyright (C) 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
*
6+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this material except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
21+
package io.temporal.workflow;
22+
23+
import static org.junit.Assert.assertEquals;
24+
25+
import io.temporal.client.WorkflowExecutionDescription;
26+
import io.temporal.client.WorkflowStub;
27+
import io.temporal.testing.internal.SDKTestWorkflowRule;
28+
import io.temporal.workflow.shared.TestWorkflows.TestWorkflow1;
29+
import org.junit.Rule;
30+
import org.junit.Test;
31+
32+
public class WorkflowDescribe {
33+
34+
@Rule
35+
public SDKTestWorkflowRule testWorkflowRule =
36+
SDKTestWorkflowRule.newBuilder().setWorkflowTypes(TestInitWorkflow.class).build();
37+
38+
@Test
39+
public void testWorkflowDescribe() {
40+
TestWorkflow1 workflowStub =
41+
testWorkflowRule.newWorkflowStubTimeoutOptions(TestWorkflow1.class);
42+
String result = workflowStub.execute(testWorkflowRule.getTaskQueue());
43+
assertEquals(testWorkflowRule.getTaskQueue(), result);
44+
WorkflowExecutionDescription description = WorkflowStub.fromTyped(workflowStub).describe();
45+
assertEquals(testWorkflowRule.getTaskQueue(), description.getTaskQueue());
46+
assertEquals("TestWorkflow1", description.getWorkflowType());
47+
assertEquals(WorkflowStub.fromTyped(workflowStub).getExecution(), description.getExecution());
48+
}
49+
50+
public static class TestInitWorkflow implements TestWorkflow1 {
51+
@Override
52+
public String execute(String taskQueue) {
53+
return taskQueue;
54+
}
55+
}
56+
}

temporal-test-server/src/main/java/io/temporal/internal/testservice/TestWorkflowMutableStateImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3024,7 +3024,8 @@ private DescribeWorkflowExecutionResponse describeWorkflowExecutionInsideLock()
30243024
// No setAutoResetPoints - the test environment doesn't support that feature
30253025
.setSearchAttributes(visibilityStore.getSearchAttributesForExecution(executionId))
30263026
.setStatus(this.getWorkflowExecutionStatus())
3027-
.setHistoryLength(fullHistory.size());
3027+
.setHistoryLength(fullHistory.size())
3028+
.setTaskQueue(this.getStartRequest().getTaskQueue().getName());
30283029

30293030
populateWorkflowExecutionInfoFromHistory(executionInfo, fullHistory);
30303031

temporal-testing/src/main/java/io/temporal/testing/TimeLockingInterceptor.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,11 @@ public WorkflowStub newInstance(WorkflowOptions options) {
193193
return new TimeLockingWorkflowStub(locker, next.newInstance(options));
194194
}
195195

196+
@Override
197+
public WorkflowExecutionDescription describe() {
198+
return next.describe();
199+
}
200+
196201
/** Unlocks time skipping before blocking calls and locks back after completion. */
197202
private class TimeLockingFuture<R> extends CompletableFuture<R> {
198203

0 commit comments

Comments
 (0)