diff --git a/src/configure/configure.ts b/src/configure/configure.ts index fcd6e271..8a0996c6 100644 --- a/src/configure/configure.ts +++ b/src/configure/configure.ts @@ -13,6 +13,7 @@ import { RemoteGitHubWorkflowConfigurer } from './configurers/remoteGitHubWorkfl import { ResourceSelectorFactory } from './configurers/ResourceSelectorFactory'; import { AssetHandler } from './helper/AssetHandler'; import { getAzureSession, getSubscriptionSession } from './helper/azureSessionHelper'; +import { Cache } from './helper/Cache'; import { ControlProvider } from './helper/controlProvider'; import { AzureDevOpsHelper } from './helper/devOps/azureDevOpsHelper'; import { GitHubProvider } from './helper/gitHubHelper'; @@ -96,6 +97,7 @@ class Orchestrator { private pipelineType: PipelineType; public constructor() { + Cache.getCache().clearCache(); this.inputs = new WizardInputs(); this.controlProvider = new ControlProvider(); UniqueResourceNameSuffix = uuid().substr(0, 5); @@ -123,6 +125,7 @@ class Orchestrator { telemetryHelper.setTelemetry(TelemetryKeys.resourceType, this.inputs.targetResource.resource.type); if (targetType === TargetResourceType.WebApp) { this.context['resourceId'] = this.inputs.targetResource.resource.id; + Cache.getCache().put(this.inputs.targetResource.resource.id, this.inputs.targetResource.resource); telemetryHelper.setTelemetry(TelemetryKeys.resourceKind, this.inputs.targetResource.resource.kind); telemetryHelper.setTelemetry(TelemetryKeys.resourceIdHash, Utilities.createSha256Hash(this.inputs.targetResource.resource.id)); } @@ -277,10 +280,11 @@ class Orchestrator { if (!!node) { if (await this.extractAzureResourceFromNode(node)) { this.context['isResourceAlreadySelected'] = true; + Cache.getCache().put(this.inputs.targetResource.resource.id, this.inputs.targetResource.resource); this.context['resourceId'] = this.inputs.targetResource.resource.id; } else { if (node.fsPath) { - //right click on a folder + // right click on a folder this.workspacePath = node.fsPath; telemetryHelper.setTelemetry(TelemetryKeys.SourceRepoLocation, SourceOptions.CurrentWorkspace); } diff --git a/src/configure/helper/Cache.ts b/src/configure/helper/Cache.ts new file mode 100644 index 00000000..3ddcdd8c --- /dev/null +++ b/src/configure/helper/Cache.ts @@ -0,0 +1,42 @@ +import { ICache } from "./ICache"; + +export class Cache implements ICache { + public static getCache(): ICache { + if (!this.cache) { + this.cache = new Cache(); + } + return this.cache; + } + + private static cache: Cache; + private store: Map; + + constructor() { + this.store = new Map(); + } + + public getValue(key: string): any { + key = this.sanitizeKey(key); + if (this.store.has(key)) { + return this.store.get(key); + } + return null; + } + + public clearCache() { + this.store = new Map(); + } + + public put(key: string, value: any): void { + key = this.sanitizeKey(key); + this.store.set(key, value); + } + + private sanitizeKey(key: string): string { + const apiVersionIndex = key.indexOf('?api-version='); + if (apiVersionIndex >= 0 && !(key.indexOf('&') > apiVersionIndex)) { + key = key.substring(0, key.indexOf('?api-version=')); + } + return key; + } +} diff --git a/src/configure/helper/ICache.ts b/src/configure/helper/ICache.ts new file mode 100644 index 00000000..a0d650ed --- /dev/null +++ b/src/configure/helper/ICache.ts @@ -0,0 +1,5 @@ +export interface ICache { + getValue(key: string): any; + put(key: string, value: any): void; + clearCache(): void; +} diff --git a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts index efaeea2f..54bf79a3 100644 --- a/src/configure/templateInputHelper/utilities/DataSourceUtility.ts +++ b/src/configure/templateInputHelper/utilities/DataSourceUtility.ts @@ -1,6 +1,7 @@ import { JSONPath } from 'jsonpath-plus'; import { isNullOrUndefined } from 'util'; import { ArmRestClient } from "../../clients/azure/armRestClient"; +import { Cache } from '../../helper/Cache'; import { MustacheHelper } from "../../helper/mustacheHelper"; import { DataSource } from "../../model/Contracts"; import { AzureSession, QuickPickItemWithData, StringMap } from "../../model/models"; @@ -38,17 +39,23 @@ export class DataSourceUtility { var view = { inputs: inputs }; var armUri = MustacheHelper.render(dataSource.endpointUrlStem, view); var httpMethod = dataSource.httpMethod || "GET"; - var requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; - let amrClient = new ArmRestClient(azureSession); - return amrClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)) - .then((response: any) => { - return this.evaluateDataSourceResponse(dataSource, response, view); - }); + const requestBody = !!dataSource.requestBody ? MustacheHelper.render(dataSource.requestBody, view) : null; + const armClient = new ArmRestClient(azureSession); + let result: any; + if (httpMethod == "GET" && Cache.getCache().getValue(armUri)) { + result = Cache.getCache().getValue(armUri); + } else { + result = await armClient.fetchArmData(armUri, httpMethod, JSON.parse(requestBody)); + if (httpMethod == "GET") { + Cache.getCache().put(armUri, result); + } + } + return this.evaluateDataSourceResponse(dataSource, result, view); } private static evaluateDataSourceResponse(dataSource: DataSource, response: any, view: { inputs: StringMap }): any { if (!!dataSource.resultSelector) { - var resultSelector = MustacheHelper.render(dataSource.resultSelector, view); + const resultSelector = MustacheHelper.render(dataSource.resultSelector, view); response = JSONPath({ json: response, path: resultSelector, wrap: false, flatten: true }); if (response === "" || response === isNullOrUndefined) { return null;