From 450296e7f275e9cec3af2c76a50af201b1929dd6 Mon Sep 17 00:00:00 2001 From: Denis Davidyuk Date: Sun, 31 Mar 2024 00:08:54 +1000 Subject: [PATCH] fix(node,middleware,compiler): version check if deployed at path --- src/Middleware.ts | 23 +++++++++++------------ src/Node.ts | 17 ++++++++--------- src/contract/compiler/Http.ts | 23 +++++++++++------------ src/utils/autorest.ts | 28 +++++++++++++++++----------- test/integration/AeSdkMethods.ts | 8 ++++---- 5 files changed, 51 insertions(+), 48 deletions(-) diff --git a/src/Middleware.ts b/src/Middleware.ts index 1e1013de2e..e832adac91 100644 --- a/src/Middleware.ts +++ b/src/Middleware.ts @@ -1,6 +1,6 @@ // eslint-disable-next-line max-classes-per-file import BigNumber from 'bignumber.js'; -import { OperationArguments, OperationSpec } from '@azure/core-client'; +import { OperationArguments, OperationOptions, OperationSpec } from '@azure/core-client'; import { userAgentPolicyName, setClientRequestIdPolicyName } from '@azure/core-rest-pipeline'; import { genRequestQueuesPolicy, genCombineGetRequestsPolicy, genErrorFormatterPolicy, @@ -120,10 +120,20 @@ export default class Middleware retryOverallDelay?: number; } = {}, ) { + let version: string | undefined; + const getVersion = async (opts: OperationOptions): Promise => { + if (version != null) return version; + version = (await this.getStatus(opts)).mdwVersion; + return version; + }; + // eslint-disable-next-line constructor-super super(url, { allowInsecureConnection: true, additionalPolicies: [ + ...ignoreVersion ? [] : [ + genVersionCheckPolicy('middleware', getVersion, '1.47.0', '2.0.0'), + ], genRequestQueuesPolicy(), genCombineGetRequestsPolicy(), genRetryOnFailurePolicy(retryCount, retryOverallDelay), @@ -133,16 +143,5 @@ export default class Middleware }); this.pipeline.removePolicy({ name: userAgentPolicyName }); this.pipeline.removePolicy({ name: setClientRequestIdPolicyName }); - if (!ignoreVersion) { - let version: string | undefined; - const getVersion = async (): Promise => { - if (version != null) return version; - version = (await this.getStatus()).mdwVersion; - return version; - }; - this.pipeline.addPolicy( - genVersionCheckPolicy('middleware', '/mdw/v2/status', getVersion, '1.47.0', '2.0.0'), - ); - } } } diff --git a/src/Node.ts b/src/Node.ts index 13bda9229a..5a4d819bf5 100644 --- a/src/Node.ts +++ b/src/Node.ts @@ -1,6 +1,6 @@ // eslint-disable-next-line max-classes-per-file import BigNumber from 'bignumber.js'; -import { OperationArguments, OperationSpec } from '@azure/core-client'; +import { OperationArguments, OperationOptions, OperationSpec } from '@azure/core-client'; import { userAgentPolicyName, setClientRequestIdPolicyName } from '@azure/core-rest-pipeline'; import { genRequestQueuesPolicy, genCombineGetRequestsPolicy, genErrorFormatterPolicy, @@ -130,10 +130,14 @@ export default class Node extends (NodeTransformed as unknown as NodeTransformed retryOverallDelay?: number; } = {}, ) { + const getVersion = async (opts: OperationOptions): Promise => ( + (await this._getCachedStatus(opts)).nodeVersion + ); // eslint-disable-next-line constructor-super super(url, { allowInsecureConnection: true, additionalPolicies: [ + ...ignoreVersion ? [] : [genVersionCheckPolicy('node', getVersion, '6.2.0', '7.0.0')], genRequestQueuesPolicy(), genCombineGetRequestsPolicy(), genRetryOnFailurePolicy(retryCount, retryOverallDelay), @@ -145,22 +149,17 @@ export default class Node extends (NodeTransformed as unknown as NodeTransformed }); this.pipeline.removePolicy({ name: userAgentPolicyName }); this.pipeline.removePolicy({ name: setClientRequestIdPolicyName }); - if (!ignoreVersion) { - const getVersion = async (): Promise => (await this._getCachedStatus()).nodeVersion; - this.pipeline.addPolicy( - genVersionCheckPolicy('node', '/v3/status', getVersion, '6.2.0', '7.0.0'), - ); - } this.intAsString = true; } #cachedStatusPromise?: ReturnType; - async _getCachedStatus(): ReturnType { + async _getCachedStatus(options?: OperationOptions): ReturnType { if (this.#cachedStatusPromise != null) return this.#cachedStatusPromise; - return this.getStatus(); + return this.getStatus(options); } + // eslint-disable-next-line rulesdir/tsdoc-syntax /** @ts-expect-error use code generation to create node class? */ override async getStatus( ...args: Parameters['getStatus']> diff --git a/src/contract/compiler/Http.ts b/src/contract/compiler/Http.ts index 5282d7d151..72b5c363a7 100644 --- a/src/contract/compiler/Http.ts +++ b/src/contract/compiler/Http.ts @@ -1,6 +1,7 @@ import { RestError, userAgentPolicyName, setClientRequestIdPolicyName, } from '@azure/core-rest-pipeline'; +import { OperationOptions } from '@azure/core-client'; import { Compiler as CompilerApi, ErrorModel, @@ -31,11 +32,20 @@ export default class CompilerHttp extends CompilerBase { * @param options - Options * @param options.ignoreVersion - Don't check compiler version */ - constructor(compilerUrl: string, { ignoreVersion }: { ignoreVersion?: boolean } = {}) { + constructor(compilerUrl: string, { ignoreVersion = false }: { ignoreVersion?: boolean } = {}) { super(); + + let version: string | undefined; + const getVersion = async (opts: OperationOptions): Promise => { + if (version != null) return version; + version = (await this.api.apiVersion(opts)).apiVersion; + return version; + }; + this.api = new CompilerApi(compilerUrl, { allowInsecureConnection: true, additionalPolicies: [ + ...ignoreVersion ? [] : [genVersionCheckPolicy('compiler', getVersion, '7.3.0', '9.0.0')], genErrorFormatterPolicy((body: GeneralCompilerError | CompilerErrorApi[]) => { let message = ''; if ('reason' in body) { @@ -55,17 +65,6 @@ export default class CompilerHttp extends CompilerBase { }); this.api.pipeline.removePolicy({ name: userAgentPolicyName }); this.api.pipeline.removePolicy({ name: setClientRequestIdPolicyName }); - if (ignoreVersion !== true) { - let version: string | undefined; - const getVersion = async (): Promise => { - if (version != null) return version; - version = (await this.api.apiVersion()).apiVersion; - return version; - }; - this.api.pipeline.addPolicy( - genVersionCheckPolicy('compiler', '/api-version', getVersion, '7.3.0', '9.0.0'), - ); - } } async compileBySourceCode( diff --git a/src/utils/autorest.ts b/src/utils/autorest.ts index 32456cabe9..17de2ce7d6 100644 --- a/src/utils/autorest.ts +++ b/src/utils/autorest.ts @@ -1,5 +1,5 @@ -import { RestError, PipelineResponse, PipelinePolicy } from '@azure/core-rest-pipeline'; -import { AdditionalPolicyConfig, FullOperationResponse } from '@azure/core-client'; +import { RestError, PipelineResponse } from '@azure/core-rest-pipeline'; +import { AdditionalPolicyConfig, FullOperationResponse, OperationOptions } from '@azure/core-client'; import { pause } from './other'; import semverSatisfies from './semver-satisfies'; import { UnsupportedVersionError } from './errors'; @@ -94,18 +94,24 @@ export const genErrorFormatterPolicy = ( export const genVersionCheckPolicy = ( name: string, - ignorePath: string, - versionCb: () => Promise, + versionCb: (options: OperationOptions) => Promise, geVersion: string, ltVersion: string, -): PipelinePolicy => ({ - name: 'version-check', - async sendRequest(request, next) { - if (new URL(request.url).pathname === ignorePath) return next(request); - const args = [await versionCb(), geVersion, ltVersion] as const; - if (!semverSatisfies(...args)) throw new UnsupportedVersionError(name, ...args); - return next(request); +): AdditionalPolicyConfig => ({ + policy: { + name: 'version-check', + async sendRequest(request, next) { + if (request.headers.has('__version-check')) { + request.headers.delete('__version-check'); + return next(request); + } + const options = { requestOptions: { customHeaders: { '__version-check': 'true' } } }; + const args = [await versionCb(options), geVersion, ltVersion] as const; + if (!semverSatisfies(...args)) throw new UnsupportedVersionError(name, ...args); + return next(request); + }, }, + position: 'perCall', }); export const genRetryOnFailurePolicy = ( diff --git a/test/integration/AeSdkMethods.ts b/test/integration/AeSdkMethods.ts index 0536e7dd54..2e9218ec9c 100644 --- a/test/integration/AeSdkMethods.ts +++ b/test/integration/AeSdkMethods.ts @@ -62,22 +62,22 @@ describe('AeSdkMethods', () => { { policy: { name: 'logPolicy' }, options: { afterPhase: 'Sign' } }, { policy: { name: 'serializationPolicy' }, options: { phase: 'Serialize' } }, { policy: { name: 'deserializationPolicy' }, options: { phase: 'Deserialize' } }, + { policy: { name: 'version-check' }, options: {} }, { policy: { name: 'request-queues' }, options: {} }, { policy: { name: 'combine-get-requests' }, options: {} }, { policy: { name: 'retry-on-failure' }, options: {} }, { policy: { name: 'error-formatter' }, options: {} }, - { policy: { name: 'version-check' }, options: {} }, ], _orderedPolicies: [ { name: 'serializationPolicy' }, { name: 'proxyPolicy' }, { name: 'decompressResponsePolicy' }, { name: 'formDataPolicy' }, + { name: 'version-check' }, { name: 'request-queues' }, { name: 'combine-get-requests' }, { name: 'retry-on-failure' }, { name: 'error-formatter' }, - { name: 'version-check' }, { name: 'deserializationPolicy' }, { name: 'multipartPolicy' }, { name: 'defaultRetryPolicy' }, @@ -107,16 +107,16 @@ describe('AeSdkMethods', () => { { policy: { name: 'logPolicy' }, options: { afterPhase: 'Sign' } }, { policy: { name: 'serializationPolicy' }, options: { phase: 'Serialize' } }, { policy: { name: 'deserializationPolicy' }, options: { phase: 'Deserialize' } }, - { policy: { name: 'error-formatter' }, options: {} }, { policy: { name: 'version-check' }, options: {} }, + { policy: { name: 'error-formatter' }, options: {} }, ], _orderedPolicies: [ { name: 'serializationPolicy' }, { name: 'proxyPolicy' }, { name: 'decompressResponsePolicy' }, { name: 'formDataPolicy' }, - { name: 'error-formatter' }, { name: 'version-check' }, + { name: 'error-formatter' }, { name: 'deserializationPolicy' }, { name: 'multipartPolicy' }, { name: 'defaultRetryPolicy' },