Skip to content

Commit c942bf7

Browse files
authored
Add Azure deployment support for DTS projects (#4566)
1 parent c769e26 commit c942bf7

40 files changed

+1033
-111
lines changed

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1483,7 +1483,7 @@
14831483
"@azure/storage-blob": "^12.5.0",
14841484
"@microsoft/vscode-azext-azureappservice": "^3.6.4",
14851485
"@microsoft/vscode-azext-azureappsettings": "^0.2.8",
1486-
"@microsoft/vscode-azext-azureutils": "^3.3.3",
1486+
"@microsoft/vscode-azext-azureutils": "^3.4.0",
14871487
"@microsoft/vscode-azext-utils": "^3.1.1",
14881488
"@microsoft/vscode-azureresources-api": "^2.0.4",
14891489
"@microsoft/vscode-container-client": "^0.1.2",

src/commands/appSettings/connectionSettings/ISetConnectionSettingContext.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { type IActionContext } from "@microsoft/vscode-azext-utils";
7-
import { type CodeActionValues, type ConnectionKey } from "../../../constants";
7+
import { type CodeAction, type ConnectionKey } from "../../../constants";
88
import { type IConnectionTypesContext } from "./IConnectionTypesContext";
99

1010
export interface ISetConnectionSettingContext extends IActionContext, IConnectionTypesContext {
11-
action: CodeActionValues;
11+
action: CodeAction;
1212
projectPath: string;
1313

1414
// Remote connections for deploy
1515
[ConnectionKey.Storage]?: string;
1616
[ConnectionKey.EventHubs]?: string;
17+
[ConnectionKey.DTS]?: string;
18+
[ConnectionKey.DTSHub]?: string;
1719
[ConnectionKey.SQL]?: string;
1820
}

src/commands/appSettings/connectionSettings/SetConnectionSettingStepBase.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { AzureWizardExecuteStep } from "@microsoft/vscode-azext-utils";
7-
import { CodeAction, type ConnectionKeyValues } from "../../../constants";
7+
import { CodeAction, type ConnectionKey } from "../../../constants";
88
import { MismatchBehavior, setLocalAppSetting } from "../../../funcConfig/local.settings";
99
import { type ISetConnectionSettingContext } from "./ISetConnectionSettingContext";
1010

1111
export abstract class SetConnectionSettingStepBase<T extends ISetConnectionSettingContext> extends AzureWizardExecuteStep<T> {
12-
public abstract readonly debugDeploySetting: ConnectionKeyValues;
12+
public abstract readonly debugDeploySetting: ConnectionKey;
1313

1414
protected async setConnectionSetting(context: T, value: string): Promise<void> {
1515
if (context.action === CodeAction.Deploy) {

src/commands/appSettings/connectionSettings/azureWebJobsStorage/AzureWebJobsStorageExecuteStep.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { type IStorageAccountWizardContext } from '@microsoft/vscode-azext-azureutils';
7-
import { ConnectionKey, ConnectionType, localStorageEmulatorConnectionString, type ConnectionKeyValues } from '../../../../constants';
7+
import { ConnectionKey, ConnectionType, localStorageEmulatorConnectionString } from '../../../../constants';
88
import { SetConnectionSettingStepBase } from '../SetConnectionSettingStepBase';
99
import { getStorageConnectionString } from '../getLocalConnectionSetting';
1010
import { type IAzureWebJobsStorageWizardContext } from './IAzureWebJobsStorageWizardContext';
1111

1212
export class AzureWebJobsStorageExecuteStep<T extends IAzureWebJobsStorageWizardContext> extends SetConnectionSettingStepBase<T> {
1313
public priority: number = 230;
14-
public debugDeploySetting: ConnectionKeyValues = ConnectionKey.Storage;
14+
public debugDeploySetting: ConnectionKey = ConnectionKey.Storage;
1515

1616
public async execute(context: T): Promise<void> {
1717
let value: string;

src/commands/appSettings/connectionSettings/durableTaskScheduler/DTSConnectionCustomPromptStep.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ import { type IDTSConnectionWizardContext } from './IDTSConnectionWizardContext'
1010

1111
export class DTSConnectionCustomPromptStep<T extends IDTSConnectionWizardContext> extends AzureWizardPromptStep<T> {
1212
public async prompt(context: T): Promise<void> {
13-
context.newDTSConnection = (await context.ui.showInputBox({
13+
context.newDTSConnectionSetting = (await context.ui.showInputBox({
1414
prompt: localize('customDTSConnectionPrompt', 'Provide a custom DTS connection string.'),
1515
validateInput: (value: string | undefined) => this.validateInput(value)
1616
})).trim();
1717
}
1818

1919
public shouldPrompt(context: T): boolean {
20-
return !context.newDTSConnection && context.dtsConnectionType === ConnectionType.Custom;
20+
return !context.newDTSConnectionSetting && context.dtsConnectionType === ConnectionType.Custom;
2121
}
2222

2323
private validateInput(name: string | undefined): string | undefined {
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { VerifyProvidersStep } from '@microsoft/vscode-azext-azureutils';
7+
import { AzureWizardPromptStep, type AzureWizardExecuteStep, type IWizardOptions } from '@microsoft/vscode-azext-utils';
8+
import { type MessageItem } from 'vscode';
9+
import { ConnectionType, DurableTaskProvider } from '../../../../constants';
10+
import { useEmulator } from '../../../../constants-nls';
11+
import { localize } from '../../../../localize';
12+
import { DurableTaskSchedulerListStep } from './azure/DurableTaskSchedulerListStep';
13+
import { DTSConnectionCustomPromptStep } from './custom/DTSConnectionCustomPromptStep';
14+
import { DTSHubNameCustomPromptStep } from './custom/DTSHubNameCustomPromptStep';
15+
import { DTSConnectionSetSettingStep } from './DTSConnectionSetSettingStep';
16+
import { DTSHubNameSetSettingStep } from './DTSHubNameSetSettingStep';
17+
import { DTSEmulatorStartStep } from './emulator/DTSEmulatorStartStep';
18+
import { type IDTSAzureConnectionWizardContext, type IDTSConnectionWizardContext } from './IDTSConnectionWizardContext';
19+
20+
export class DTSConnectionListStep<T extends IDTSConnectionWizardContext> extends AzureWizardPromptStep<T> {
21+
constructor(readonly connectionTypes: Set<ConnectionType>) {
22+
super();
23+
}
24+
25+
public async prompt(context: T): Promise<void> {
26+
const connectAzureButton = { title: localize('connectAzureTaskScheduler', 'Connect Azure Task Scheduler'), data: ConnectionType.Azure };
27+
const connectEmulatorButton = { title: useEmulator, data: ConnectionType.Emulator };
28+
const connectCustomDTSButton = { title: localize('connectCustomTaskScheduler', 'Manually Set a Connection String'), data: ConnectionType.Custom };
29+
30+
const buttons: MessageItem[] = [];
31+
if (this.connectionTypes.has(ConnectionType.Azure)) {
32+
buttons.push(connectAzureButton);
33+
}
34+
if (this.connectionTypes.has(ConnectionType.Emulator)) {
35+
buttons.push(connectEmulatorButton);
36+
}
37+
if (this.connectionTypes.has(ConnectionType.Custom)) {
38+
buttons.push(connectCustomDTSButton);
39+
}
40+
41+
const message: string = localize('selectDTSConnection', 'Durable Functions needs to be configured to use a Durable Task Scheduler.');
42+
context.dtsConnectionType = (await context.ui.showWarningMessage(message, { modal: true }, ...buttons) as {
43+
title: string;
44+
data: ConnectionType;
45+
}).data;
46+
47+
context.telemetry.properties.dtsConnectionType = context.dtsConnectionType;
48+
}
49+
50+
public shouldPrompt(context: T): boolean {
51+
return !context.dtsConnectionType;
52+
}
53+
54+
public async getSubWizard(context: T): Promise<IWizardOptions<T> | undefined> {
55+
const promptSteps: AzureWizardPromptStep<T | IDTSAzureConnectionWizardContext>[] = [];
56+
const executeSteps: AzureWizardExecuteStep<T | IDTSAzureConnectionWizardContext>[] = [];
57+
58+
switch (context.dtsConnectionType) {
59+
case ConnectionType.Azure:
60+
promptSteps.push(new DurableTaskSchedulerListStep());
61+
executeSteps.push(new VerifyProvidersStep<IDTSAzureConnectionWizardContext>([DurableTaskProvider]));
62+
break;
63+
case ConnectionType.Emulator:
64+
executeSteps.push(new DTSEmulatorStartStep());
65+
break;
66+
case ConnectionType.Custom:
67+
promptSteps.push(
68+
new DTSConnectionCustomPromptStep(),
69+
new DTSHubNameCustomPromptStep(),
70+
);
71+
break;
72+
default:
73+
throw new Error(localize('unexpectedConnectionType', 'Internal error: Unexpected DTS connection type encountered: "{0}".', context.dtsConnectionType));
74+
}
75+
76+
executeSteps.push(
77+
new DTSConnectionSetSettingStep(),
78+
new DTSHubNameSetSettingStep(),
79+
);
80+
81+
return { promptSteps, executeSteps };
82+
}
83+
}

src/commands/appSettings/connectionSettings/durableTaskScheduler/DTSConnectionSetSettingStep.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,23 @@
55

66
import { nonNullProp } from '@microsoft/vscode-azext-utils';
77
import { ConnectionKey } from '../../../../constants';
8+
import { clientIdKey } from '../../../durableTaskScheduler/copySchedulerConnectionString';
89
import { SetConnectionSettingStepBase } from '../SetConnectionSettingStepBase';
9-
import { type IDTSConnectionWizardContext } from './IDTSConnectionWizardContext';
10+
import { type IDTSAzureConnectionWizardContext, type IDTSConnectionWizardContext } from './IDTSConnectionWizardContext';
1011

11-
export class DTSConnectionSetSettingStep<T extends IDTSConnectionWizardContext> extends SetConnectionSettingStepBase<T> {
12+
export class DTSConnectionSetSettingStep<T extends IDTSConnectionWizardContext | IDTSAzureConnectionWizardContext> extends SetConnectionSettingStepBase<T> {
1213
public priority: number = 240;
1314
public debugDeploySetting: ConnectionKey = ConnectionKey.DTS;
1415

1516
public async execute(context: T): Promise<void> {
16-
await this.setConnectionSetting(context, nonNullProp(context, 'newDTSConnection'));
17+
let newDTSConnectionSetting = nonNullProp(context, 'newDTSConnectionSetting');
18+
if ((context as IDTSAzureConnectionWizardContext).managedIdentity) {
19+
newDTSConnectionSetting = newDTSConnectionSetting.replace(clientIdKey, (context as IDTSAzureConnectionWizardContext).managedIdentity?.clientId ?? clientIdKey);
20+
}
21+
await this.setConnectionSetting(context, newDTSConnectionSetting);
1722
}
1823

1924
public shouldExecute(context: T): boolean {
20-
return !!context.newDTSConnection;
25+
return !!context.newDTSConnectionSetting;
2126
}
2227
}

src/commands/appSettings/connectionSettings/durableTaskScheduler/DTSEmulatorStartStep.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ export class DTSEmulatorStartStep<T extends IDTSConnectionWizardContext> extends
3636
void window.showInformationMessage(message);
3737
ext.outputChannel.appendLog(message);
3838

39-
context.newDTSConnection = `Endpoint=${emulator.schedulerEndpoint};Authentication=None`;
40-
context.newDTSHubName = 'default';
39+
context.newDTSConnectionSetting = `Endpoint=${emulator.schedulerEndpoint};Authentication=None`;
40+
context.newDTSHubNameConnectionSetting = 'default';
4141
}
4242

4343
public shouldExecute(context: T): boolean {
44-
return !context.newDTSConnection && context.dtsConnectionType === ConnectionType.Emulator;
44+
return !context.newDTSConnectionSetting && context.dtsConnectionType === ConnectionType.Emulator;
4545
}
4646
}

src/commands/appSettings/connectionSettings/durableTaskScheduler/DTSHubNameCustomPromptStep.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ import { type IDTSConnectionWizardContext } from './IDTSConnectionWizardContext'
1212

1313
export class DTSHubNameCustomPromptStep<T extends IDTSConnectionWizardContext> extends AzureWizardPromptStep<T> {
1414
public async prompt(context: T): Promise<void> {
15-
context.newDTSHubName = (await context.ui.showInputBox({
15+
context.newDTSHubNameConnectionSetting = (await context.ui.showInputBox({
1616
prompt: localize('customDTSConnectionPrompt', 'Provide the custom DTS hub name.'),
1717
value: await getDTSHubName(context, context.projectPath),
1818
validateInput: (value: string) => this.validateInput(value)
1919
})).trim();
2020
}
2121

2222
public shouldPrompt(context: T): boolean {
23-
return !context.newDTSHubName && context.dtsConnectionType === ConnectionType.Custom;
23+
return !context.newDTSHubNameConnectionSetting && context.dtsConnectionType === ConnectionType.Custom;
2424
}
2525

2626
private validateInput(name: string): string | undefined {

0 commit comments

Comments
 (0)