Skip to content

Commit f8d4757

Browse files
l0minousDiler Zaza
andauthored
feat(stepfunctions): Enable execution details page (#7578)
## Problem `View Execution Details by Execution ARN` command currently only opens a placeholder Hello World webview instead of an Execution Details page. ## Solution - Modify `workflowStudioApiHandler.ts` into `StepFunctionApiHandler.ts` as well adding ability to perform Api calls for execution detail specific APIs - Updating `types.ts` , `stepFunctions.ts` (in clients folder) , `executionDetailProvider.ts` to support new API calls and sdk v3 - Implementing separate `handleMessage.ts` to handle messaging between Execution Details webview and toolkit ## Verification ![test2](https://github.com/user-attachments/assets/c67cce37-bdf4-4eb9-86c6-2b80f281c428) --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --------- Co-authored-by: Diler Zaza <[email protected]>
1 parent e489f68 commit f8d4757

File tree

12 files changed

+253
-59
lines changed

12 files changed

+253
-59
lines changed

packages/core/package.nls.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
"AWS.stepFunctions.executeStateMachine.info.executing": "Starting execution of '{0}' in {1}...",
3333
"AWS.stepFunctions.executeStateMachine.info.started": "Execution started",
3434
"AWS.stepFunctions.executeStateMachine.error.failedToStart": "There was an error starting execution for '{0}', check AWS Toolkit logs for more information.",
35-
"AWS.stepfunctions.viewExecutionDetailsByExecutionARN": "View Execution Details by Execution ARN",
3635
"AWS.stepFunctions.asl.format.enable.desc": "Enables the default formatter used with Amazon States Language files",
3736
"AWS.stepFunctions.asl.maxItemsComputed.desc": "The maximum number of outline symbols and folding regions computed (limited for performance reasons).",
3837
"AWS.stepFunctions.workflowStudio.actions.progressMessage": "Opening asl file in Workflow Studio",
@@ -229,6 +228,7 @@
229228
"AWS.command.stepFunctions.createStateMachineFromTemplate": "Create a new Step Functions state machine",
230229
"AWS.command.stepFunctions.publishStateMachine": "Publish state machine to Step Functions",
231230
"AWS.command.stepFunctions.openWithWorkflowStudio": "Open with Workflow Studio",
231+
"AWS.command.stepFunctions.viewExecutionDetailsByExecutionARN": "View Execution Details by Execution ARN",
232232
"AWS.command.cdk.previewStateMachine": "Render state machine graph from CDK application",
233233
"AWS.command.copyLogResource": "Copy Log Stream or Group",
234234
"AWS.command.saveCurrentLogDataContent": "Save Log to File",

packages/core/src/shared/clients/stepFunctions.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,35 @@ import {
77
CreateStateMachineCommand,
88
CreateStateMachineCommandInput,
99
CreateStateMachineCommandOutput,
10+
DescribeExecutionCommand,
11+
DescribeExecutionCommandInput,
12+
DescribeExecutionCommandOutput,
13+
DescribeMapRunCommand,
14+
DescribeMapRunCommandInput,
15+
DescribeMapRunCommandOutput,
1016
DescribeStateMachineCommand,
1117
DescribeStateMachineCommandInput,
1218
DescribeStateMachineCommandOutput,
19+
DescribeStateMachineForExecutionCommand,
20+
DescribeStateMachineForExecutionCommandInput,
21+
DescribeStateMachineForExecutionCommandOutput,
22+
GetExecutionHistoryCommand,
23+
GetExecutionHistoryCommandInput,
24+
GetExecutionHistoryCommandOutput,
1325
ListStateMachinesCommand,
1426
ListStateMachinesCommandInput,
1527
ListStateMachinesCommandOutput,
28+
RedriveExecutionCommand,
29+
RedriveExecutionCommandInput,
30+
RedriveExecutionCommandOutput,
1631
SFNClient,
1732
StartExecutionCommand,
1833
StartExecutionCommandInput,
1934
StartExecutionCommandOutput,
2035
StateMachineListItem,
36+
StopExecutionCommand,
37+
StopExecutionCommandInput,
38+
StopExecutionCommandOutput,
2139
TestStateCommand,
2240
TestStateCommandInput,
2341
TestStateCommandOutput,
@@ -50,10 +68,38 @@ export class StepFunctionsClient extends ClientWrapper<SFNClient> {
5068
return this.makeRequest(DescribeStateMachineCommand, request)
5169
}
5270

71+
public async describeStateMachineForExecution(
72+
request: DescribeStateMachineForExecutionCommandInput
73+
): Promise<DescribeStateMachineForExecutionCommandOutput> {
74+
return this.makeRequest(DescribeStateMachineForExecutionCommand, request)
75+
}
76+
77+
public async describeExecution(request: DescribeExecutionCommandInput): Promise<DescribeExecutionCommandOutput> {
78+
return this.makeRequest(DescribeExecutionCommand, request)
79+
}
80+
81+
public async describeMapRun(request: DescribeMapRunCommandInput): Promise<DescribeMapRunCommandOutput> {
82+
return this.makeRequest(DescribeMapRunCommand, request)
83+
}
84+
85+
public async getExecutionHistory(
86+
request: GetExecutionHistoryCommandInput
87+
): Promise<GetExecutionHistoryCommandOutput> {
88+
return this.makeRequest(GetExecutionHistoryCommand, request)
89+
}
90+
91+
public async reDriveExecution(request: RedriveExecutionCommandInput): Promise<RedriveExecutionCommandOutput> {
92+
return this.makeRequest(RedriveExecutionCommand, request)
93+
}
94+
5395
public async executeStateMachine(request: StartExecutionCommandInput): Promise<StartExecutionCommandOutput> {
5496
return this.makeRequest(StartExecutionCommand, request)
5597
}
5698

99+
public async stopExecution(request: StopExecutionCommandInput): Promise<StopExecutionCommandOutput> {
100+
return this.makeRequest(StopExecutionCommand, request)
101+
}
102+
57103
public async createStateMachine(request: CreateStateMachineCommandInput): Promise<CreateStateMachineCommandOutput> {
58104
return this.makeRequest(CreateStateMachineCommand, request)
59105
}

packages/core/src/stepFunctions/commands/visualizeStateMachine/renderStateMachineGraphCDK.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { isTreeNode } from '../../../shared/treeview/resourceTreeDataProvider'
1212
import { unboxTreeNode } from '../../../shared/treeview/utils'
1313
import { Commands } from '../../../shared/vscode/commands2'
1414
import { PreviewStateMachineCDKWizard } from '../../wizards/previewStateMachineCDKWizard'
15-
import { WorkflowMode } from '../../workflowStudio/types'
15+
import { WorkflowMode } from '../../messageHandlers/types'
1616
import { WorkflowStudioEditorProvider } from '../../workflowStudio/workflowStudioEditorProvider'
1717
import { getStateMachineDefinitionFromCfnTemplate } from './getStateMachineDefinitionFromCfnTemplate'
1818

packages/core/src/stepFunctions/executionDetails/executionDetailProvider.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ import { getLogger } from '../../shared/logger/logger'
88
import request from '../../shared/request'
99
import { ToolkitError } from '../../shared/errors'
1010
import { i18n } from '../../shared/i18n-helper'
11-
import { ComponentType } from '../workflowStudio/types'
11+
import { ComponentType } from '../messageHandlers/types'
1212
import { isLocalDev, localhost, cdn } from '../constants/webviewResources'
13+
import { handleMessage } from './handleMessage'
14+
import { ExecutionDetailsContext } from '../messageHandlers/types'
1315

1416
/**
1517
* Provider for Execution Details panels.
@@ -98,11 +100,16 @@ export class ExecutionDetailProvider {
98100

99101
// Set up the content
100102
panel.webview.html = await this.getWebviewContent()
103+
const context: ExecutionDetailsContext = {
104+
panel,
105+
loaderNotification: undefined,
106+
executionArn,
107+
}
101108

102109
// Handle messages from the webview
103110
panel.webview.onDidReceiveMessage(async (message) => {
104111
this.logger.debug('Received message from execution details webview: %O', message)
105-
// Add message handlers as needed
112+
await handleMessage(message, context)
106113
})
107114
} catch (err) {
108115
void vscode.window.showErrorMessage(i18n('AWS.stepFunctions.executionDetails.failed'))
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
/*!
3+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
import {
8+
Command,
9+
Message,
10+
MessageType,
11+
ExecutionDetailsContext,
12+
ApiCallRequestMessage,
13+
InitResponseMessage,
14+
} from '../messageHandlers/types'
15+
import {
16+
loadStageMessageHandler,
17+
handleUnsupportedMessage,
18+
apiCallMessageHandler,
19+
} from '../messageHandlers/handleMessageHelpers'
20+
21+
/**
22+
* Handles messages received from the ExecutionDetails webview. Depending on the message type and command,
23+
* calls the appropriate handler function
24+
* @param message The message received from the webview
25+
* @param context The context object containing information about the execution details webview environment
26+
*/
27+
export async function handleMessage(message: Message, context: ExecutionDetailsContext) {
28+
const { command, messageType } = message
29+
if (messageType === MessageType.REQUEST) {
30+
switch (command) {
31+
case Command.INIT:
32+
void initMessageHandler(context)
33+
break
34+
case Command.API_CALL:
35+
void apiCallMessageHandler(message as ApiCallRequestMessage, context)
36+
break
37+
default:
38+
void handleUnsupportedMessage(context, message)
39+
break
40+
}
41+
} else if (messageType === MessageType.BROADCAST) {
42+
switch (command) {
43+
case Command.LOAD_STAGE:
44+
void loadStageMessageHandler(context)
45+
break
46+
default:
47+
void handleUnsupportedMessage(context, message)
48+
break
49+
}
50+
} else {
51+
void handleUnsupportedMessage(context, message)
52+
}
53+
}
54+
55+
/**
56+
* Handler for when the webview is ready.
57+
* This handler is used to initialize the webview with execution details.
58+
* @param context The context object containing the necessary information for the webview.
59+
*/
60+
async function initMessageHandler(context: ExecutionDetailsContext) {
61+
try {
62+
await context.panel.webview.postMessage({
63+
messageType: MessageType.BROADCAST,
64+
command: Command.INIT,
65+
executionArn: context.executionArn,
66+
})
67+
} catch (e) {
68+
await context.panel.webview.postMessage({
69+
messageType: MessageType.RESPONSE,
70+
command: Command.INIT,
71+
isSuccess: false,
72+
failureReason: (e as Error).message,
73+
} as InitResponseMessage)
74+
}
75+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
/*!
3+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
import { Command, Message, MessageType, BaseContext, ApiCallRequestMessage, UnsupportedMessage } from './types'
8+
import { StepFunctionApiHandler } from './stepFunctionApiHandler'
9+
import globals from '../../shared/extensionGlobals'
10+
import { getLogger } from '../../shared/logger/logger'
11+
12+
/**
13+
* Handler for managing webview stage load, which updates load notifications.
14+
* @param context The context object containing the necessary information for the webview.
15+
*/
16+
export async function loadStageMessageHandler(context: BaseContext) {
17+
context.loaderNotification?.progress.report({ increment: 25 })
18+
setTimeout(() => {
19+
context.loaderNotification?.resolve()
20+
}, 100)
21+
}
22+
23+
/**
24+
* Handler for making API calls from the webview and returning the response.
25+
* @param request The request message containing the API to call and the parameters
26+
* @param context The webview context used for returning the API response to the webview
27+
*/
28+
export function apiCallMessageHandler(request: ApiCallRequestMessage, context: BaseContext) {
29+
const logger = getLogger('stepfunctions')
30+
const apiHandler = new StepFunctionApiHandler(globals.awsContext.getCredentialDefaultRegion(), context)
31+
apiHandler.performApiCall(request).catch((error) => logger.error('%s API call failed: %O', request.apiName, error))
32+
}
33+
34+
/**
35+
* Handles unsupported or unrecognized messages by sending a response to the webview. Ensures compatibility with future
36+
* commands and message types, preventing issues if the user has an outdated extension version.
37+
* @param context The context object containing information about the webview environment
38+
* @param command The command received from the webview
39+
* @param messageType The type of the message received
40+
*/
41+
export async function handleUnsupportedMessage(context: BaseContext, originalMessage: Message) {
42+
await context.panel.webview.postMessage({
43+
messageType: MessageType.RESPONSE,
44+
command: Command.UNSUPPORTED_COMMAND,
45+
originalMessage,
46+
} as UnsupportedMessage)
47+
}

packages/core/src/stepFunctions/workflowStudio/workflowStudioApiHandler.ts renamed to packages/core/src/stepFunctions/messageHandlers/stepFunctionApiHandler.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
import * as StepFunctions from '@aws-sdk/client-sfn'
77
import { IamClient, IamRole } from '../../shared/clients/iam'
88
import { StepFunctionsClient } from '../../shared/clients/stepFunctions'
9-
import { ApiAction, ApiCallRequestMessage, Command, MessageType, WebviewContext } from './types'
9+
import { ApiAction, ApiCallRequestMessage, Command, MessageType, BaseContext } from './types'
1010
import { telemetry } from '../../shared/telemetry/telemetry'
1111
import { ListRolesRequest } from '@aws-sdk/client-iam'
1212

13-
export class WorkflowStudioApiHandler {
13+
export class StepFunctionApiHandler {
1414
public constructor(
1515
region: string,
16-
private readonly context: WebviewContext,
16+
private readonly context: BaseContext,
1717
private readonly clients = {
1818
sfn: new StepFunctionsClient(region),
1919
iam: new IamClient(region),
@@ -33,6 +33,30 @@ export class WorkflowStudioApiHandler {
3333
case ApiAction.SFNTestState:
3434
response = await this.testState(params)
3535
break
36+
case ApiAction.SFNDescribeStateMachine:
37+
response = await this.clients.sfn.getStateMachineDetails(params)
38+
break
39+
case ApiAction.SFNDescribeStateMachineForExecution:
40+
response = await this.clients.sfn.describeStateMachineForExecution(params)
41+
break
42+
case ApiAction.SFNDescribeExecution:
43+
response = await this.clients.sfn.describeExecution(params)
44+
break
45+
case ApiAction.SFNDescribeMapRun:
46+
response = await this.clients.sfn.describeMapRun(params)
47+
break
48+
case ApiAction.SFNGetExecutionHistory:
49+
response = await this.clients.sfn.getExecutionHistory(params)
50+
break
51+
case ApiAction.SFNRedriveExecution:
52+
response = await this.clients.sfn.reDriveExecution(params)
53+
break
54+
case ApiAction.SFNStartExecution:
55+
response = await this.clients.sfn.executeStateMachine(params)
56+
break
57+
case ApiAction.SFNStopExecution:
58+
response = await this.clients.sfn.stopExecution(params)
59+
break
3660
default:
3761
throw new Error(`Unknown API: ${apiName}`)
3862
}

packages/core/src/stepFunctions/workflowStudio/types.ts renamed to packages/core/src/stepFunctions/messageHandlers/types.ts

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,27 @@ export enum WorkflowMode {
1616
Readonly = 'readonly',
1717
}
1818

19-
export type WebviewContext = {
19+
export interface BaseContext {
20+
panel: vscode.WebviewPanel
21+
loaderNotification: undefined | LoaderNotification
22+
}
23+
24+
export interface WebviewContext extends BaseContext {
2025
stateMachineName: string
2126
mode: WorkflowMode
22-
panel: vscode.WebviewPanel
2327
textDocument: vscode.TextDocument
2428
disposables: vscode.Disposable[]
2529
workSpacePath: string
2630
defaultTemplatePath: string
2731
defaultTemplateName: string
2832
fileStates: Record<string, FileWatchInfo>
29-
loaderNotification: undefined | LoaderNotification
3033
fileId: string
3134
}
3235

36+
export interface ExecutionDetailsContext extends BaseContext {
37+
executionArn: string
38+
}
39+
3340
export type LoaderNotification = {
3441
progress: vscode.Progress<{
3542
message?: string | undefined
@@ -96,11 +103,27 @@ export interface SyncFileRequestMessage extends SaveFileRequestMessage {
96103
export enum ApiAction {
97104
IAMListRoles = 'iam:ListRoles',
98105
SFNTestState = 'sfn:TestState',
106+
SFNDescribeStateMachine = 'sfn:describeStateMachine',
107+
SFNDescribeStateMachineForExecution = 'sfn:describeStateMachineForExecution',
108+
SFNDescribeExecution = 'sfn:describeExecution',
109+
SFNDescribeMapRun = 'sfn:describeMapRun',
110+
SFNGetExecutionHistory = 'sfn:getExecutionHistory',
111+
SFNRedriveExecution = 'sfn:redriveExecution',
112+
SFNStartExecution = 'sfn:startExecution',
113+
SFNStopExecution = 'sfn:stopExecution',
99114
}
100115

101116
type ApiCallRequestMapping = {
102117
[ApiAction.IAMListRoles]: IAM.ListRolesRequest
103118
[ApiAction.SFNTestState]: StepFunctions.TestStateInput
119+
[ApiAction.SFNDescribeStateMachine]: StepFunctions.DescribeStateMachineInput
120+
[ApiAction.SFNDescribeStateMachineForExecution]: StepFunctions.DescribeStateMachineForExecutionInput
121+
[ApiAction.SFNDescribeExecution]: StepFunctions.DescribeExecutionInput
122+
[ApiAction.SFNDescribeMapRun]: StepFunctions.DescribeMapRunInput
123+
[ApiAction.SFNGetExecutionHistory]: StepFunctions.GetExecutionHistoryInput
124+
[ApiAction.SFNRedriveExecution]: StepFunctions.RedriveExecutionInput
125+
[ApiAction.SFNStartExecution]: StepFunctions.StartExecutionInput
126+
[ApiAction.SFNStopExecution]: StepFunctions.StopExecutionInput
104127
}
105128

106129
interface ApiCallRequestMessageBase<ApiName extends ApiAction> extends Message {
@@ -115,3 +138,11 @@ interface ApiCallRequestMessageBase<ApiName extends ApiAction> extends Message {
115138
export type ApiCallRequestMessage =
116139
| ApiCallRequestMessageBase<ApiAction.IAMListRoles>
117140
| ApiCallRequestMessageBase<ApiAction.SFNTestState>
141+
| ApiCallRequestMessageBase<ApiAction.SFNDescribeStateMachine>
142+
| ApiCallRequestMessageBase<ApiAction.SFNDescribeStateMachineForExecution>
143+
| ApiCallRequestMessageBase<ApiAction.SFNDescribeExecution>
144+
| ApiCallRequestMessageBase<ApiAction.SFNDescribeMapRun>
145+
| ApiCallRequestMessageBase<ApiAction.SFNGetExecutionHistory>
146+
| ApiCallRequestMessageBase<ApiAction.SFNRedriveExecution>
147+
| ApiCallRequestMessageBase<ApiAction.SFNStartExecution>
148+
| ApiCallRequestMessageBase<ApiAction.SFNStopExecution>

0 commit comments

Comments
 (0)