Skip to content

Add DTS deploy activity log integration #4574

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: mwf/deploy-dts
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1484,7 +1484,7 @@
"@microsoft/vscode-azext-azureappservice": "^3.6.3",
"@microsoft/vscode-azext-azureappsettings": "^0.2.8",
"@microsoft/vscode-azext-azureutils": "^3.4.0",
"@microsoft/vscode-azext-utils": "^3.1.1",
"@microsoft/vscode-azext-utils": "^3.2.0",
"@microsoft/vscode-azureresources-api": "^2.0.4",
"@microsoft/vscode-container-client": "^0.1.2",
"cross-fetch": "^4.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,65 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { nonNullProp } from '@microsoft/vscode-azext-utils';
import { ActivityChildItem, ActivityChildType, activityFailContext, activityFailIcon, activityProgressContext, activityProgressIcon, activitySuccessContext, activitySuccessIcon, createContextValue, nonNullProp, type ExecuteActivityOutput } from '@microsoft/vscode-azext-utils';
import { ConnectionKey } from '../../../../constants';
import { localize } from '../../../../localize';
import { SetConnectionSettingStepBase } from '../SetConnectionSettingStepBase';
import { type IDTSAzureConnectionWizardContext, type IDTSConnectionWizardContext } from './IDTSConnectionWizardContext';

export class DTSConnectionSetSettingStep<T extends IDTSConnectionWizardContext> extends SetConnectionSettingStepBase<T> {
public priority: number = 240;
public stepName: string = 'dtsConnectionSetSettingStep';
public debugDeploySetting: ConnectionKey = ConnectionKey.DTS;

public async execute(context: T): Promise<void> {
let newDTSConnectionSetting = nonNullProp(context, 'newDTSConnectionSetting');
if ((context as unknown as IDTSAzureConnectionWizardContext).managedIdentity) {
newDTSConnectionSetting = newDTSConnectionSetting.replace('<ClientID>', (context as unknown as IDTSAzureConnectionWizardContext).managedIdentity?.clientId ?? '');
}

await this.setConnectionSetting(context, newDTSConnectionSetting);
context.newDTSConnectionSetting = newDTSConnectionSetting;

context.valuesToMask.push(context.newDTSConnectionSetting);
}

public shouldExecute(context: T): boolean {
return !!context.newDTSConnectionSetting;
}

public createSuccessOutput(context: T): ExecuteActivityOutput {
return {
item: new ActivityChildItem({
label: localize('prepareDTSConnectionProgressLabel', 'Prepare DTS connection: "{0}"', 'Endpoint=...'),
contextValue: createContextValue([`${this.stepName}Item`, activitySuccessContext]),
activityType: ActivityChildType.Success,
iconPath: activitySuccessIcon,
}),
message: localize('prepareDTSConnectionSuccess', 'Successfully prepared DTS connection: "{0}".', context.newDTSConnectionSetting),
};
}

public createProgressOutput(): ExecuteActivityOutput {
return {
item: new ActivityChildItem({
label: localize('prepareDTSConnectionProgressLabel', 'Prepare DTS connection: "{0}"', 'Endpoint=...'),
contextValue: createContextValue([`${this.stepName}Item`, activityProgressContext]),
activityType: ActivityChildType.Progress,
iconPath: activityProgressIcon,
}),
};
}

public createFailOutput(context: T): ExecuteActivityOutput {
return {
item: new ActivityChildItem({
label: localize('prepareDTSConnectionProgressLabel', 'Prepare DTS connection: "{0}"', 'Endpoint=...'),
contextValue: createContextValue([`${this.stepName}Item`, activityFailContext]),
activityType: ActivityChildType.Fail,
iconPath: activityFailIcon,
}),
message: localize('prepareDTSConnectionFail', 'Failed to prepare DTS connection: "{0}".', context.newDTSConnectionSetting),
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { nonNullProp } from '@microsoft/vscode-azext-utils';
import { ActivityChildItem, ActivityChildType, activityFailIcon, activityProgressContext, activityProgressIcon, activitySuccessContext, activitySuccessIcon, createContextValue, nonNullProp, type ExecuteActivityOutput } from '@microsoft/vscode-azext-utils';
import { ConnectionKey } from '../../../../constants';
import { localize } from '../../../../localize';
import { SetConnectionSettingStepBase } from '../SetConnectionSettingStepBase';
import { type IDTSConnectionWizardContext } from './IDTSConnectionWizardContext';

export class DTSHubNameSetSettingStep<T extends IDTSConnectionWizardContext> extends SetConnectionSettingStepBase<T> {
public priority: number = 241;
public stepName: string = 'dtsHubNameSetSettingStep';
public debugDeploySetting: ConnectionKey = ConnectionKey.DTSHub;

public async execute(context: T): Promise<void> {
Expand All @@ -19,4 +21,39 @@ export class DTSHubNameSetSettingStep<T extends IDTSConnectionWizardContext> ext
public shouldExecute(context: T): boolean {
return !!context.newDTSHubNameConnectionSetting;
}

public createSuccessOutput(context: T): ExecuteActivityOutput {
return {
item: new ActivityChildItem({
label: localize('prepareDTSHubNameLabel', 'Prepare DTS hub connection: "{0}"', context.newDTSHubNameConnectionSetting),
contextValue: createContextValue([`${this.stepName}Item`, activitySuccessContext]),
activityType: ActivityChildType.Success,
iconPath: activitySuccessIcon,
}),
message: localize('prepareDTSHubNameSuccess', 'Successfully prepared DTS hub connection: "{0}".', context.newDTSConnectionSetting),
};
}

public createProgressOutput(): ExecuteActivityOutput {
return {
item: new ActivityChildItem({
label: localize('prepareDTSHubNameProgressLabel', 'Prepare DTS hub connection: "..."'),
contextValue: createContextValue([`${this.stepName}Item`, activityProgressContext]),
activityType: ActivityChildType.Progress,
iconPath: activityProgressIcon,
}),
};
}

public createFailOutput(context: T): ExecuteActivityOutput {
return {
item: new ActivityChildItem({
label: localize('prepareDTSHubNameLabel', 'Prepare DTS hub connection: "{0}"', context.newDTSHubNameConnectionSetting),
contextValue: createContextValue([`${this.stepName}Item`, activitySuccessContext]),
activityType: ActivityChildType.Fail,
iconPath: activityFailIcon,
}),
message: localize('prepareDTSHubNameFail', 'Failed to prepare DTS hub connection: "{0}".', context.newDTSConnectionSetting),
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { type IActionContext } from "@microsoft/vscode-azext-utils";
import { type ExecuteActivityContext, type IActionContext } from "@microsoft/vscode-azext-utils";
import { type AzureSubscription } from "@microsoft/vscode-azureresources-api";
import { type ConnectionType } from "../../../../constants";
import { type DurableTaskHubResource, type DurableTaskSchedulerResource } from "../../../../tree/durableTaskScheduler/DurableTaskSchedulerClient";
Expand All @@ -20,7 +20,7 @@ export interface IDTSConnectionWizardContext extends IActionContext, ISetConnect
newDTSHubNameConnectionSetting?: string;
}

export interface IDTSAzureConnectionWizardContext extends IFunctionAppUserAssignedIdentitiesContext, IDTSConnectionWizardContext {
export interface IDTSAzureConnectionWizardContext extends IFunctionAppUserAssignedIdentitiesContext, IDTSConnectionWizardContext, Partial<ExecuteActivityContext> {
subscription?: AzureSubscription;

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { ActivityChildItem, ActivityChildType, activityInfoContext, activityInfoIcon, AzureWizardPromptStep, createContextValue, prependOrInsertAfterLastInfoChild, type ActivityInfoChild } from "@microsoft/vscode-azext-utils";
import { ext } from "../../../../../extensionVariables";
import { localize } from "../../../../../localize";
import { type IDTSAzureConnectionWizardContext } from "../IDTSConnectionWizardContext";

const startingResourcesContext: string = 'startingResourcesLogStepItem';

export class DTSStartingResourcesLogStep<T extends IDTSAzureConnectionWizardContext> extends AzureWizardPromptStep<T> {
public hideStepCount: boolean = true;
protected hasLogged: boolean = false;

public async configureBeforePrompt(context: T): Promise<void> {
if (this.hasLogged) {
return;
}

if (context.resourceGroup) {
prependOrInsertAfterLastInfoChild(context,
new ActivityChildItem({
contextValue: createContextValue([startingResourcesContext, activityInfoContext]),
label: localize('useResourceGroup', 'Use resource group "{0}"', context.resourceGroup.name),
activityType: ActivityChildType.Info,
iconPath: activityInfoIcon
}) as ActivityInfoChild
);
ext.outputChannel.appendLog(localize('usingResourceGroup', 'Using resource group "{0}".', context.resourceGroup.name));
}

if (context.site) {
prependOrInsertAfterLastInfoChild(context,
new ActivityChildItem({
label: localize('useFunctionApp', 'Use function app "{0}"', context.site.fullName),
contextValue: createContextValue([startingResourcesContext, activityInfoContext]),
activityType: ActivityChildType.Info,
iconPath: activityInfoIcon,
}) as ActivityInfoChild,
);
ext.outputChannel.appendLog(localize('usingFunctionApp', 'Using function app "{0}".', context.site.fullName));
}

if (context.dts) {
prependOrInsertAfterLastInfoChild(context,
new ActivityChildItem({
label: localize('useDTS', 'Use durable task scheduler "{0}"', context.dts.name),
contextValue: createContextValue([startingResourcesContext, activityInfoContext]),
activityType: ActivityChildType.Info,
iconPath: activityInfoIcon
}) as ActivityInfoChild,
);
ext.outputChannel.appendLog(localize('usingDTS', 'Using durable task scheduler "{0}".', context.dts.name));
}

if (context.dtsHub) {
prependOrInsertAfterLastInfoChild(context,
new ActivityChildItem({
label: localize('useDTSHub', 'Use durable task hub "{0}"', context.dtsHub.name),
contextValue: createContextValue([startingResourcesContext, activityInfoContext]),
activityType: ActivityChildType.Info,
iconPath: activityInfoIcon,
}) as ActivityInfoChild,
);
ext.outputChannel.appendLog(localize('usingDTSHub', 'Using durable task hub "{0}".', context.dtsHub.name));
}

ext.outputChannel.appendLog(localize('prioritizingSiteLocation', 'Prioritizing site location: "{0}".', context.site?.location));
this.hasLogged = true;
}

public async prompt(): Promise<void> {
// Don't prompt, just use to log starting resources
}

public shouldPrompt(): boolean {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,31 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { AzureWizardExecuteStep, nonNullProp, nonNullValueAndProp } from "@microsoft/vscode-azext-utils";
import { AzureWizardExecuteStepWithActivityOutput, nonNullProp, nonNullValueAndProp } from "@microsoft/vscode-azext-utils";
import { type Progress } from "vscode";
import { localize } from "../../../../../localize";
import { HttpDurableTaskSchedulerClient, type DurableTaskSchedulerClient } from "../../../../../tree/durableTaskScheduler/DurableTaskSchedulerClient";
import { type IDTSAzureConnectionWizardContext } from "../IDTSConnectionWizardContext";

export class DurableTaskHubCreateStep<T extends IDTSAzureConnectionWizardContext> extends AzureWizardExecuteStep<T> {
priority: number = 160;
private readonly schedulerClient: DurableTaskSchedulerClient;
export class DurableTaskHubCreateStep<T extends IDTSAzureConnectionWizardContext> extends AzureWizardExecuteStepWithActivityOutput<T> {
public priority: number = 160;
public stepName: string = 'durableTaskHubCreateStep';

protected getOutputLogSuccess = (context: T) => localize('createTaskHubSuccess', 'Created durable task hub "{0}"', context.dtsHub?.name);
protected getOutputLogFail = (context: T) => localize('createTaskHubFail', 'Failed to create durable task hub "{0}"', context.newDTSHubName);
protected getTreeItemLabel = (context: T) => localize('createTaskHubLabel', 'Create durable task hub "{0}"', context.newDTSHubName);

private readonly _schedulerClient: DurableTaskSchedulerClient;

constructor(schedulerClient?: DurableTaskSchedulerClient) {
super();
this.schedulerClient = schedulerClient ?? new HttpDurableTaskSchedulerClient();
this._schedulerClient = schedulerClient ?? new HttpDurableTaskSchedulerClient();
}

public async execute(context: T, progress: Progress<{ message?: string; increment?: number; }>): Promise<void> {
progress.report({ message: localize('createTaskHub', 'Creating durable task hub...') });

context.dtsHub = await this.schedulerClient.createTaskHub(
context.dtsHub = await this._schedulerClient.createTaskHub(
nonNullProp(context, 'subscription'),
nonNullValueAndProp(context.resourceGroup, 'name'),
nonNullValueAndProp(context.dts, 'name'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,33 @@
*--------------------------------------------------------------------------------------------*/

import { LocationListStep } from "@microsoft/vscode-azext-azureutils";
import { AzureWizardExecuteStep, nonNullProp, nonNullValueAndProp } from "@microsoft/vscode-azext-utils";
import { ActivityChildItem, ActivityChildType, activityProgressContext, activityProgressIcon, AzureWizardExecuteStepWithActivityOutput, createContextValue, nonNullProp, nonNullValueAndProp, type ExecuteActivityOutput } from "@microsoft/vscode-azext-utils";
import { type Progress } from "vscode";
import { localize } from "../../../../../localize";
import { HttpDurableTaskSchedulerClient, type DurableTaskSchedulerClient } from "../../../../../tree/durableTaskScheduler/DurableTaskSchedulerClient";
import { withCancellation } from "../../../../../utils/cancellation";
import { getSchedulerConnectionString, SchedulerAuthenticationType } from "../../../../durableTaskScheduler/copySchedulerConnectionString";
import { type IDTSAzureConnectionWizardContext } from "../IDTSConnectionWizardContext";

export class DurableTaskSchedulerCreateStep<T extends IDTSAzureConnectionWizardContext> extends AzureWizardExecuteStep<T> {
priority: number = 150;
private readonly schedulerClient: DurableTaskSchedulerClient;
export class DurableTaskSchedulerCreateStep<T extends IDTSAzureConnectionWizardContext> extends AzureWizardExecuteStepWithActivityOutput<T> {
public priority: number = 150;
public stepName: string = 'durableTaskSchedulerCreateStep';

protected getOutputLogSuccess = (context: T) => localize('createTaskSchedulerSuccess', 'Created durable task scheduler "{0}"', context.dts?.name);
protected getOutputLogFail = (context: T) => localize('createTaskSchedulerFail', 'Failed to create durable task scheduler "{0}"', context.newDTSName);
protected getTreeItemLabel = (context: T) => localize('createTaskSchedulerLabel', 'Create durable task scheduler "{0}"', context.newDTSName);

private readonly _schedulerClient: DurableTaskSchedulerClient;

public constructor(schedulerClient?: DurableTaskSchedulerClient) {
super();
this.schedulerClient = schedulerClient ?? new HttpDurableTaskSchedulerClient();
this._schedulerClient = schedulerClient ?? new HttpDurableTaskSchedulerClient();
}

public async execute(context: T, progress: Progress<{ message?: string; increment?: number; }>): Promise<void> {
progress.report({ message: localize('createTaskScheduler', 'Creating durable task scheduler...') });

const response = (await this.schedulerClient.createScheduler(
const response = (await this._schedulerClient.createScheduler(
nonNullProp(context, 'subscription'),
nonNullValueAndProp(context.resourceGroup, 'name'),
(await LocationListStep.getLocation(context)).name,
Expand All @@ -44,4 +50,16 @@ export class DurableTaskSchedulerCreateStep<T extends IDTSAzureConnectionWizardC
public shouldExecute(context: T): boolean {
return !context.dts;
}

public createProgressOutput(context: T): ExecuteActivityOutput {
return {
item: new ActivityChildItem({
label: this.getTreeItemLabel(context),
description: localize('dtsCreateWarning', 'This could take a while...'),
contextValue: createContextValue([`${this.stepName}Item`, activityProgressContext]),
activityType: ActivityChildType.Progress,
iconPath: activityProgressIcon,
}),
};
}
}
Loading