Skip to content

Commit 09bc3d8

Browse files
committed
.
1 parent 9346441 commit 09bc3d8

File tree

3 files changed

+286
-0
lines changed

3 files changed

+286
-0
lines changed
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import * as vscode from 'vscode'
7+
import { getLogger } from '../../../shared/logger/logger'
8+
import { EventBridgeSchedulerService, ScheduleConfig } from '../eventBridgeSchedulerService'
9+
import { showQuickPick, showInputBox } from '../../../shared/ui/pickerPrompter'
10+
import { createQuickStartUrl } from '../../../shared/utilities/workspaceUtils'
11+
12+
/**
13+
* Command to create a new EventBridge Scheduler schedule
14+
*
15+
* This command guides users through creating schedules for automated task execution.
16+
* EventBridge Scheduler supports various target types including Lambda functions,
17+
* SQS queues, SNS topics, and Step Functions state machines.
18+
*
19+
* Features:
20+
* - Support for cron and rate expressions
21+
* - Flexible time windows for fault tolerance
22+
* - Multiple target integrations
23+
* - Timezone support for cron schedules
24+
*/
25+
export async function createEventBridgeSchedule(): Promise<void> {
26+
const logger = getLogger()
27+
logger.info('Starting EventBridge Scheduler create schedule workflow')
28+
29+
try {
30+
const schedulerService = new EventBridgeSchedulerService()
31+
32+
// Get schedule name
33+
const scheduleName = await showInputBox({
34+
title: 'Schedule Name',
35+
placeholder: 'my-daily-backup-schedule',
36+
validateInput: (input) => {
37+
if (!input || input.trim().length === 0) {
38+
return 'Schedule name is required'
39+
}
40+
if (input.length > 64) {
41+
return 'Schedule name must be 64 characters or fewer'
42+
}
43+
if (!/^[a-zA-Z0-9\-_]+$/.test(input)) {
44+
return 'Schedule name can only contain letters, numbers, hyphens, and underscores'
45+
}
46+
return undefined
47+
}
48+
})
49+
50+
if (!scheduleName) {
51+
return
52+
}
53+
54+
// Get schedule type
55+
const scheduleType = await showQuickPick([
56+
{ label: 'Rate-based', detail: 'Run at regular intervals (every X minutes/hours/days)' },
57+
{ label: 'Cron-based', detail: 'Run based on cron expression (specific times/dates)' },
58+
{ label: 'One-time', detail: 'Run once at a specific date and time' }
59+
], {
60+
title: 'Schedule Type',
61+
ignoreFocusOut: true
62+
})
63+
64+
if (!scheduleType) {
65+
return
66+
}
67+
68+
// Get schedule expression based on type
69+
let scheduleExpression: string
70+
switch (scheduleType.label) {
71+
case 'Rate-based':
72+
scheduleExpression = await getRateExpression()
73+
break
74+
case 'Cron-based':
75+
scheduleExpression = await getCronExpression()
76+
break
77+
case 'One-time':
78+
scheduleExpression = await getOneTimeExpression()
79+
break
80+
default:
81+
return
82+
}
83+
84+
if (!scheduleExpression) {
85+
return
86+
}
87+
88+
// Get target type
89+
const targetType = await showQuickPick([
90+
{ label: 'lambda', detail: 'AWS Lambda function' },
91+
{ label: 'sqs', detail: 'Amazon SQS queue' },
92+
{ label: 'sns', detail: 'Amazon SNS topic' },
93+
{ label: 'stepfunctions', detail: 'AWS Step Functions state machine' },
94+
{ label: 'eventbridge', detail: 'Amazon EventBridge custom bus' }
95+
], {
96+
title: 'Target Type',
97+
ignoreFocusOut: true
98+
})
99+
100+
if (!targetType) {
101+
return
102+
}
103+
104+
// For now, show a placeholder message
105+
await vscode.window.showInformationMessage(
106+
`EventBridge Scheduler integration is not yet fully implemented. ` +
107+
`Schedule "${scheduleName}" with expression "${scheduleExpression}" ` +
108+
`targeting ${targetType.label} would be created.`,
109+
'View Documentation'
110+
).then(async (selection) => {
111+
if (selection === 'View Documentation') {
112+
await schedulerService.openScheduleTypesDocumentation()
113+
}
114+
})
115+
116+
} catch (error) {
117+
logger.error('Failed to create EventBridge Scheduler schedule:', error)
118+
await vscode.window.showErrorMessage(`Failed to create schedule: ${error}`)
119+
}
120+
}
121+
122+
async function getRateExpression(): Promise<string | undefined> {
123+
const interval = await showInputBox({
124+
title: 'Rate Interval',
125+
placeholder: '5 minutes',
126+
prompt: 'Enter interval (e.g., "5 minutes", "1 hour", "2 days")',
127+
validateInput: (input) => {
128+
if (!input || !/^\d+\s+(minute|minutes|hour|hours|day|days)$/.test(input.trim())) {
129+
return 'Please enter a valid interval (e.g., "5 minutes", "1 hour", "2 days")'
130+
}
131+
return undefined
132+
}
133+
})
134+
135+
return interval ? `rate(${interval})` : undefined
136+
}
137+
138+
async function getCronExpression(): Promise<string | undefined> {
139+
const cronExpr = await showInputBox({
140+
title: 'Cron Expression',
141+
placeholder: '0 12 * * ? *',
142+
prompt: 'Enter cron expression (6 fields: minute hour day month day-of-week year)',
143+
validateInput: (input) => {
144+
if (!input || input.trim().split(/\s+/).length !== 6) {
145+
return 'Cron expression must have exactly 6 fields'
146+
}
147+
return undefined
148+
}
149+
})
150+
151+
return cronExpr ? `cron(${cronExpr})` : undefined
152+
}
153+
154+
async function getOneTimeExpression(): Promise<string | undefined> {
155+
const datetime = await showInputBox({
156+
title: 'One-time Schedule',
157+
placeholder: '2024-12-31T23:59:59',
158+
prompt: 'Enter date and time (ISO 8601 format: YYYY-MM-DDTHH:MM:SS)',
159+
validateInput: (input) => {
160+
if (!input || !input.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/)) {
161+
return 'Please enter date in ISO 8601 format (YYYY-MM-DDTHH:MM:SS)'
162+
}
163+
return undefined
164+
}
165+
})
166+
167+
return datetime ? `at(${datetime})` : undefined
168+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import * as vscode from 'vscode'
7+
import { getLogger } from '../../shared/logger/logger'
8+
import {
9+
eventBridgeSchedulerCreateScheduleUrl,
10+
eventBridgeSchedulerApiGatewayUrl,
11+
eventBridgeSchedulerRolePermissionsUrl
12+
} from '../../shared/constants'
13+
14+
/**
15+
* Service for managing Amazon EventBridge Scheduler schedules
16+
*
17+
* EventBridge Scheduler allows you to create, run, and manage tasks at scale.
18+
* It supports flexible scheduling patterns including one-time schedules,
19+
* recurring schedules with cron expressions, and rate-based schedules.
20+
*/
21+
export class EventBridgeSchedulerService {
22+
private readonly logger = getLogger()
23+
24+
/**
25+
* Creates a new schedule in EventBridge Scheduler
26+
*
27+
* @param scheduleName - Name of the schedule to create
28+
* @param scheduleExpression - Cron or rate expression for the schedule
29+
* @param target - The target service to invoke (Lambda, SQS, SNS, etc.)
30+
*/
31+
public async createSchedule(
32+
scheduleName: string,
33+
scheduleExpression: string,
34+
target: ScheduleTarget
35+
): Promise<void> {
36+
this.logger.info(`Creating EventBridge Scheduler schedule: ${scheduleName}`)
37+
38+
// Implementation would go here
39+
// This would integrate with the AWS EventBridge Scheduler API
40+
41+
throw new Error('EventBridge Scheduler integration not yet implemented')
42+
}
43+
44+
/**
45+
* Opens documentation about EventBridge Scheduler schedule types
46+
*/
47+
public async openScheduleTypesDocumentation(): Promise<void> {
48+
await vscode.env.openExternal(vscode.Uri.parse(eventBridgeSchedulerCreateScheduleUrl))
49+
}
50+
51+
/**
52+
* Opens documentation about managing schedules
53+
*/
54+
public async openManageSchedulesDocumentation(): Promise<void> {
55+
await vscode.env.openExternal(vscode.Uri.parse(eventBridgeSchedulerApiGatewayUrl))
56+
}
57+
58+
/**
59+
* Opens documentation about setting up IAM permissions
60+
*/
61+
public async openPermissionsDocumentation(): Promise<void> {
62+
await vscode.env.openExternal(vscode.Uri.parse(eventBridgeSchedulerRolePermissionsUrl))
63+
}
64+
}
65+
66+
/**
67+
* Represents a target for an EventBridge Scheduler schedule
68+
*/
69+
export interface ScheduleTarget {
70+
/** The ARN of the target resource */
71+
arn: string
72+
73+
/** IAM role ARN for scheduler to assume when invoking the target */
74+
roleArn: string
75+
76+
/** Input data to pass to the target */
77+
input?: string
78+
79+
/** Type of target (lambda, sqs, sns, etc.) */
80+
type: 'lambda' | 'sqs' | 'sns' | 'stepfunctions' | 'eventbridge' | 'kinesis'
81+
}
82+
83+
/**
84+
* Configuration for creating a schedule
85+
*/
86+
export interface ScheduleConfig {
87+
/** Name of the schedule */
88+
name: string
89+
90+
/** Description of the schedule */
91+
description?: string
92+
93+
/** Schedule expression (cron or rate) */
94+
scheduleExpression: string
95+
96+
/** Target to invoke */
97+
target: ScheduleTarget
98+
99+
/** Whether the schedule is enabled */
100+
enabled: boolean
101+
102+
/** Timezone for cron expressions */
103+
timezone?: string
104+
105+
/** Flexible time window settings */
106+
flexibleTimeWindow?: {
107+
mode: 'OFF' | 'FLEXIBLE'
108+
maximumWindowInMinutes?: number
109+
}
110+
}

packages/core/src/shared/constants.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,14 @@ export const amazonQHelpUrl = 'https://aws.amazon.com/q/'
189189
export const amazonQVscodeMarketplace =
190190
'https://marketplace.visualstudio.com/items?itemName=AmazonWebServices.amazon-q-vscode'
191191

192+
// URLs for Amazon EventBridge Scheduler
193+
export const eventBridgeSchedulerCreateScheduleUrl: string =
194+
'https://docs.aws.amazon.com/scheduler/latest/UserGuide/schedule-types.html'
195+
export const eventBridgeSchedulerApiGatewayUrl: string =
196+
'https://docs.aws.amazon.com/scheduler/latest/UserGuide/managing-schedule.html'
197+
export const eventBridgeSchedulerRolePermissionsUrl: string =
198+
'https://docs.aws.amazon.com/scheduler/latest/UserGuide/setting-up.html'
199+
192200
/**
193201
* Names of directories relevant to the crash reporting functionality.
194202
*

0 commit comments

Comments
 (0)