Skip to content

Commit dfcb568

Browse files
authored
Refactor getSite to initSite and use a get site to type guard (#4564)
* Refactor getSite to initSite and use a get site to type guard * Make viewProperties get getData to async call site * PR feedback * Minor fixes to state
1 parent 0dc04aa commit dfcb568

33 files changed

+242
-149
lines changed

src/FunctionAppResolver.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import { ResolvedContainerizedFunctionAppResource } from "./tree/containerizedFu
77
import { createResourceGraphClient } from "./utils/azureClients";
88

99
export type FunctionAppModel = {
10-
pricingTier: string,
10+
isFlex: boolean,
1111
id: string,
12+
type: string,
1213
kind: string,
1314
name: string,
1415
resourceGroup: string,
@@ -23,6 +24,7 @@ type FunctionQueryModel = {
2324
},
2425
location: string,
2526
id: string,
27+
type: string,
2628
kind: string,
2729
name: string,
2830
resourceGroup: string
@@ -36,11 +38,12 @@ export class FunctionAppResolver implements AppResourceResolver {
3638
public async resolveResource(subContext: ISubscriptionContext, resource: AppResource): Promise<ResolvedFunctionAppResource | ResolvedContainerizedFunctionAppResource | undefined> {
3739
return await callWithTelemetryAndErrorHandling('resolveResource', async (context: IActionContext) => {
3840
if (this.siteCacheLastUpdated < Date.now() - 1000 * 3) {
41+
// do this before the graph client is created because the async graph client create takes enough time to mess up the following resolves
42+
this.loaded = false;
43+
this.siteCache.clear(); // clear the cache before fetching new data
3944
this.siteCacheLastUpdated = Date.now();
4045
const graphClient = await createResourceGraphClient({ ...context, ...subContext });
4146
async function fetchAllApps(graphClient: ResourceGraphClient, subContext: ISubscriptionContext, resolver: FunctionAppResolver): Promise<void> {
42-
resolver.loaded = false;
43-
resolver.siteCache.clear(); // clear the cache before fetching new data
4447
const query = `resources | where type == 'microsoft.web/sites' and kind contains 'functionapp' and kind !contains 'workflowapp'`;
4548

4649
async function fetchApps(skipToken?: string): Promise<void> {
@@ -55,8 +58,9 @@ export class FunctionAppResolver implements AppResourceResolver {
5558
const record = response.data as Record<string, FunctionQueryModel>;
5659
Object.values(record).forEach(data => {
5760
const dataModel: FunctionAppModel = {
58-
pricingTier: data.properties.sku,
61+
isFlex: data.properties.sku.toLocaleLowerCase() === 'flexconsumption',
5962
id: data.id,
63+
type: data.type,
6064
kind: data.kind,
6165
name: data.name,
6266
resourceGroup: data.resourceGroup,
@@ -86,14 +90,15 @@ export class FunctionAppResolver implements AppResourceResolver {
8690
await this.listFunctionAppsTask;
8791
}
8892

89-
const site = this.siteCache.get(nonNullProp(resource, 'id').toLowerCase());
90-
if (nonNullValueAndProp(site, 'kind') === 'functionapp,linux,container,azurecontainerapps') {
93+
const siteModel = this.siteCache.get(nonNullProp(resource, 'id').toLowerCase());
94+
if (nonNullValueAndProp(siteModel, 'kind') === 'functionapp,linux,container,azurecontainerapps') {
95+
// need the full site to resolve containerized function apps
9196
const client = await createWebSiteClient({ ...context, ...subContext });
92-
const fullSite = await client.webApps.get(nonNullValueAndProp(site, 'resourceGroup'), nonNullValueAndProp(site, 'name'));
97+
const fullSite = await client.webApps.get(nonNullValueAndProp(siteModel, 'resourceGroup'), nonNullValueAndProp(siteModel, 'name'));
9398
return ResolvedContainerizedFunctionAppResource.createResolvedFunctionAppResource(context, subContext, fullSite);
9499
}
95-
if (site) {
96-
return new ResolvedFunctionAppResource(subContext, site);
100+
if (siteModel) {
101+
return new ResolvedFunctionAppResource(subContext, undefined, siteModel);
97102
}
98103

99104
return undefined;

src/commands/browseWebsite.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ export async function browseWebsite(context: IActionContext, node?: SlotTreeItem
1313
if (!node) {
1414
node = await pickAppResource(context);
1515
}
16-
17-
await openUrl(nonNullValueAndProp(await node.getSite(context), 'defaultHostUrl'));
16+
await node.initSite(context);
17+
await openUrl(nonNullValueAndProp(node.site, 'defaultHostUrl'));
1818
}

src/commands/configureDeploymentSource.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ export async function configureDeploymentSource(context: IActionContext, node?:
1313
node = await pickFunctionApp(context);
1414
}
1515

16-
const updatedScmType: string | undefined = await editScmType(context, (await node.getSite(context)), node.subscription);
16+
await node.initSite(context);
17+
const updatedScmType: string | undefined = await editScmType(context, node.site, node.subscription);
1718
if (updatedScmType !== undefined) {
1819
context.telemetry.properties.updatedScmType = updatedScmType;
1920
}

src/commands/createFunctionApp/stacks/getStackPicks.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -369,10 +369,10 @@ export async function getEolWarningMessages(context: ISubscriptionActionContext,
369369

370370
export async function showEolWarningIfNecessary(context: ISubscriptionActionContext, parent: AzExtParentTreeItem, client?: IAppSettingsClient) {
371371
if (isResolvedFunctionApp(parent)) {
372-
const site = await parent.getSite(context);
373-
client = client ?? await site.createClient(context);
372+
await parent.initSite(context);
373+
client = client ?? await parent.site.createClient(context);
374374
const eolWarningMessage = await getEolWarningMessages(context, {
375-
site: site.rawSite,
375+
site: parent.site.rawSite,
376376
isLinux: client.isLinux,
377377
isFlex: parent.isFlex,
378378
client

src/commands/deploy/deploy.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ async function deploy(actionContext: IActionContext, arg1: vscode.Uri | string |
8383
return await getOrCreateFunctionApp(context)
8484
});
8585

86-
const site = await node.resolved.getSite(context);
86+
await node.initSite(context);
87+
const site = node.resolved.site;
8788

8889
if (node.contextValue.includes('container')) {
8990
const learnMoreLink: string = 'https://aka.ms/deployContainerApps'

src/commands/deploy/getWarningsForConnectionSettings.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ export async function getWarningsForConnectionSettings(context: IActionContext,
3232

3333
const localConnectionSettings = await getConnectionSettings(localSettings.Values ?? {});
3434
const remoteConnectionSettings = await getConnectionSettings(options.appSettings?.properties ?? {});
35-
const site = await options.node.getSite(context);
35+
await options.node.initSite(context);
3636

3737
if (localConnectionSettings.some(setting => setting.type === 'ManagedIdentity')) {
38-
if (!site.rawSite.identity ||
39-
site.rawSite.identity.type === 'None') {
38+
if (!options.node.site.rawSite.identity ||
39+
options.node.site.rawSite.identity.type === 'None') {
4040
// if they have nothing in remote, warn them to connect a managed identity
4141
return localize('configureManagedIdentityWarning',
4242
'Your app is not connected to a managed identity. To ensure access, please configure a managed identity. Without it, your application may encounter authorization issues.');

src/commands/deploy/notifyDeployComplete.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ import { startStreamingLogs } from '../logstream/startStreamingLogs';
1717
import { hasRemoteEventGridBlobTrigger, promptForEventGrid } from './promptForEventGrid';
1818

1919
export async function notifyDeployComplete(context: IActionContext, node: SlotTreeItem, workspaceFolder: WorkspaceFolder, isFlexConsumption?: boolean): Promise<void> {
20-
const deployComplete: string = localize('deployComplete', 'Deployment to "{0}" completed.', (await node.getSite(context)).fullName);
20+
await node.initSite(context);
21+
const deployComplete: string = localize('deployComplete', 'Deployment to "{0}" completed.', node.site.fullName);
2122
const viewOutput: MessageItem = { title: localize('viewOutput', 'View output') };
2223
const streamLogs: MessageItem = { title: localize('streamLogs', 'Stream logs') };
2324
const uploadSettings: MessageItem = { title: localize('uploadAppSettings', 'Upload settings') };
@@ -37,6 +38,7 @@ export async function notifyDeployComplete(context: IActionContext, node: SlotTr
3738
postDeployContext.telemetry.properties.dialogResult = result && result.title;
3839
postDeployContext.valuesToMask.push(...context.valuesToMask);
3940
context.telemetry.eventVersion = 2;
41+
await node.initSite(context);
4042

4143
if (result === viewOutput) {
4244
ext.outputChannel.show();
@@ -45,7 +47,7 @@ export async function notifyDeployComplete(context: IActionContext, node: SlotTr
4547
} else if (result === uploadSettings) {
4648
const subContext = {
4749
...postDeployContext,
48-
...(await node.getSite(context)).subscription
50+
...node.site.subscription
4951
}
5052
await uploadAppSettings(subContext, node.appSettingsTreeItem, undefined, workspaceFolder);
5153
}
@@ -60,7 +62,7 @@ export async function notifyDeployComplete(context: IActionContext, node: SlotTr
6062
const message: string = currentAttempt === 1 ?
6163
localize('queryingTriggers', 'Querying triggers...') :
6264
localize('queryingTriggersAttempt', 'Querying triggers (Attempt {0}/{1})...', currentAttempt, retries + 1);
63-
ext.outputChannel.appendLog(message, { resourceName: (await node.getSite(context)).fullName });
65+
ext.outputChannel.appendLog(message, { resourceName: node.site.fullName });
6466
await listHttpTriggerUrls(context, node);
6567
},
6668
{ retries, minTimeout: 2 * 1000 }
@@ -77,8 +79,8 @@ async function listHttpTriggerUrls(context: IActionContext, node: SlotTreeItem):
7779
const children: AzExtTreeItem[] = await node.getCachedChildren(context);
7880
const functionsNode: RemoteFunctionsTreeItem = <RemoteFunctionsTreeItem>children.find(n => n instanceof RemoteFunctionsTreeItem);
7981
await node.treeDataProvider.refresh(context, functionsNode);
80-
81-
const logOptions: {} = { resourceName: (await node.getSite(context)).fullName };
82+
await node.initSite(context);
83+
const logOptions: {} = { resourceName: node.site.fullName };
8284
let hasHttpTriggers: boolean = false;
8385
const functions: AzExtTreeItem[] = await functionsNode.getCachedChildren(context);
8486
const anonFunctions: RemoteFunctionTreeItem[] = <RemoteFunctionTreeItem[]>functions.filter(f => f instanceof RemoteFunctionTreeItem && f.isHttpTrigger && f.isAnonymous);

src/commands/deploy/promptForEventGrid.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import { getWorkspaceSetting, updateWorkspaceSetting } from "../../vsCodeConfig/
1414

1515
export async function hasRemoteEventGridBlobTrigger(context: IActionContext, node: SlotTreeItem): Promise<boolean> {
1616
const retries = 3;
17-
const client = await (await node.getSite(context)).createClient(context);
17+
await node.initSite(context);
18+
const client = await node.site.createClient(context);
1819

1920
const funcs = await retry<FunctionEnvelope[]>(
2021
async () => {

src/commands/deploy/verifyAppSettings.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,20 @@ export async function verifyAppSettings(options: {
3434
}): Promise<void> {
3535

3636
const { context, node, projectPath, version, language, bools, durableStorageType } = options;
37-
const client = await (await node.getSite(context)).createClient(context);
37+
await node.initSite(context);
38+
const client = await node.site.createClient(context);
3839
const appSettings: StringDictionary = options.appSettings;
3940
if (appSettings.properties) {
4041
const remoteRuntime: string | undefined = appSettings.properties[workerRuntimeKey];
41-
await verifyVersionAndLanguage(context, projectPath, (await node.getSite(context)).fullName, version, language, appSettings.properties);
42+
await verifyVersionAndLanguage(context, projectPath, node.site.fullName, version, language, appSettings.properties);
4243

4344
// update the settings if the remote runtime was changed
4445
let updateAppSettings: boolean = appSettings.properties[workerRuntimeKey] !== remoteRuntime;
45-
if ((await node.getSite(context)).isLinux) {
46+
if (node.site.isLinux) {
4647
const remoteBuildSettingsChanged = verifyLinuxRemoteBuildSettings(context, appSettings.properties, bools);
4748
updateAppSettings ||= remoteBuildSettingsChanged;
4849
} else {
49-
updateAppSettings ||= verifyRunFromPackage(context, (await node.getSite(context)), appSettings.properties);
50+
updateAppSettings ||= verifyRunFromPackage(context, node.site, appSettings.properties);
5051
}
5152

5253
const updatedRemoteConnection: boolean = await verifyAndUpdateAppConnectionStrings(context, durableStorageType, appSettings.properties);

src/commands/executeFunction/executeFunction.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,11 @@ export async function executeFunctionWithInput(context: IActionContext, function
9999
const headers = createHttpHeaders({
100100
'Content-Type': 'application/json',
101101
});
102-
103-
const client: SiteClient | undefined = node instanceof RemoteFunctionTreeItem ?
104-
await (await node.parent.parent.getSite(context)).createClient(context) :
105-
undefined;
102+
let client: SiteClient | undefined;
103+
if (node instanceof RemoteFunctionTreeItem) {
104+
await node.parent.parent.initSite(context);
105+
client = await node.parent.parent.site.createClient(context);
106+
}
106107

107108
if (client) {
108109
headers.set('x-functions-key', (await client.listHostKeys()).masterKey ?? '');

0 commit comments

Comments
 (0)