Skip to content

Commit 5330f3d

Browse files
author
Diler Zaza
committed
Supporting express executions
1 parent 3d63696 commit 5330f3d

File tree

6 files changed

+83
-6
lines changed

6 files changed

+83
-6
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,18 @@ export class DefaultLambdaClient {
120120
}
121121
}
122122

123+
public async getFunctionConfiguration(name: string): Promise<Lambda.FunctionConfiguration> {
124+
const client = await this.createSdkClient()
125+
try {
126+
const request = client.getFunctionConfiguration({ FunctionName: name })
127+
const response = await request.promise()
128+
return response
129+
} catch (e) {
130+
getLogger().error('Failed to get function configuration: %s', e)
131+
throw e
132+
}
133+
}
134+
123135
private async createSdkClient(): Promise<Lambda> {
124136
return await globals.sdkClientBuilder.createAwsService(
125137
Lambda,

packages/core/src/stepFunctions/activation.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,11 @@ async function registerStepFunctionCommands(
105105
prompt: 'Enter Execution ARN',
106106
placeHolder:
107107
'arn:aws:states:us-east-1:123456789012:execution:MyStateMachine:12345678-1234-1234-1234-123456789012',
108+
ignoreFocusOut: true,
108109
})
109110

110111
if (validate(arn)) {
111-
await ExecutionDetailProvider.openExecutionDetails(arn!)
112+
await handleExecutionDetails(arn!)
112113
} else {
113114
void vscode.window.showErrorMessage(
114115
'Invalid ARN format. Please provide a valid Step Functions execution ARN (e.g., arn:aws:states:us-east-1:123456789012:execution:MyStateMachine:12345678-1234-1234-1234-123456789012)'
@@ -118,6 +119,44 @@ async function registerStepFunctionCommands(
118119
)
119120
}
120121

122+
/**
123+
* Determines if a Step Functions execution ARN is for an express execution
124+
* @param arn The execution ARN to check
125+
* @returns true if it's an express execution, false if it's a standard execution
126+
*/
127+
function isExpressExecution(arn: string): boolean {
128+
const arnSegments = arn.split(':')
129+
return arnSegments.length === 9 && arnSegments[5] === 'express'
130+
}
131+
132+
/**
133+
* Handles opening execution details based on execution type (standard vs express)
134+
* @param arn The execution ARN
135+
*/
136+
async function handleExecutionDetails(arn: string): Promise<void> {
137+
if (isExpressExecution(arn)) {
138+
// For express executions, prompt for additional information
139+
const startTime = await vscode.window.showInputBox({
140+
prompt: 'Enter Start Time',
141+
placeHolder: 'Start time of the express execution.',
142+
ignoreFocusOut: true,
143+
})
144+
145+
if (startTime) {
146+
await ExecutionDetailProvider.openExecutionDetails(arn, startTime)
147+
} else {
148+
void vscode.window.showErrorMessage(
149+
'Invalid Start Time. Value must be a Unix timestamp or in date time string format: YYYY-MM-DDTHH:mm:ss.sssZ.'
150+
)
151+
}
152+
}
153+
154+
// For standard executions, directly open execution details
155+
else {
156+
await ExecutionDetailProvider.openExecutionDetails(arn)
157+
}
158+
}
159+
121160
async function startLspServer(extensionContext: vscode.ExtensionContext) {
122161
const perflog = new PerfLog('stepFunctions: start LSP client/server')
123162
await ASLLanguageClient.create(extensionContext)

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export class ExecutionDetailProvider {
2828
*/
2929
public static async openExecutionDetails(
3030
executionArn: string,
31+
startTime?: string,
3132
params?: vscode.WebviewPanelOptions & vscode.WebviewOptions
3233
): Promise<void> {
3334
// Create and show the webview panel
@@ -43,7 +44,7 @@ export class ExecutionDetailProvider {
4344
)
4445
// Create the provider and initialize the panel
4546
const provider = new ExecutionDetailProvider()
46-
await provider.initializePanel(panel, executionArn)
47+
await provider.initializePanel(panel, executionArn, startTime)
4748
}
4849

4950
protected webviewHtml: string
@@ -67,7 +68,7 @@ export class ExecutionDetailProvider {
6768
* Gets the webview content for Execution Details.
6869
* @private
6970
*/
70-
private getWebviewContent = async (executionArn: string): Promise<string> => {
71+
private getWebviewContent = async (executionArn: string, startTime?: string): Promise<string> => {
7172
const htmlFileSplit = this.webviewHtml.split('<head>')
7273

7374
// Set asset source to CDN
@@ -85,22 +86,25 @@ export class ExecutionDetailProvider {
8586
const componentTypeTag = `<meta name="component-type" content="${ComponentType.ExecutionDetails}" />`
8687
const executionArnTag = `<meta name="execution-arn" content="${executionArn}" />`
8788

88-
return `${htmlFileSplit[0]} <head> ${baseTag} ${localeTag} ${darkModeTag} ${componentTypeTag} ${executionArnTag} ${htmlFileSplit[1]}`
89+
// Only include start time tag for express executions (when startTime is provided)
90+
const startTimeTag = startTime ? `<meta name="start-time" content="${startTime}" />` : ''
91+
92+
return `${htmlFileSplit[0]} <head> ${baseTag} ${localeTag} ${darkModeTag} ${componentTypeTag} ${executionArnTag} ${startTimeTag} ${htmlFileSplit[1]}`
8993
}
9094

9195
/**
9296
* Initializes a WebView panel with execution details.
9397
* @param panel The WebView panel to initialize
9498
* @param executionArn The ARN of the execution to display
9599
*/
96-
public async initializePanel(panel: vscode.WebviewPanel, executionArn: string): Promise<void> {
100+
public async initializePanel(panel: vscode.WebviewPanel, executionArn: string, startTime?: string): Promise<void> {
97101
try {
98102
if (!this.webviewHtml) {
99103
await this.fetchWebviewHtml()
100104
}
101105

102106
// Set up the content
103-
panel.webview.html = await this.getWebviewContent(executionArn)
107+
panel.webview.html = await this.getWebviewContent(executionArn, startTime)
104108
const context: ExecutionDetailsContext = {
105109
panel,
106110
loaderNotification: undefined,

packages/core/src/stepFunctions/messageHandlers/stepFunctionApiHandler.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
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 { CloudWatchLogsClient } from '../../shared/clients/cloudWatchLogs'
10+
import { DefaultLambdaClient } from '../../shared/clients/lambdaClient'
911
import { ApiAction, ApiCallRequestMessage, Command, MessageType, BaseContext } from './types'
1012
import { telemetry } from '../../shared/telemetry/telemetry'
1113
import { ListRolesRequest } from '@aws-sdk/client-iam'
@@ -17,6 +19,8 @@ export class StepFunctionApiHandler {
1719
private readonly clients = {
1820
sfn: new StepFunctionsClient(region),
1921
iam: new IamClient(region),
22+
cwl: new CloudWatchLogsClient(region),
23+
lambda: new DefaultLambdaClient(region),
2024
}
2125
) {}
2226

@@ -57,6 +61,12 @@ export class StepFunctionApiHandler {
5761
case ApiAction.SFNStopExecution:
5862
response = await this.clients.sfn.stopExecution(params)
5963
break
64+
case ApiAction.CWlFilterLogEvents:
65+
response = await this.clients.cwl.filterLogEvents(params)
66+
break
67+
case ApiAction.LambdaGetFunctionConfiguration:
68+
response = await this.clients.lambda.getFunctionConfiguration(params.FunctionName!)
69+
break
6070
default:
6171
throw new Error(`Unknown API: ${apiName}`)
6272
}

packages/core/src/stepFunctions/messageHandlers/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*/
55
import { IAM } from 'aws-sdk'
66
import * as StepFunctions from '@aws-sdk/client-sfn'
7+
import * as CloudWatchLogs from '@aws-sdk/client-cloudwatch-logs'
8+
import * as Lambda from '@aws-sdk/client-lambda'
79
import * as vscode from 'vscode'
810

911
export enum ComponentType {
@@ -111,6 +113,8 @@ export enum ApiAction {
111113
SFNRedriveExecution = 'sfn:redriveExecution',
112114
SFNStartExecution = 'sfn:startExecution',
113115
SFNStopExecution = 'sfn:stopExecution',
116+
CWlFilterLogEvents = 'cwl:filterLogEvents',
117+
LambdaGetFunctionConfiguration = 'lambda:getFunctionConfiguration',
114118
}
115119

116120
type ApiCallRequestMapping = {
@@ -124,6 +128,8 @@ type ApiCallRequestMapping = {
124128
[ApiAction.SFNRedriveExecution]: StepFunctions.RedriveExecutionInput
125129
[ApiAction.SFNStartExecution]: StepFunctions.StartExecutionInput
126130
[ApiAction.SFNStopExecution]: StepFunctions.StopExecutionInput
131+
[ApiAction.CWlFilterLogEvents]: CloudWatchLogs.FilterLogEventsCommandInput
132+
[ApiAction.LambdaGetFunctionConfiguration]: Lambda.GetFunctionConfigurationCommandInput
127133
}
128134

129135
interface ApiCallRequestMessageBase<ApiName extends ApiAction> extends Message {
@@ -146,3 +152,5 @@ export type ApiCallRequestMessage =
146152
| ApiCallRequestMessageBase<ApiAction.SFNRedriveExecution>
147153
| ApiCallRequestMessageBase<ApiAction.SFNStartExecution>
148154
| ApiCallRequestMessageBase<ApiAction.SFNStopExecution>
155+
| ApiCallRequestMessageBase<ApiAction.CWlFilterLogEvents>
156+
| ApiCallRequestMessageBase<ApiAction.LambdaGetFunctionConfiguration>

packages/core/src/test/stepFunctions/apiHandler/stepFunctionApiHandler.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import {
1717
import * as vscode from 'vscode'
1818
import { assertTelemetry } from '../../testUtil'
1919
import { StepFunctionsClient } from '../../../shared/clients/stepFunctions'
20+
import { CloudWatchLogsClient } from '../../../shared/clients/cloudWatchLogs'
21+
import { DefaultLambdaClient } from '../../../shared/clients/lambdaClient'
2022
import { IamClient } from '../../../shared/clients/iam'
2123

2224
describe('stepFunctionApiHandler', function () {
@@ -68,6 +70,8 @@ describe('stepFunctionApiHandler', function () {
6870
apiHandler = new StepFunctionApiHandler('us-east-1', context, {
6971
sfn: sfnClient,
7072
iam: new IamClient('us-east-1'),
73+
cwl: new CloudWatchLogsClient('us-east-1'),
74+
lambda: new DefaultLambdaClient('us-east-1'),
7175
})
7276

7377
testState = sinon.stub(sfnClient, 'testState')

0 commit comments

Comments
 (0)