Skip to content

Commit 39dcbe4

Browse files
authored
SAM Step Functions quick start template (#1114)
Authored-by: Vaib Suri <[email protected]>
1 parent 4136553 commit 39dcbe4

File tree

5 files changed

+61
-19
lines changed

5 files changed

+61
-19
lines changed

package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@
337337
"AWS.samcli.initWizard.template.helloWorld.description": "A basic SAM app",
338338
"AWS.samcli.initWizard.template.eventBridge_helloWorld.description": "Invokes a Lambda for every EC2 instance state change in your account",
339339
"AWS.samcli.initWizard.template.eventBridge_starterApp.description": "Invokes a Lambda based on a dynamic event trigger for an EventBridge Schema of your choice",
340+
"AWS.samcli.initWizard.template.stepFunctionsSampleApp.description": "Orchestrates multiple Lambdas to execute a stock trading workflow on an hourly schedule",
340341
"AWS.samcli.initWizard.schemas.region.prompt": "Select an EventBridge Schemas Region",
341342
"AWS.samcli.initWizard.schemas.registry.prompt": "Select a Registry",
342343
"AWS.samcli.initWizard.schemas.registry.failed_to_load_resources": "Error loading registries.",

src/lambda/commands/createNewSamApp.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { fileExists } from '../../shared/filesystemUtilities'
2525
import { getLogger } from '../../shared/logger'
2626
import { RegionProvider } from '../../shared/regions/regionProvider'
2727
import { getRegionsForActiveCredentials } from '../../shared/regions/regionUtilities'
28-
import { getSamCliContext, SamCliContext } from '../../shared/sam/cli/samCliContext'
28+
import { getSamCliVersion, getSamCliContext, SamCliContext } from '../../shared/sam/cli/samCliContext'
2929
import { runSamCliInit, SamCliInitArgs } from '../../shared/sam/cli/samCliInit'
3030
import { throwAndNotifyIfInvalid } from '../../shared/sam/cli/samCliValidationUtils'
3131
import { SamCliValidator } from '../../shared/sam/cli/samCliValidator'
@@ -99,8 +99,9 @@ export async function createNewSamApplication(
9999
const currentCredentials = await awsContext.getCredentials()
100100
const availableRegions = getRegionsForActiveCredentials(awsContext, regionProvider)
101101
const schemasRegions = availableRegions.filter(region => regionProvider.isServiceInRegion('schemas', region.id))
102+
const samCliVersion = await getSamCliVersion(samCliContext)
102103

103-
const wizardContext = new DefaultCreateNewSamAppWizardContext(currentCredentials, schemasRegions)
104+
const wizardContext = new DefaultCreateNewSamAppWizardContext(currentCredentials, schemasRegions, samCliVersion)
104105
config = await new CreateNewSamAppWizard(wizardContext).run()
105106

106107
if (!config) {

src/lambda/models/samTemplates.ts

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,38 @@
55
import * as nls from 'vscode-nls'
66
const localize = nls.loadMessageBundle()
77

8+
import * as semver from 'semver'
89
import { Runtime } from 'aws-sdk/clients/lambda'
910
import { Set } from 'immutable'
1011
import { supportsEventBridgeTemplates } from '../../../src/eventSchemas/models/schemaCodeLangs'
1112

1213
export const helloWorldTemplate = 'AWS SAM Hello World'
1314
export const eventBridgeHelloWorldTemplate = 'AWS SAM EventBridge Hello World'
1415
export const eventBridgeStarterAppTemplate = 'AWS SAM EventBridge App from Scratch'
16+
export const stepFunctionsSampleApp = 'AWS Step Functions Sample App'
1517
export const repromptUserForTemplate = 'REQUIRES_AWS_CREDENTIALS_REPROMPT_USER_FOR_TEMPLATE'
1618

19+
export const CLI_VERSION_STEP_FUNCTIONS_TEMPLATE = '0.52.0'
20+
1721
export type SamTemplate =
1822
| 'AWS SAM Hello World'
1923
| 'AWS SAM EventBridge Hello World'
2024
| 'AWS SAM EventBridge App from Scratch'
25+
| 'AWS Step Functions Sample App'
2126
| 'REQUIRES_AWS_CREDENTIALS_REPROMPT_USER_FOR_TEMPLATE'
2227

23-
export const validTemplateOptions: Set<SamTemplate> = Set<SamTemplate>([
24-
helloWorldTemplate,
25-
eventBridgeHelloWorldTemplate,
26-
eventBridgeStarterAppTemplate,
27-
])
28-
29-
export const helloWorldOption: Set<SamTemplate> = Set<SamTemplate>([helloWorldTemplate])
28+
export function getSamTemplateWizardOption(runtime: Runtime, samCliVersion: string): Set<SamTemplate> {
29+
let templateOptions: Array<SamTemplate> = Array<SamTemplate>(helloWorldTemplate)
3030

31-
export function getSamTemplateWizardOption(runtime: Runtime): Set<SamTemplate> {
3231
if (supportsEventBridgeTemplates(runtime)) {
33-
return validTemplateOptions
32+
templateOptions.push(eventBridgeHelloWorldTemplate, eventBridgeStarterAppTemplate)
3433
}
3534

36-
return helloWorldOption
35+
if (supportsStepFuntionsTemplate(samCliVersion)) {
36+
templateOptions.push(stepFunctionsSampleApp)
37+
}
38+
39+
return Set<SamTemplate>(templateOptions)
3740
}
3841

3942
export function getSamCliTemplateParameter(templateSelected: SamTemplate): string {
@@ -44,6 +47,8 @@ export function getSamCliTemplateParameter(templateSelected: SamTemplate): strin
4447
return 'eventBridge-hello-world'
4548
case eventBridgeStarterAppTemplate:
4649
return 'eventBridge-schema-app'
50+
case stepFunctionsSampleApp:
51+
return 'step-functions-sample-app'
4752
default:
4853
throw new Error(`${templateSelected} is not valid sam template`)
4954
}
@@ -63,7 +68,19 @@ export function getTemplateDescription(template: SamTemplate): string {
6368
'AWS.samcli.initWizard.template.eventBridge_starterApp.description',
6469
'Invokes a Lambda based on a dynamic event trigger for an EventBridge Schema of your choice'
6570
)
71+
case stepFunctionsSampleApp:
72+
return localize(
73+
'AWS.samcli.initWizard.template.stepFunctionsSampleApp.description',
74+
'Orchestrates multiple Lambdas to execute a stock trading workflow on an hourly schedule'
75+
)
6676
default:
6777
throw new Error(`No description found for template ${template}`)
6878
}
6979
}
80+
81+
export function supportsStepFuntionsTemplate(samCliVersion: string): boolean {
82+
if (!samCliVersion) {
83+
return false
84+
}
85+
return semver.gte(samCliVersion, CLI_VERSION_STEP_FUNCTIONS_TEMPLATE)
86+
}

src/lambda/wizards/samInitWizard.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,13 @@ export class DefaultCreateNewSamAppWizardContext extends WizardContext implement
5959
private readonly helpButton = createHelpButton(localize('AWS.command.help', 'View Documentation'))
6060
private readonly currentCredentials: Credentials | undefined
6161
private readonly schemasRegions: Region[]
62+
private readonly samCliVersion: string
6263

63-
public constructor(currentCredentials: Credentials | undefined, schemasRegions: Region[]) {
64+
public constructor(currentCredentials: Credentials | undefined, schemasRegions: Region[], samCliVersion: string) {
6465
super()
6566
this.currentCredentials = currentCredentials
6667
this.schemasRegions = schemasRegions
68+
this.samCliVersion = samCliVersion
6769
}
6870

6971
public async promptUserForRuntime(currRuntime?: Runtime): Promise<Runtime | undefined> {
@@ -104,7 +106,7 @@ export class DefaultCreateNewSamAppWizardContext extends WizardContext implement
104106
currRuntime: Runtime,
105107
currTemplate?: SamTemplate
106108
): Promise<SamTemplate | undefined> {
107-
const templates = getSamTemplateWizardOption(currRuntime)
109+
const templates = getSamTemplateWizardOption(currRuntime, this.samCliVersion)
108110
const quickPick = picker.createQuickPick<vscode.QuickPickItem>({
109111
options: {
110112
ignoreFocusOut: true,

src/test/lambda/models/samTemplates.test.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,35 @@
55

66
import * as assert from 'assert'
77
import {
8+
CLI_VERSION_STEP_FUNCTIONS_TEMPLATE,
89
getSamCliTemplateParameter,
910
getSamTemplateWizardOption,
1011
getTemplateDescription,
11-
helloWorldOption,
1212
repromptUserForTemplate,
13-
validTemplateOptions,
13+
SamTemplate,
14+
helloWorldTemplate,
15+
eventBridgeHelloWorldTemplate,
16+
eventBridgeStarterAppTemplate,
17+
stepFunctionsSampleApp,
1418
} from '../../../lambda/models/samTemplates'
19+
import { Set } from 'immutable'
1520
import { assertThrowsError } from '../../../test/shared/utilities/assertUtils'
1621

1722
import { samLambdaRuntimes } from '../../../lambda/models/samLambdaRuntime'
1823

24+
const validTemplateOptions: Set<SamTemplate> = Set<SamTemplate>([
25+
helloWorldTemplate,
26+
eventBridgeHelloWorldTemplate,
27+
eventBridgeStarterAppTemplate,
28+
stepFunctionsSampleApp,
29+
])
30+
31+
const defaultTemplateOptions: Set<SamTemplate> = Set<SamTemplate>([helloWorldTemplate, stepFunctionsSampleApp])
32+
1933
describe('getSamTemplateWizardOption', () => {
2034
it('should successfully return available templates for specific runtime', () => {
2135
for (const runtime of samLambdaRuntimes.values()) {
22-
const result = getSamTemplateWizardOption(runtime)
36+
const result = getSamTemplateWizardOption(runtime, CLI_VERSION_STEP_FUNCTIONS_TEMPLATE)
2337
switch (runtime) {
2438
case 'python3.6':
2539
case 'python3.7':
@@ -33,13 +47,20 @@ describe('getSamTemplateWizardOption', () => {
3347
default:
3448
assert.deepStrictEqual(
3549
result,
36-
helloWorldOption,
37-
'Rest of the runtimes support hello-world template only'
50+
defaultTemplateOptions,
51+
'Rest of the runtimes support default templates only'
3852
)
3953
break
4054
}
4155
}
4256
})
57+
58+
it('should not return Step Functions templates for a SAM CLI version that does not support them', () => {
59+
for (const runtime of samLambdaRuntimes.values()) {
60+
const result = getSamTemplateWizardOption(runtime, '0.40.0')
61+
assert(!result.contains(stepFunctionsSampleApp))
62+
}
63+
})
4364
})
4465

4566
describe('getSamCliTemplateParameter', () => {

0 commit comments

Comments
 (0)