Skip to content

Commit

Permalink
Add high-level workflow describe
Browse files Browse the repository at this point in the history
  • Loading branch information
Quinn-With-Two-Ns committed Nov 20, 2024
1 parent 2a68883 commit da59a8d
Show file tree
Hide file tree
Showing 11 changed files with 195 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2022 Temporal Technologies, Inc. All Rights Reserved.
*
* Copyright (C) 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this material except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.temporal.client;

import io.temporal.api.workflowservice.v1.DescribeWorkflowExecutionResponse;
import io.temporal.common.converter.DataConverter;
import javax.annotation.Nonnull;

/** Contains information about a workflow execution. */
public class WorkflowExecutionDescription extends WorkflowExecutionMetadata {
private final @Nonnull DescribeWorkflowExecutionResponse response;

public WorkflowExecutionDescription(
@Nonnull DescribeWorkflowExecutionResponse response, @Nonnull DataConverter dataConverter) {
super(response.getWorkflowExecutionInfo(), dataConverter);
this.response = response;
}

/** Returns the raw response from the Temporal service. */
public DescribeWorkflowExecutionResponse getRawDescription() {
return response;
}
}
10 changes: 10 additions & 0 deletions temporal-sdk/src/main/java/io/temporal/client/WorkflowStub.java
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,16 @@ <R> CompletableFuture<R> getResultAsync(
*/
void terminate(@Nullable String reason, Object... details);

/**
* Get the current description of this workflow.
*
* @throws WorkflowNotFoundException if the workflow execution doesn't exist
* @throws WorkflowServiceException for all other failures including networking and service
* availability issues
* @return the current description of this workflow
*/
WorkflowExecutionDescription describe();

Optional<WorkflowOptions> getOptions();

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,21 @@ public void terminate(@Nullable String reason, Object... details) {
}
}

@Override
public WorkflowExecutionDescription describe() {
checkStarted();
WorkflowExecution targetExecution = execution.get();
try {
WorkflowClientCallsInterceptor.DescribeWorkflowOutput result =
workflowClientInvoker.describe(
new WorkflowClientCallsInterceptor.DescribeWorkflowInput(targetExecution));
return result.getDescription();
} catch (Exception e) {
Throwable failure = throwAsWorkflowFailureException(e, targetExecution);
throw new WorkflowServiceException(targetExecution, workflowType.orElse(null), failure);
}
}

@Override
public Optional<WorkflowOptions> getOptions() {
return Optional.ofNullable(options);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ public interface WorkflowClientCallsInterceptor {

TerminateOutput terminate(TerminateInput input);

DescribeWorkflowOutput describe(DescribeWorkflowInput input);

final class WorkflowStartInput {
private final String workflowId;
private final String workflowType;
Expand Down Expand Up @@ -601,4 +603,28 @@ public Object[] getDetails() {
}

final class TerminateOutput {}

final class DescribeWorkflowInput {
private final WorkflowExecution workflowExecution;

public DescribeWorkflowInput(WorkflowExecution workflowExecution) {
this.workflowExecution = workflowExecution;
}

public WorkflowExecution getWorkflowExecution() {
return workflowExecution;
}
}

final class DescribeWorkflowOutput {
private final WorkflowExecutionDescription description;

public DescribeWorkflowOutput(WorkflowExecutionDescription description) {
this.description = description;
}

public WorkflowExecutionDescription getDescription() {
return description;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,9 @@ public CancelOutput cancel(CancelInput input) {
public TerminateOutput terminate(TerminateInput input) {
return next.terminate(input);
}

@Override
public DescribeWorkflowOutput describe(DescribeWorkflowInput input) {
return next.describe(input);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,26 @@ public TerminateOutput terminate(TerminateInput input) {
return new TerminateOutput();
}

@Override
public DescribeWorkflowOutput describe(DescribeWorkflowInput input) {
DescribeWorkflowExecutionResponse response =
genericClient.describeWorkflowExecution(
DescribeWorkflowExecutionRequest.newBuilder()
.setNamespace(clientOptions.getNamespace())
.setExecution(input.getWorkflowExecution())
.build());

DataConverter dataConverterWithWorkflowContext =
clientOptions
.getDataConverter()
.withContext(
new WorkflowSerializationContext(
clientOptions.getNamespace(), input.getWorkflowExecution().getWorkflowId()));

return new DescribeWorkflowOutput(
new WorkflowExecutionDescription(response, dataConverterWithWorkflowContext));
}

private static <R> R convertResultPayloads(
Optional<Payloads> resultValue,
Class<R> resultClass,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ CompletableFuture<ListWorkflowExecutionsResponse> listWorkflowExecutionsAsync(

DescribeScheduleResponse describeSchedule(DescribeScheduleRequest request);

DescribeWorkflowExecutionResponse describeWorkflowExecution(
DescribeWorkflowExecutionRequest request);

@Experimental
UpdateWorkerBuildIdCompatibilityResponse updateWorkerBuildIdCompatability(
UpdateWorkerBuildIdCompatibilityRequest request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,18 @@ public DescribeScheduleResponse describeSchedule(DescribeScheduleRequest request
grpcRetryerOptions);
}

@Override
public DescribeWorkflowExecutionResponse describeWorkflowExecution(
DescribeWorkflowExecutionRequest request) {
return grpcRetryer.retryWithResult(
() ->
service
.blockingStub()
.withOption(METRICS_TAGS_CALL_OPTIONS_KEY, metricsScope)
.describeWorkflowExecution(request),
grpcRetryerOptions);
}

private static <T> CompletableFuture<T> toCompletableFuture(
ListenableFuture<T> listenableFuture) {
CompletableFuture<T> result = new CompletableFuture<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2022 Temporal Technologies, Inc. All Rights Reserved.
*
* Copyright (C) 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this material except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.temporal.workflow;

import static org.junit.Assert.assertEquals;

import io.temporal.client.WorkflowExecutionDescription;
import io.temporal.client.WorkflowStub;
import io.temporal.testing.internal.SDKTestWorkflowRule;
import io.temporal.workflow.shared.TestWorkflows.TestWorkflow1;
import org.junit.Rule;
import org.junit.Test;

public class WorkflowDescribe {

@Rule
public SDKTestWorkflowRule testWorkflowRule =
SDKTestWorkflowRule.newBuilder().setWorkflowTypes(TestInitWorkflow.class).build();

@Test
public void testWorkflowDescribe() {
TestWorkflow1 workflowStub =
testWorkflowRule.newWorkflowStubTimeoutOptions(TestWorkflow1.class);
String result = workflowStub.execute(testWorkflowRule.getTaskQueue());
assertEquals(testWorkflowRule.getTaskQueue(), result);
WorkflowExecutionDescription description = WorkflowStub.fromTyped(workflowStub).describe();
assertEquals(testWorkflowRule.getTaskQueue(), description.getTaskQueue());
assertEquals("TestWorkflow1", description.getWorkflowType());
assertEquals(WorkflowStub.fromTyped(workflowStub).getExecution(), description.getExecution());
}

public static class TestInitWorkflow implements TestWorkflow1 {
@Override
public String execute(String taskQueue) {
return taskQueue;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3024,7 +3024,8 @@ private DescribeWorkflowExecutionResponse describeWorkflowExecutionInsideLock()
// No setAutoResetPoints - the test environment doesn't support that feature
.setSearchAttributes(visibilityStore.getSearchAttributesForExecution(executionId))
.setStatus(this.getWorkflowExecutionStatus())
.setHistoryLength(fullHistory.size());
.setHistoryLength(fullHistory.size())
.setTaskQueue(this.getStartRequest().getTaskQueue().getName());

populateWorkflowExecutionInfoFromHistory(executionInfo, fullHistory);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ public WorkflowStub newInstance(WorkflowOptions options) {
return new TimeLockingWorkflowStub(locker, next.newInstance(options));
}

@Override
public WorkflowExecutionDescription describe() {
return next.describe();
}

/** Unlocks time skipping before blocking calls and locks back after completion. */
private class TimeLockingFuture<R> extends CompletableFuture<R> {

Expand Down

0 comments on commit da59a8d

Please sign in to comment.