Add Connection String Execute Step for SQL Bindings (#19293)

* add execute step

* nit comment

* edit param docs

* address comments

* ensure the user has the installs the latest version
This commit is contained in:
Vasu Bhog
2022-05-09 16:06:02 -07:00
committed by GitHub
parent e80b8f92f2
commit 51e5890c83
6 changed files with 243 additions and 21 deletions

View File

@@ -121,7 +121,7 @@ export async function getAzureFunctionsExtensionApi(): Promise<AzureFunctionsExt
return undefined;
}
}
const azureFunctionApi = apiProvider.getApi<AzureFunctionsExtensionApi>('*');
const azureFunctionApi = apiProvider.getApi<AzureFunctionsExtensionApi>('^1.8.0');
if (azureFunctionApi) {
return azureFunctionApi;
} else {

View File

@@ -0,0 +1,41 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { AzureWizardExecuteStep, IActionContext } from '@microsoft/vscode-azext-utils';
import { IConnectionInfo } from 'vscode-mssql';
import * as azureFunctionsUtils from '../common/azureFunctionsUtils';
/**
* This execute step is used to add a connection string to the local.settings.json file when creating a new Azure Functions project
* and is needed due to vscode restarting the extension host after the user chooses to open project in new window or current window
* through the createFunction API call for vscode-azurefunctions
* @param projectFolder The folder containing the Azure Functions project
* @param connectionInfo The connection info to use when creating the connection string
* @param connectionStringSettingName the name of the connection string setting
* @returns AzureWizardExecuteStep to be used in the createFunction API call
*/
export function createAddConnectionStringStep(projectFolder: string, connectionInfo: IConnectionInfo, connectionStringSettingName?: string): AzureWizardExecuteStep<IActionContext> {
return new class AzureWizardExecuteStep {
// priority number is set to be lower than OpenFolderStep in vscode-azurefunctions
// https://github.com/microsoft/vscode-azurefunctions/blob/main/src/commands/createNewProject/OpenFolderStep.ts#L11
public priority: number = 240;
public async execute(): Promise<void> {
let settingsFile = await azureFunctionsUtils.getSettingsFile(projectFolder);
if (!settingsFile) {
return;
}
let connectionString = await azureFunctionsUtils.promptConnectionStringPasswordAndUpdateConnectionString(connectionInfo, settingsFile);
if (!connectionString) {
return;
}
void azureFunctionsUtils.addConnectionStringToConfig(connectionString, projectFolder, connectionStringSettingName);
}
public shouldExecute(): boolean {
return true;
}
};
}

View File

@@ -13,6 +13,7 @@ import * as azureFunctionsContracts from '../contracts/azureFunctions/azureFunct
import { CreateAzureFunctionStep, TelemetryActions, TelemetryReporter, TelemetryViews, ExitReason } from '../common/telemetry';
import { AddSqlBindingParams, BindingType, GetAzureFunctionsParams, GetAzureFunctionsResult, ResultStatus } from 'sql-bindings';
import { IConnectionInfo, ITreeNodeInfo } from 'vscode-mssql';
import { createAddConnectionStringStep } from '../createNewProject/addConnectionStringStep';
export const hostFileName: string = 'host.json';
@@ -223,6 +224,8 @@ export async function createAzureFunction(node?: ITreeNodeInfo): Promise<void> {
.withAdditionalProperties(propertyBag)
.withConnectionInfo(connectionInfo).send();
}
// addtional execution step that will be used by vscode-azurefunctions to execute only when creating a new azure function project
let connectionStringExecuteStep = createAddConnectionStringStep(projectFolder, connectionInfo, connectionStringSettingName);
// create C# Azure Function with SQL Binding
telemetryStep = 'createFunctionAPI';
@@ -238,7 +241,8 @@ export async function createAzureFunction(node?: ITreeNodeInfo): Promise<void> {
...(selectedBindingType === BindingType.output && { table: objectName })
},
folderPath: projectFolder,
suppressCreateProjectPrompt: true
suppressCreateProjectPrompt: true,
...(isCreateNewProject && { executeStep: connectionStringExecuteStep })
});
TelemetryReporter.createActionEvent(TelemetryViews.CreateAzureFunctionWithSqlBinding, telemetryStep)
.withAdditionalProperties(propertyBag)
@@ -246,22 +250,9 @@ export async function createAzureFunction(node?: ITreeNodeInfo): Promise<void> {
// check for the new function file to be created and dispose of the file system watcher
const timeoutForFunctionFile = utils.timeoutPromise(constants.timeoutAzureFunctionFileError);
let functionFilePath = await Promise.race([newFunctionFileObject.filePromise, timeoutForFunctionFile]);
// prompt user for include password for connection string
if (isCreateNewProject && functionFilePath) {
telemetryStep = CreateAzureFunctionStep.promptForIncludePassword;
let settingsFile = await azureFunctionsUtils.getSettingsFile(projectFolder);
if (!settingsFile) {
return;
}
let connectionString = await azureFunctionsUtils.promptConnectionStringPasswordAndUpdateConnectionString(connectionInfo, settingsFile);
if (!connectionString) {
return;
}
void azureFunctionsUtils.addConnectionStringToConfig(connectionString, projectFolder, connectionStringSettingName);
}
await Promise.race([newFunctionFileObject.filePromise, timeoutForFunctionFile]);
telemetryStep = 'finishCreateFunction';
propertyBag.telemetryStep = telemetryStep;
exitReason = ExitReason.finishCreate;
TelemetryReporter.createActionEvent(TelemetryViews.CreateAzureFunctionWithSqlBinding, TelemetryActions.finishCreateAzureFunctionWithSqlBinding)