From 1479c2862887f499ac691e2db8cb988a14df2d5a Mon Sep 17 00:00:00 2001 From: Anurag Chauhan <44864882+anuragc617@users.noreply.github.com> Date: Mon, 21 Sep 2020 15:26:51 +0530 Subject: [PATCH 1/3] adding or operator in datasourceId --- .../templateInputHelper/utilities/DataSourceExpression.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts index 96950098..9801292b 100644 --- a/src/configure/templateInputHelper/utilities/DataSourceExpression.ts +++ b/src/configure/templateInputHelper/utilities/DataSourceExpression.ts @@ -90,7 +90,7 @@ export class DataSourceExpression { // If both data sources evaluate to string, then take the first one if (!Array.isArray(result[0]) && !Array.isArray(result[1])) { - return result[0]; + return result[0] || result[1]; } if (Array.isArray(result[0]) && Array.isArray(result[1])) { @@ -169,5 +169,6 @@ export class DataSourceExpression { export enum Operator { UNDEFINED = 0, - INTERSECT = 1 + INTERSECT = 1, + OR = 2 } \ No newline at end of file From c2f0c29b12969aa05c8987b21ffdd2bc01e6839c Mon Sep 17 00:00:00 2001 From: Anurag Chauhan <44864882+anuragc617@users.noreply.github.com> Date: Thu, 24 Sep 2020 23:58:24 +0530 Subject: [PATCH 2/3] changing inputs notification message --- src/configure/resources/messages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/configure/resources/messages.ts b/src/configure/resources/messages.ts index e8b5fa41..0da437b1 100644 --- a/src/configure/resources/messages.ts +++ b/src/configure/resources/messages.ts @@ -97,7 +97,7 @@ export class Messages { public static maxValueMessage = "The value should be less than or equals to %s"; public static valueShouldBeNumber = "The value %s is not numberic"; public static regexPatternNotMatchingMessage = "Value should match the following regex pattern: %s"; - public static fetchingInputMessage = "Fetching inputs for %s"; + public static fetchingInputMessage = "Fetching %s value(s)"; public static GettingNodeVersion = "Getting Node version to install"; public static gettingTemplateFileAsset = "Getting template file asset to commit"; public static gettingWorkflowFile = "Getting workflow file"; From bef47d74bcb0e7a285aea080c88f9dfa8b24035f Mon Sep 17 00:00:00 2001 From: Anurag Chauhan <44864882+anuragc617@users.noreply.github.com> Date: Thu, 8 Oct 2020 12:18:47 +0530 Subject: [PATCH 3/3] caching the datasource request --- src/configure/configure.ts | 6 ++- src/configure/helper/Cache.ts | 42 +++++++++++++++++++ src/configure/helper/ICache.ts | 5 +++ .../utilities/DataSourceUtility.ts | 21 ++++++---- 4 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 src/configure/helper/Cache.ts create mode 100644 src/configure/helper/ICache.ts 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;