@typespec/ts-http-runtime 1.0.0-alpha.20231023.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +159 -0
- package/dist/index.js +3509 -0
- package/dist/index.js.map +1 -0
- package/dist-esm/src/abort-controller/AbortError.js +27 -0
- package/dist-esm/src/abort-controller/AbortError.js.map +1 -0
- package/dist-esm/src/abort-controller/AbortSignalLike.js +4 -0
- package/dist-esm/src/abort-controller/AbortSignalLike.js.map +1 -0
- package/dist-esm/src/accessTokenCache.js +32 -0
- package/dist-esm/src/accessTokenCache.js.map +1 -0
- package/dist-esm/src/auth/keyCredential.js +4 -0
- package/dist-esm/src/auth/keyCredential.js.map +1 -0
- package/dist-esm/src/auth/tokenCredential.js +19 -0
- package/dist-esm/src/auth/tokenCredential.js.map +1 -0
- package/dist-esm/src/client/apiVersionPolicy.js +23 -0
- package/dist-esm/src/client/apiVersionPolicy.js.map +1 -0
- package/dist-esm/src/client/clientHelpers.js +52 -0
- package/dist-esm/src/client/clientHelpers.js.map +1 -0
- package/dist-esm/src/client/common.js +4 -0
- package/dist-esm/src/client/common.js.map +1 -0
- package/dist-esm/src/client/getClient.js +86 -0
- package/dist-esm/src/client/getClient.js.map +1 -0
- package/dist-esm/src/client/helpers/getBinaryBody.js +13 -0
- package/dist-esm/src/client/helpers/getBinaryBody.js.map +1 -0
- package/dist-esm/src/client/helpers/isReadableStream.browser.js +12 -0
- package/dist-esm/src/client/helpers/isReadableStream.browser.js.map +1 -0
- package/dist-esm/src/client/helpers/isReadableStream.js +10 -0
- package/dist-esm/src/client/helpers/isReadableStream.js.map +1 -0
- package/dist-esm/src/client/keyCredentialAuthenticationPolicy.js +16 -0
- package/dist-esm/src/client/keyCredentialAuthenticationPolicy.js.map +1 -0
- package/dist-esm/src/client/operationOptionHelpers.js +22 -0
- package/dist-esm/src/client/operationOptionHelpers.js.map +1 -0
- package/dist-esm/src/client/restError.js +27 -0
- package/dist-esm/src/client/restError.js.map +1 -0
- package/dist-esm/src/client/sendRequest.js +195 -0
- package/dist-esm/src/client/sendRequest.js.map +1 -0
- package/dist-esm/src/client/urlHelpers.js +100 -0
- package/dist-esm/src/client/urlHelpers.js.map +1 -0
- package/dist-esm/src/constants.js +5 -0
- package/dist-esm/src/constants.js.map +1 -0
- package/dist-esm/src/createPipelineFromOptions.js +39 -0
- package/dist-esm/src/createPipelineFromOptions.js.map +1 -0
- package/dist-esm/src/defaultHttpClient.browser.js +10 -0
- package/dist-esm/src/defaultHttpClient.browser.js.map +1 -0
- package/dist-esm/src/defaultHttpClient.js +10 -0
- package/dist-esm/src/defaultHttpClient.js.map +1 -0
- package/dist-esm/src/defaultHttpClient.native.js +10 -0
- package/dist-esm/src/defaultHttpClient.native.js.map +1 -0
- package/dist-esm/src/fetchHttpClient.js +268 -0
- package/dist-esm/src/fetchHttpClient.js.map +1 -0
- package/dist-esm/src/httpHeaders.js +89 -0
- package/dist-esm/src/httpHeaders.js.map +1 -0
- package/dist-esm/src/index.js +41 -0
- package/dist-esm/src/index.js.map +1 -0
- package/dist-esm/src/interfaces.js +4 -0
- package/dist-esm/src/interfaces.js.map +1 -0
- package/dist-esm/src/log.js +5 -0
- package/dist-esm/src/log.js.map +1 -0
- package/dist-esm/src/logger/debug.js +93 -0
- package/dist-esm/src/logger/debug.js.map +1 -0
- package/dist-esm/src/logger/log.browser.js +23 -0
- package/dist-esm/src/logger/log.browser.js.map +1 -0
- package/dist-esm/src/logger/log.js +8 -0
- package/dist-esm/src/logger/log.js.map +1 -0
- package/dist-esm/src/logger/logger.js +99 -0
- package/dist-esm/src/logger/logger.js.map +1 -0
- package/dist-esm/src/nodeHttpClient.js +332 -0
- package/dist-esm/src/nodeHttpClient.js.map +1 -0
- package/dist-esm/src/pipeline.js +262 -0
- package/dist-esm/src/pipeline.js.map +1 -0
- package/dist-esm/src/pipelineRequest.js +35 -0
- package/dist-esm/src/pipelineRequest.js.map +1 -0
- package/dist-esm/src/policies/bearerTokenAuthenticationPolicy.js +108 -0
- package/dist-esm/src/policies/bearerTokenAuthenticationPolicy.js.map +1 -0
- package/dist-esm/src/policies/decompressResponsePolicy.browser.js +14 -0
- package/dist-esm/src/policies/decompressResponsePolicy.browser.js.map +1 -0
- package/dist-esm/src/policies/decompressResponsePolicy.js +23 -0
- package/dist-esm/src/policies/decompressResponsePolicy.js.map +1 -0
- package/dist-esm/src/policies/defaultRetryPolicy.js +26 -0
- package/dist-esm/src/policies/defaultRetryPolicy.js.map +1 -0
- package/dist-esm/src/policies/exponentialRetryPolicy.js +22 -0
- package/dist-esm/src/policies/exponentialRetryPolicy.js.map +1 -0
- package/dist-esm/src/policies/formDataPolicy.browser.js +43 -0
- package/dist-esm/src/policies/formDataPolicy.browser.js.map +1 -0
- package/dist-esm/src/policies/formDataPolicy.js +79 -0
- package/dist-esm/src/policies/formDataPolicy.js.map +1 -0
- package/dist-esm/src/policies/logPolicy.js +34 -0
- package/dist-esm/src/policies/logPolicy.js.map +1 -0
- package/dist-esm/src/policies/proxyPolicy.browser.js +27 -0
- package/dist-esm/src/policies/proxyPolicy.browser.js.map +1 -0
- package/dist-esm/src/policies/proxyPolicy.js +190 -0
- package/dist-esm/src/policies/proxyPolicy.js.map +1 -0
- package/dist-esm/src/policies/redirectPolicy.js +52 -0
- package/dist-esm/src/policies/redirectPolicy.js.map +1 -0
- package/dist-esm/src/policies/retryPolicy.js +106 -0
- package/dist-esm/src/policies/retryPolicy.js.map +1 -0
- package/dist-esm/src/policies/systemErrorRetryPolicy.js +27 -0
- package/dist-esm/src/policies/systemErrorRetryPolicy.js.map +1 -0
- package/dist-esm/src/policies/throttlingRetryPolicy.js +29 -0
- package/dist-esm/src/policies/throttlingRetryPolicy.js.map +1 -0
- package/dist-esm/src/policies/tlsPolicy.js +22 -0
- package/dist-esm/src/policies/tlsPolicy.js.map +1 -0
- package/dist-esm/src/policies/tracingPolicy.js +120 -0
- package/dist-esm/src/policies/tracingPolicy.js.map +1 -0
- package/dist-esm/src/policies/userAgentPolicy.js +26 -0
- package/dist-esm/src/policies/userAgentPolicy.js.map +1 -0
- package/dist-esm/src/restError.js +48 -0
- package/dist-esm/src/restError.js.map +1 -0
- package/dist-esm/src/retryStrategies/exponentialRetryStrategy.js +70 -0
- package/dist-esm/src/retryStrategies/exponentialRetryStrategy.js.map +1 -0
- package/dist-esm/src/retryStrategies/retryStrategy.js +4 -0
- package/dist-esm/src/retryStrategies/retryStrategy.js.map +1 -0
- package/dist-esm/src/retryStrategies/throttlingRetryStrategy.js +74 -0
- package/dist-esm/src/retryStrategies/throttlingRetryStrategy.js.map +1 -0
- package/dist-esm/src/tracing/instrumenter.js +61 -0
- package/dist-esm/src/tracing/instrumenter.js.map +1 -0
- package/dist-esm/src/tracing/interfaces.js +4 -0
- package/dist-esm/src/tracing/interfaces.js.map +1 -0
- package/dist-esm/src/tracing/tracingClient.js +74 -0
- package/dist-esm/src/tracing/tracingClient.js.map +1 -0
- package/dist-esm/src/tracing/tracingContext.js +47 -0
- package/dist-esm/src/tracing/tracingContext.js.map +1 -0
- package/dist-esm/src/util/aborterUtils.js +21 -0
- package/dist-esm/src/util/aborterUtils.js.map +1 -0
- package/dist-esm/src/util/base64.browser.js +35 -0
- package/dist-esm/src/util/base64.browser.js.map +1 -0
- package/dist-esm/src/util/bytesEncoding.browser.js +82 -0
- package/dist-esm/src/util/bytesEncoding.browser.js.map +1 -0
- package/dist-esm/src/util/bytesEncoding.js +77 -0
- package/dist-esm/src/util/bytesEncoding.js.map +1 -0
- package/dist-esm/src/util/checkEnvironment.js +36 -0
- package/dist-esm/src/util/checkEnvironment.js.map +1 -0
- package/dist-esm/src/util/createAbortablePromise.js +42 -0
- package/dist-esm/src/util/createAbortablePromise.js.map +1 -0
- package/dist-esm/src/util/delay.js +22 -0
- package/dist-esm/src/util/delay.js.map +1 -0
- package/dist-esm/src/util/error.js +42 -0
- package/dist-esm/src/util/error.js.map +1 -0
- package/dist-esm/src/util/helpers.js +58 -0
- package/dist-esm/src/util/helpers.js.map +1 -0
- package/dist-esm/src/util/hex.js +21 -0
- package/dist-esm/src/util/hex.js.map +1 -0
- package/dist-esm/src/util/inspect.browser.js +4 -0
- package/dist-esm/src/util/inspect.browser.js.map +1 -0
- package/dist-esm/src/util/inspect.js +5 -0
- package/dist-esm/src/util/inspect.js.map +1 -0
- package/dist-esm/src/util/object.js +14 -0
- package/dist-esm/src/util/object.js.map +1 -0
- package/dist-esm/src/util/random.js +21 -0
- package/dist-esm/src/util/random.js.map +1 -0
- package/dist-esm/src/util/sanitizer.js +139 -0
- package/dist-esm/src/util/sanitizer.js.map +1 -0
- package/dist-esm/src/util/sha256.browser.js +61 -0
- package/dist-esm/src/util/sha256.browser.js.map +1 -0
- package/dist-esm/src/util/sha256.js +22 -0
- package/dist-esm/src/util/sha256.js.map +1 -0
- package/dist-esm/src/util/tokenCycler.js +149 -0
- package/dist-esm/src/util/tokenCycler.js.map +1 -0
- package/dist-esm/src/util/typeGuards.js +34 -0
- package/dist-esm/src/util/typeGuards.js.map +1 -0
- package/dist-esm/src/util/userAgent.js +30 -0
- package/dist-esm/src/util/userAgent.js.map +1 -0
- package/dist-esm/src/util/userAgentPlatform.browser.js +20 -0
- package/dist-esm/src/util/userAgentPlatform.browser.js.map +1 -0
- package/dist-esm/src/util/userAgentPlatform.js +17 -0
- package/dist-esm/src/util/userAgentPlatform.js.map +1 -0
- package/dist-esm/src/util/userAgentPlatform.native.js +24 -0
- package/dist-esm/src/util/userAgentPlatform.native.js.map +1 -0
- package/dist-esm/src/util/utf8.browser.js +26 -0
- package/dist-esm/src/util/utf8.browser.js.map +1 -0
- package/dist-esm/src/util/uuidUtils.browser.js +17 -0
- package/dist-esm/src/util/uuidUtils.browser.js.map +1 -0
- package/dist-esm/src/util/uuidUtils.js +22 -0
- package/dist-esm/src/util/uuidUtils.js.map +1 -0
- package/dist-esm/src/util/uuidUtils.native.js +43 -0
- package/dist-esm/src/util/uuidUtils.native.js.map +1 -0
- package/dist-esm/src/xhrHttpClient.js +177 -0
- package/dist-esm/src/xhrHttpClient.js.map +1 -0
- package/package.json +134 -0
- package/ts-http-runtime.shims.d.ts +12 -0
- package/types/ts-http-runtime.d.ts +2062 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
import { exponentialRetryStrategy } from "../retryStrategies/exponentialRetryStrategy";
|
|
4
|
+
import { retryPolicy } from "./retryPolicy";
|
|
5
|
+
import { DEFAULT_RETRY_POLICY_COUNT } from "../constants";
|
|
6
|
+
/**
|
|
7
|
+
* Name of the {@link systemErrorRetryPolicy}
|
|
8
|
+
*/
|
|
9
|
+
export const systemErrorRetryPolicyName = "systemErrorRetryPolicy";
|
|
10
|
+
/**
|
|
11
|
+
* A retry policy that specifically seeks to handle errors in the
|
|
12
|
+
* underlying transport layer (e.g. DNS lookup failures) rather than
|
|
13
|
+
* retryable error codes from the server itself.
|
|
14
|
+
* @param options - Options that customize the policy.
|
|
15
|
+
*/
|
|
16
|
+
export function systemErrorRetryPolicy(options = {}) {
|
|
17
|
+
var _a;
|
|
18
|
+
return {
|
|
19
|
+
name: systemErrorRetryPolicyName,
|
|
20
|
+
sendRequest: retryPolicy([
|
|
21
|
+
exponentialRetryStrategy(Object.assign(Object.assign({}, options), { ignoreHttpStatusCodes: true })),
|
|
22
|
+
], {
|
|
23
|
+
maxRetries: (_a = options.maxRetries) !== null && _a !== void 0 ? _a : DEFAULT_RETRY_POLICY_COUNT,
|
|
24
|
+
}).sendRequest,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=systemErrorRetryPolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemErrorRetryPolicy.js","sourceRoot":"","sources":["../../../src/policies/systemErrorRetryPolicy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAC;AACvF,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAE1D;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,wBAAwB,CAAC;AAyBnE;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CACpC,UAAyC,EAAE;;IAE3C,OAAO;QACL,IAAI,EAAE,0BAA0B;QAChC,WAAW,EAAE,WAAW,CACtB;YACE,wBAAwB,iCACnB,OAAO,KACV,qBAAqB,EAAE,IAAI,IAC3B;SACH,EACD;YACE,UAAU,EAAE,MAAA,OAAO,CAAC,UAAU,mCAAI,0BAA0B;SAC7D,CACF,CAAC,WAAW;KACd,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { PipelinePolicy } from \"../pipeline\";\nimport { exponentialRetryStrategy } from \"../retryStrategies/exponentialRetryStrategy\";\nimport { retryPolicy } from \"./retryPolicy\";\nimport { DEFAULT_RETRY_POLICY_COUNT } from \"../constants\";\n\n/**\n * Name of the {@link systemErrorRetryPolicy}\n */\nexport const systemErrorRetryPolicyName = \"systemErrorRetryPolicy\";\n\n/**\n * Options that control how to retry failed requests.\n */\nexport interface SystemErrorRetryPolicyOptions {\n /**\n * The maximum number of retry attempts. Defaults to 3.\n */\n maxRetries?: number;\n\n /**\n * The amount of delay in milliseconds between retry attempts. Defaults to 1000\n * (1 second.) The delay increases exponentially with each retry up to a maximum\n * specified by maxRetryDelayInMs.\n */\n retryDelayInMs?: number;\n\n /**\n * The maximum delay in milliseconds allowed before retrying an operation. Defaults\n * to 64000 (64 seconds).\n */\n maxRetryDelayInMs?: number;\n}\n\n/**\n * A retry policy that specifically seeks to handle errors in the\n * underlying transport layer (e.g. DNS lookup failures) rather than\n * retryable error codes from the server itself.\n * @param options - Options that customize the policy.\n */\nexport function systemErrorRetryPolicy(\n options: SystemErrorRetryPolicyOptions = {}\n): PipelinePolicy {\n return {\n name: systemErrorRetryPolicyName,\n sendRequest: retryPolicy(\n [\n exponentialRetryStrategy({\n ...options,\n ignoreHttpStatusCodes: true,\n }),\n ],\n {\n maxRetries: options.maxRetries ?? DEFAULT_RETRY_POLICY_COUNT,\n }\n ).sendRequest,\n };\n}\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
import { throttlingRetryStrategy } from "../retryStrategies/throttlingRetryStrategy";
|
|
4
|
+
import { retryPolicy } from "./retryPolicy";
|
|
5
|
+
import { DEFAULT_RETRY_POLICY_COUNT } from "../constants";
|
|
6
|
+
/**
|
|
7
|
+
* Name of the {@link throttlingRetryPolicy}
|
|
8
|
+
*/
|
|
9
|
+
export const throttlingRetryPolicyName = "throttlingRetryPolicy";
|
|
10
|
+
/**
|
|
11
|
+
* A policy that retries when the server sends a 429 response with a Retry-After header.
|
|
12
|
+
*
|
|
13
|
+
* To learn more, please refer to
|
|
14
|
+
* https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-request-limits,
|
|
15
|
+
* https://docs.microsoft.com/en-us/azure/azure-subscription-service-limits and
|
|
16
|
+
* https://docs.microsoft.com/en-us/azure/virtual-machines/troubleshooting/troubleshooting-throttling-errors
|
|
17
|
+
*
|
|
18
|
+
* @param options - Options that configure retry logic.
|
|
19
|
+
*/
|
|
20
|
+
export function throttlingRetryPolicy(options = {}) {
|
|
21
|
+
var _a;
|
|
22
|
+
return {
|
|
23
|
+
name: throttlingRetryPolicyName,
|
|
24
|
+
sendRequest: retryPolicy([throttlingRetryStrategy()], {
|
|
25
|
+
maxRetries: (_a = options.maxRetries) !== null && _a !== void 0 ? _a : DEFAULT_RETRY_POLICY_COUNT,
|
|
26
|
+
}).sendRequest,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=throttlingRetryPolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throttlingRetryPolicy.js","sourceRoot":"","sources":["../../../src/policies/throttlingRetryPolicy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,uBAAuB,EAAE,MAAM,4CAA4C,CAAC;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAE1D;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,uBAAuB,CAAC;AAYjE;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,UAAwC,EAAE;;IAC9E,OAAO;QACL,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EAAE,WAAW,CAAC,CAAC,uBAAuB,EAAE,CAAC,EAAE;YACpD,UAAU,EAAE,MAAA,OAAO,CAAC,UAAU,mCAAI,0BAA0B;SAC7D,CAAC,CAAC,WAAW;KACf,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { PipelinePolicy } from \"../pipeline\";\nimport { throttlingRetryStrategy } from \"../retryStrategies/throttlingRetryStrategy\";\nimport { retryPolicy } from \"./retryPolicy\";\nimport { DEFAULT_RETRY_POLICY_COUNT } from \"../constants\";\n\n/**\n * Name of the {@link throttlingRetryPolicy}\n */\nexport const throttlingRetryPolicyName = \"throttlingRetryPolicy\";\n\n/**\n * Options that control how to retry failed requests.\n */\nexport interface ThrottlingRetryPolicyOptions {\n /**\n * The maximum number of retry attempts. Defaults to 3.\n */\n maxRetries?: number;\n}\n\n/**\n * A policy that retries when the server sends a 429 response with a Retry-After header.\n *\n * To learn more, please refer to\n * https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-request-limits,\n * https://docs.microsoft.com/en-us/azure/azure-subscription-service-limits and\n * https://docs.microsoft.com/en-us/azure/virtual-machines/troubleshooting/troubleshooting-throttling-errors\n *\n * @param options - Options that configure retry logic.\n */\nexport function throttlingRetryPolicy(options: ThrottlingRetryPolicyOptions = {}): PipelinePolicy {\n return {\n name: throttlingRetryPolicyName,\n sendRequest: retryPolicy([throttlingRetryStrategy()], {\n maxRetries: options.maxRetries ?? DEFAULT_RETRY_POLICY_COUNT,\n }).sendRequest,\n };\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
/**
|
|
4
|
+
* Name of the TLS Policy
|
|
5
|
+
*/
|
|
6
|
+
export const tlsPolicyName = "tlsPolicy";
|
|
7
|
+
/**
|
|
8
|
+
* Gets a pipeline policy that adds the client certificate to the HttpClient agent for authentication.
|
|
9
|
+
*/
|
|
10
|
+
export function tlsPolicy(tlsSettings) {
|
|
11
|
+
return {
|
|
12
|
+
name: tlsPolicyName,
|
|
13
|
+
sendRequest: async (req, next) => {
|
|
14
|
+
// Users may define a request tlsSettings, honor those over the client level one
|
|
15
|
+
if (!req.tlsSettings) {
|
|
16
|
+
req.tlsSettings = tlsSettings;
|
|
17
|
+
}
|
|
18
|
+
return next(req);
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=tlsPolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tlsPolicy.js","sourceRoot":"","sources":["../../../src/policies/tlsPolicy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAKlC;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAC;AAEzC;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,WAAyB;IACjD,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YAC/B,gFAAgF;YAChF,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE;gBACpB,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC;aAC/B;YACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { PipelinePolicy } from \"../pipeline\";\nimport { TlsSettings } from \"../interfaces\";\n\n/**\n * Name of the TLS Policy\n */\nexport const tlsPolicyName = \"tlsPolicy\";\n\n/**\n * Gets a pipeline policy that adds the client certificate to the HttpClient agent for authentication.\n */\nexport function tlsPolicy(tlsSettings?: TlsSettings): PipelinePolicy {\n return {\n name: tlsPolicyName,\n sendRequest: async (req, next) => {\n // Users may define a request tlsSettings, honor those over the client level one\n if (!req.tlsSettings) {\n req.tlsSettings = tlsSettings;\n }\n return next(req);\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
import { createTracingClient } from "../tracing/tracingClient";
|
|
4
|
+
import { SDK_VERSION } from "../constants";
|
|
5
|
+
import { getUserAgentValue } from "../util/userAgent";
|
|
6
|
+
import { logger } from "../log";
|
|
7
|
+
import { getErrorMessage, isError } from "../util/error";
|
|
8
|
+
import { isRestError } from "../restError";
|
|
9
|
+
/**
|
|
10
|
+
* The programmatic identifier of the tracingPolicy.
|
|
11
|
+
*/
|
|
12
|
+
export const tracingPolicyName = "tracingPolicy";
|
|
13
|
+
/**
|
|
14
|
+
* A simple policy to create OpenTelemetry Spans for each request made by the pipeline
|
|
15
|
+
* that has SpanOptions with a parent.
|
|
16
|
+
* Requests made without a parent Span will not be recorded.
|
|
17
|
+
* @param options - Options to configure the telemetry logged by the tracing policy.
|
|
18
|
+
*/
|
|
19
|
+
export function tracingPolicy(options = {}) {
|
|
20
|
+
const userAgent = getUserAgentValue(options.userAgentPrefix);
|
|
21
|
+
const tracingClient = tryCreateTracingClient();
|
|
22
|
+
return {
|
|
23
|
+
name: tracingPolicyName,
|
|
24
|
+
async sendRequest(request, next) {
|
|
25
|
+
var _a, _b;
|
|
26
|
+
if (!tracingClient || !((_a = request.tracingOptions) === null || _a === void 0 ? void 0 : _a.tracingContext)) {
|
|
27
|
+
return next(request);
|
|
28
|
+
}
|
|
29
|
+
const { span, tracingContext } = (_b = tryCreateSpan(tracingClient, request, userAgent)) !== null && _b !== void 0 ? _b : {};
|
|
30
|
+
if (!span || !tracingContext) {
|
|
31
|
+
return next(request);
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const response = await tracingClient.withContext(tracingContext, next, request);
|
|
35
|
+
tryProcessResponse(span, response);
|
|
36
|
+
return response;
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
tryProcessError(span, err);
|
|
40
|
+
throw err;
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function tryCreateTracingClient() {
|
|
46
|
+
try {
|
|
47
|
+
return createTracingClient({
|
|
48
|
+
namespace: "",
|
|
49
|
+
packageName: "@typespec/ts-http-runtime",
|
|
50
|
+
packageVersion: SDK_VERSION,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
logger.warning(`Error when creating the TracingClient: ${getErrorMessage(e)}`);
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function tryCreateSpan(tracingClient, request, userAgent) {
|
|
59
|
+
try {
|
|
60
|
+
// As per spec, we do not need to differentiate between HTTP and HTTPS in span name.
|
|
61
|
+
const { span, updatedOptions } = tracingClient.startSpan(`HTTP ${request.method}`, { tracingOptions: request.tracingOptions }, {
|
|
62
|
+
spanKind: "client",
|
|
63
|
+
spanAttributes: {
|
|
64
|
+
"http.method": request.method,
|
|
65
|
+
"http.url": request.url,
|
|
66
|
+
requestId: request.requestId,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
// If the span is not recording, don't do any more work.
|
|
70
|
+
if (!span.isRecording()) {
|
|
71
|
+
span.end();
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
if (userAgent) {
|
|
75
|
+
span.setAttribute("http.user_agent", userAgent);
|
|
76
|
+
}
|
|
77
|
+
// set headers
|
|
78
|
+
const headers = tracingClient.createRequestHeaders(updatedOptions.tracingOptions.tracingContext);
|
|
79
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
80
|
+
request.headers.set(key, value);
|
|
81
|
+
}
|
|
82
|
+
return { span, tracingContext: updatedOptions.tracingOptions.tracingContext };
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
logger.warning(`Skipping creating a tracing span due to an error: ${getErrorMessage(e)}`);
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function tryProcessError(span, error) {
|
|
90
|
+
try {
|
|
91
|
+
span.setStatus({
|
|
92
|
+
status: "error",
|
|
93
|
+
error: isError(error) ? error : undefined,
|
|
94
|
+
});
|
|
95
|
+
if (isRestError(error) && error.statusCode) {
|
|
96
|
+
span.setAttribute("http.status_code", error.statusCode);
|
|
97
|
+
}
|
|
98
|
+
span.end();
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
logger.warning(`Skipping tracing span processing due to an error: ${getErrorMessage(e)}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function tryProcessResponse(span, response) {
|
|
105
|
+
try {
|
|
106
|
+
span.setAttribute("http.status_code", response.status);
|
|
107
|
+
const serviceRequestId = response.headers.get("x-ms-request-id");
|
|
108
|
+
if (serviceRequestId) {
|
|
109
|
+
span.setAttribute("serviceRequestId", serviceRequestId);
|
|
110
|
+
}
|
|
111
|
+
span.setStatus({
|
|
112
|
+
status: "success",
|
|
113
|
+
});
|
|
114
|
+
span.end();
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
logger.warning(`Skipping tracing span processing due to an error: ${getErrorMessage(e)}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=tracingPolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracingPolicy.js","sourceRoot":"","sources":["../../../src/policies/tracingPolicy.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TracingClient, TracingContext, TracingSpan } from \"../tracing/interfaces\";\nimport { createTracingClient } from \"../tracing/tracingClient\";\nimport { SDK_VERSION } from \"../constants\";\nimport { PipelineRequest, PipelineResponse, SendRequest } from \"../interfaces\";\nimport { PipelinePolicy } from \"../pipeline\";\nimport { getUserAgentValue } from \"../util/userAgent\";\nimport { logger } from \"../log\";\nimport { getErrorMessage, isError } from \"../util/error\";\nimport { isRestError } from \"../restError\";\n\n/**\n * The programmatic identifier of the tracingPolicy.\n */\nexport const tracingPolicyName = \"tracingPolicy\";\n\n/**\n * Options to configure the tracing policy.\n */\nexport interface TracingPolicyOptions {\n /**\n * String prefix to add to the user agent logged as metadata\n * on the generated Span.\n * Defaults to an empty string.\n */\n userAgentPrefix?: string;\n}\n\n/**\n * A simple policy to create OpenTelemetry Spans for each request made by the pipeline\n * that has SpanOptions with a parent.\n * Requests made without a parent Span will not be recorded.\n * @param options - Options to configure the telemetry logged by the tracing policy.\n */\nexport function tracingPolicy(options: TracingPolicyOptions = {}): PipelinePolicy {\n const userAgent = getUserAgentValue(options.userAgentPrefix);\n const tracingClient = tryCreateTracingClient();\n\n return {\n name: tracingPolicyName,\n async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {\n if (!tracingClient || !request.tracingOptions?.tracingContext) {\n return next(request);\n }\n\n const { span, tracingContext } = tryCreateSpan(tracingClient, request, userAgent) ?? {};\n\n if (!span || !tracingContext) {\n return next(request);\n }\n\n try {\n const response = await tracingClient.withContext(tracingContext, next, request);\n tryProcessResponse(span, response);\n return response;\n } catch (err: any) {\n tryProcessError(span, err);\n throw err;\n }\n },\n };\n}\n\nfunction tryCreateTracingClient(): TracingClient | undefined {\n try {\n return createTracingClient({\n namespace: \"\",\n packageName: \"@typespec/ts-http-runtime\",\n packageVersion: SDK_VERSION,\n });\n } catch (e: unknown) {\n logger.warning(`Error when creating the TracingClient: ${getErrorMessage(e)}`);\n return undefined;\n }\n}\n\nfunction tryCreateSpan(\n tracingClient: TracingClient,\n request: PipelineRequest,\n userAgent?: string\n): { span: TracingSpan; tracingContext: TracingContext } | undefined {\n try {\n // As per spec, we do not need to differentiate between HTTP and HTTPS in span name.\n const { span, updatedOptions } = tracingClient.startSpan(\n `HTTP ${request.method}`,\n { tracingOptions: request.tracingOptions },\n {\n spanKind: \"client\",\n spanAttributes: {\n \"http.method\": request.method,\n \"http.url\": request.url,\n requestId: request.requestId,\n },\n }\n );\n\n // If the span is not recording, don't do any more work.\n if (!span.isRecording()) {\n span.end();\n return undefined;\n }\n\n if (userAgent) {\n span.setAttribute(\"http.user_agent\", userAgent);\n }\n\n // set headers\n const headers = tracingClient.createRequestHeaders(\n updatedOptions.tracingOptions.tracingContext\n );\n for (const [key, value] of Object.entries(headers)) {\n request.headers.set(key, value);\n }\n return { span, tracingContext: updatedOptions.tracingOptions.tracingContext };\n } catch (e: any) {\n logger.warning(`Skipping creating a tracing span due to an error: ${getErrorMessage(e)}`);\n return undefined;\n }\n}\n\nfunction tryProcessError(span: TracingSpan, error: unknown): void {\n try {\n span.setStatus({\n status: \"error\",\n error: isError(error) ? error : undefined,\n });\n if (isRestError(error) && error.statusCode) {\n span.setAttribute(\"http.status_code\", error.statusCode);\n }\n span.end();\n } catch (e: any) {\n logger.warning(`Skipping tracing span processing due to an error: ${getErrorMessage(e)}`);\n }\n}\n\nfunction tryProcessResponse(span: TracingSpan, response: PipelineResponse): void {\n try {\n span.setAttribute(\"http.status_code\", response.status);\n const serviceRequestId = response.headers.get(\"x-ms-request-id\");\n if (serviceRequestId) {\n span.setAttribute(\"serviceRequestId\", serviceRequestId);\n }\n span.setStatus({\n status: \"success\",\n });\n span.end();\n } catch (e: any) {\n logger.warning(`Skipping tracing span processing due to an error: ${getErrorMessage(e)}`);\n }\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
import { getUserAgentHeaderName, getUserAgentValue } from "../util/userAgent";
|
|
4
|
+
const UserAgentHeaderName = getUserAgentHeaderName();
|
|
5
|
+
/**
|
|
6
|
+
* The programmatic identifier of the userAgentPolicy.
|
|
7
|
+
*/
|
|
8
|
+
export const userAgentPolicyName = "userAgentPolicy";
|
|
9
|
+
/**
|
|
10
|
+
* A policy that sets the User-Agent header (or equivalent) to reflect
|
|
11
|
+
* the library version.
|
|
12
|
+
* @param options - Options to customize the user agent value.
|
|
13
|
+
*/
|
|
14
|
+
export function userAgentPolicy(options = {}) {
|
|
15
|
+
const userAgentValue = getUserAgentValue(options.userAgentPrefix);
|
|
16
|
+
return {
|
|
17
|
+
name: userAgentPolicyName,
|
|
18
|
+
async sendRequest(request, next) {
|
|
19
|
+
if (!request.headers.has(UserAgentHeaderName)) {
|
|
20
|
+
request.headers.set(UserAgentHeaderName, userAgentValue);
|
|
21
|
+
}
|
|
22
|
+
return next(request);
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=userAgentPolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userAgentPolicy.js","sourceRoot":"","sources":["../../../src/policies/userAgentPolicy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE9E,MAAM,mBAAmB,GAAG,sBAAsB,EAAE,CAAC;AAErD;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AAarD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,UAAkC,EAAE;IAClE,MAAM,cAAc,GAAG,iBAAiB,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAClE,OAAO;QACL,IAAI,EAAE,mBAAmB;QACzB,KAAK,CAAC,WAAW,CAAC,OAAwB,EAAE,IAAiB;YAC3D,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,EAAE;gBAC7C,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,cAAc,CAAC,CAAC;aAC1D;YACD,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { PipelineRequest, PipelineResponse, SendRequest } from \"../interfaces\";\nimport { PipelinePolicy } from \"../pipeline\";\nimport { getUserAgentHeaderName, getUserAgentValue } from \"../util/userAgent\";\n\nconst UserAgentHeaderName = getUserAgentHeaderName();\n\n/**\n * The programmatic identifier of the userAgentPolicy.\n */\nexport const userAgentPolicyName = \"userAgentPolicy\";\n\n/**\n * Options for adding user agent details to outgoing requests.\n */\nexport interface UserAgentPolicyOptions {\n /**\n * String prefix to add to the user agent for outgoing requests.\n * Defaults to an empty string.\n */\n userAgentPrefix?: string;\n}\n\n/**\n * A policy that sets the User-Agent header (or equivalent) to reflect\n * the library version.\n * @param options - Options to customize the user agent value.\n */\nexport function userAgentPolicy(options: UserAgentPolicyOptions = {}): PipelinePolicy {\n const userAgentValue = getUserAgentValue(options.userAgentPrefix);\n return {\n name: userAgentPolicyName,\n async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {\n if (!request.headers.has(UserAgentHeaderName)) {\n request.headers.set(UserAgentHeaderName, userAgentValue);\n }\n return next(request);\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
import { isError } from "./util/error";
|
|
4
|
+
import { custom } from "./util/inspect";
|
|
5
|
+
import { Sanitizer } from "./util/sanitizer";
|
|
6
|
+
const errorSanitizer = new Sanitizer();
|
|
7
|
+
/**
|
|
8
|
+
* A custom error type for failed pipeline requests.
|
|
9
|
+
*/
|
|
10
|
+
export class RestError extends Error {
|
|
11
|
+
constructor(message, options = {}) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = "RestError";
|
|
14
|
+
this.code = options.code;
|
|
15
|
+
this.statusCode = options.statusCode;
|
|
16
|
+
this.request = options.request;
|
|
17
|
+
this.response = options.response;
|
|
18
|
+
Object.setPrototypeOf(this, RestError.prototype);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Logging method for util.inspect in Node
|
|
22
|
+
*/
|
|
23
|
+
[custom]() {
|
|
24
|
+
return `RestError: ${this.message} \n ${errorSanitizer.sanitize(this)}`;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Something went wrong when making the request.
|
|
29
|
+
* This means the actual request failed for some reason,
|
|
30
|
+
* such as a DNS issue or the connection being lost.
|
|
31
|
+
*/
|
|
32
|
+
RestError.REQUEST_SEND_ERROR = "REQUEST_SEND_ERROR";
|
|
33
|
+
/**
|
|
34
|
+
* This means that parsing the response from the server failed.
|
|
35
|
+
* It may have been malformed.
|
|
36
|
+
*/
|
|
37
|
+
RestError.PARSE_ERROR = "PARSE_ERROR";
|
|
38
|
+
/**
|
|
39
|
+
* Typeguard for RestError
|
|
40
|
+
* @param e - Something caught by a catch clause.
|
|
41
|
+
*/
|
|
42
|
+
export function isRestError(e) {
|
|
43
|
+
if (e instanceof RestError) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
return isError(e) && e.name === "RestError";
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=restError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restError.js","sourceRoot":"","sources":["../../src/restError.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,cAAc,GAAG,IAAI,SAAS,EAAE,CAAC;AAwBvC;;GAEG;AACH,MAAM,OAAO,SAAU,SAAQ,KAAK;IAkClC,YAAY,OAAe,EAAE,UAA4B,EAAE;QACzD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QAEjC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,CAAC,MAAM,CAAC;QACN,OAAO,cAAc,IAAI,CAAC,OAAO,OAAO,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IAC1E,CAAC;;AAjDD;;;;GAIG;AACa,4BAAkB,GAAW,oBAAoB,CAAC;AAClE;;;GAGG;AACa,qBAAW,GAAW,aAAa,CAAC;AA0CtD;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,CAAU;IACpC,IAAI,CAAC,YAAY,SAAS,EAAE;QAC1B,OAAO,IAAI,CAAC;KACb;IACD,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC;AAC9C,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { isError } from \"./util/error\";\nimport { PipelineRequest, PipelineResponse } from \"./interfaces\";\nimport { custom } from \"./util/inspect\";\nimport { Sanitizer } from \"./util/sanitizer\";\n\nconst errorSanitizer = new Sanitizer();\n\n/**\n * The options supported by RestError.\n */\nexport interface RestErrorOptions {\n /**\n * The code of the error itself (use statics on RestError if possible.)\n */\n code?: string;\n /**\n * The HTTP status code of the request (if applicable.)\n */\n statusCode?: number;\n /**\n * The request that was made.\n */\n request?: PipelineRequest;\n /**\n * The response received (if any.)\n */\n response?: PipelineResponse;\n}\n\n/**\n * A custom error type for failed pipeline requests.\n */\nexport class RestError extends Error {\n /**\n * Something went wrong when making the request.\n * This means the actual request failed for some reason,\n * such as a DNS issue or the connection being lost.\n */\n static readonly REQUEST_SEND_ERROR: string = \"REQUEST_SEND_ERROR\";\n /**\n * This means that parsing the response from the server failed.\n * It may have been malformed.\n */\n static readonly PARSE_ERROR: string = \"PARSE_ERROR\";\n\n /**\n * The code of the error itself (use statics on RestError if possible.)\n */\n public code?: string;\n /**\n * The HTTP status code of the request (if applicable.)\n */\n public statusCode?: number;\n /**\n * The request that was made.\n */\n public request?: PipelineRequest;\n /**\n * The response received (if any.)\n */\n public response?: PipelineResponse;\n /**\n * Bonus property set by the throw site.\n */\n public details?: unknown;\n\n constructor(message: string, options: RestErrorOptions = {}) {\n super(message);\n this.name = \"RestError\";\n this.code = options.code;\n this.statusCode = options.statusCode;\n this.request = options.request;\n this.response = options.response;\n\n Object.setPrototypeOf(this, RestError.prototype);\n }\n\n /**\n * Logging method for util.inspect in Node\n */\n [custom](): string {\n return `RestError: ${this.message} \\n ${errorSanitizer.sanitize(this)}`;\n }\n}\n\n/**\n * Typeguard for RestError\n * @param e - Something caught by a catch clause.\n */\nexport function isRestError(e: unknown): e is RestError {\n if (e instanceof RestError) {\n return true;\n }\n return isError(e) && e.name === \"RestError\";\n}\n"]}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
import { getRandomIntegerInclusive } from "../util/random";
|
|
4
|
+
import { isThrottlingRetryResponse } from "./throttlingRetryStrategy";
|
|
5
|
+
// intervals are in milliseconds
|
|
6
|
+
const DEFAULT_CLIENT_RETRY_INTERVAL = 1000;
|
|
7
|
+
const DEFAULT_CLIENT_MAX_RETRY_INTERVAL = 1000 * 64;
|
|
8
|
+
/**
|
|
9
|
+
* A retry strategy that retries with an exponentially increasing delay in these two cases:
|
|
10
|
+
* - When there are errors in the underlying transport layer (e.g. DNS lookup failures).
|
|
11
|
+
* - Or otherwise if the outgoing request fails (408, greater or equal than 500, except for 501 and 505).
|
|
12
|
+
*/
|
|
13
|
+
export function exponentialRetryStrategy(options = {}) {
|
|
14
|
+
var _a, _b;
|
|
15
|
+
const retryInterval = (_a = options.retryDelayInMs) !== null && _a !== void 0 ? _a : DEFAULT_CLIENT_RETRY_INTERVAL;
|
|
16
|
+
const maxRetryInterval = (_b = options.maxRetryDelayInMs) !== null && _b !== void 0 ? _b : DEFAULT_CLIENT_MAX_RETRY_INTERVAL;
|
|
17
|
+
let retryAfterInMs = retryInterval;
|
|
18
|
+
return {
|
|
19
|
+
name: "exponentialRetryStrategy",
|
|
20
|
+
retry({ retryCount, response, responseError }) {
|
|
21
|
+
const matchedSystemError = isSystemError(responseError);
|
|
22
|
+
const ignoreSystemErrors = matchedSystemError && options.ignoreSystemErrors;
|
|
23
|
+
const isExponential = isExponentialRetryResponse(response);
|
|
24
|
+
const ignoreExponentialResponse = isExponential && options.ignoreHttpStatusCodes;
|
|
25
|
+
const unknownResponse = response && (isThrottlingRetryResponse(response) || !isExponential);
|
|
26
|
+
if (unknownResponse || ignoreExponentialResponse || ignoreSystemErrors) {
|
|
27
|
+
return { skipStrategy: true };
|
|
28
|
+
}
|
|
29
|
+
if (responseError && !matchedSystemError && !isExponential) {
|
|
30
|
+
return { errorToThrow: responseError };
|
|
31
|
+
}
|
|
32
|
+
// Exponentially increase the delay each time
|
|
33
|
+
const exponentialDelay = retryAfterInMs * Math.pow(2, retryCount);
|
|
34
|
+
// Don't let the delay exceed the maximum
|
|
35
|
+
const clampedExponentialDelay = Math.min(maxRetryInterval, exponentialDelay);
|
|
36
|
+
// Allow the final value to have some "jitter" (within 50% of the delay size) so
|
|
37
|
+
// that retries across multiple clients don't occur simultaneously.
|
|
38
|
+
retryAfterInMs =
|
|
39
|
+
clampedExponentialDelay / 2 + getRandomIntegerInclusive(0, clampedExponentialDelay / 2);
|
|
40
|
+
return { retryAfterInMs };
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* A response is a retry response if it has status codes:
|
|
46
|
+
* - 408, or
|
|
47
|
+
* - Greater or equal than 500, except for 501 and 505.
|
|
48
|
+
*/
|
|
49
|
+
export function isExponentialRetryResponse(response) {
|
|
50
|
+
return Boolean(response &&
|
|
51
|
+
response.status !== undefined &&
|
|
52
|
+
(response.status >= 500 || response.status === 408) &&
|
|
53
|
+
response.status !== 501 &&
|
|
54
|
+
response.status !== 505);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Determines whether an error from a pipeline response was triggered in the network layer.
|
|
58
|
+
*/
|
|
59
|
+
export function isSystemError(err) {
|
|
60
|
+
if (!err) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
return (err.code === "ETIMEDOUT" ||
|
|
64
|
+
err.code === "ESOCKETTIMEDOUT" ||
|
|
65
|
+
err.code === "ECONNREFUSED" ||
|
|
66
|
+
err.code === "ECONNRESET" ||
|
|
67
|
+
err.code === "ENOENT" ||
|
|
68
|
+
err.code === "ENOTFOUND");
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=exponentialRetryStrategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exponentialRetryStrategy.js","sourceRoot":"","sources":["../../../src/retryStrategies/exponentialRetryStrategy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAE3D,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAEtE,gCAAgC;AAChC,MAAM,6BAA6B,GAAG,IAAI,CAAC;AAC3C,MAAM,iCAAiC,GAAG,IAAI,GAAG,EAAE,CAAC;AAEpD;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CACtC,UAuBI,EAAE;;IAEN,MAAM,aAAa,GAAG,MAAA,OAAO,CAAC,cAAc,mCAAI,6BAA6B,CAAC;IAC9E,MAAM,gBAAgB,GAAG,MAAA,OAAO,CAAC,iBAAiB,mCAAI,iCAAiC,CAAC;IAExF,IAAI,cAAc,GAAG,aAAa,CAAC;IAEnC,OAAO;QACL,IAAI,EAAE,0BAA0B;QAChC,KAAK,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE;YAC3C,MAAM,kBAAkB,GAAG,aAAa,CAAC,aAAa,CAAC,CAAC;YACxD,MAAM,kBAAkB,GAAG,kBAAkB,IAAI,OAAO,CAAC,kBAAkB,CAAC;YAE5E,MAAM,aAAa,GAAG,0BAA0B,CAAC,QAAQ,CAAC,CAAC;YAC3D,MAAM,yBAAyB,GAAG,aAAa,IAAI,OAAO,CAAC,qBAAqB,CAAC;YACjF,MAAM,eAAe,GAAG,QAAQ,IAAI,CAAC,yBAAyB,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAE5F,IAAI,eAAe,IAAI,yBAAyB,IAAI,kBAAkB,EAAE;gBACtE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;aAC/B;YAED,IAAI,aAAa,IAAI,CAAC,kBAAkB,IAAI,CAAC,aAAa,EAAE;gBAC1D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;aACxC;YAED,6CAA6C;YAC7C,MAAM,gBAAgB,GAAG,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;YAClE,yCAAyC;YACzC,MAAM,uBAAuB,GAAG,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;YAC7E,gFAAgF;YAChF,mEAAmE;YACnE,cAAc;gBACZ,uBAAuB,GAAG,CAAC,GAAG,yBAAyB,CAAC,CAAC,EAAE,uBAAuB,GAAG,CAAC,CAAC,CAAC;YAC1F,OAAO,EAAE,cAAc,EAAE,CAAC;QAC5B,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CAAC,QAA2B;IACpE,OAAO,OAAO,CACZ,QAAQ;QACN,QAAQ,CAAC,MAAM,KAAK,SAAS;QAC7B,CAAC,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC;QACnD,QAAQ,CAAC,MAAM,KAAK,GAAG;QACvB,QAAQ,CAAC,MAAM,KAAK,GAAG,CAC1B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,GAAe;IAC3C,IAAI,CAAC,GAAG,EAAE;QACR,OAAO,KAAK,CAAC;KACd;IACD,OAAO,CACL,GAAG,CAAC,IAAI,KAAK,WAAW;QACxB,GAAG,CAAC,IAAI,KAAK,iBAAiB;QAC9B,GAAG,CAAC,IAAI,KAAK,cAAc;QAC3B,GAAG,CAAC,IAAI,KAAK,YAAY;QACzB,GAAG,CAAC,IAAI,KAAK,QAAQ;QACrB,GAAG,CAAC,IAAI,KAAK,WAAW,CACzB,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { PipelineResponse } from \"../interfaces\";\nimport { RestError } from \"../restError\";\nimport { getRandomIntegerInclusive } from \"../util/random\";\nimport { RetryStrategy } from \"./retryStrategy\";\nimport { isThrottlingRetryResponse } from \"./throttlingRetryStrategy\";\n\n// intervals are in milliseconds\nconst DEFAULT_CLIENT_RETRY_INTERVAL = 1000;\nconst DEFAULT_CLIENT_MAX_RETRY_INTERVAL = 1000 * 64;\n\n/**\n * A retry strategy that retries with an exponentially increasing delay in these two cases:\n * - When there are errors in the underlying transport layer (e.g. DNS lookup failures).\n * - Or otherwise if the outgoing request fails (408, greater or equal than 500, except for 501 and 505).\n */\nexport function exponentialRetryStrategy(\n options: {\n /**\n * The amount of delay in milliseconds between retry attempts. Defaults to 1000\n * (1 second.) The delay increases exponentially with each retry up to a maximum\n * specified by maxRetryDelayInMs.\n */\n retryDelayInMs?: number;\n\n /**\n * The maximum delay in milliseconds allowed before retrying an operation. Defaults\n * to 64000 (64 seconds).\n */\n maxRetryDelayInMs?: number;\n\n /**\n * If true it won't retry if it received a system error.\n */\n ignoreSystemErrors?: boolean;\n\n /**\n * If true it won't retry if it received a non-fatal HTTP status code.\n */\n ignoreHttpStatusCodes?: boolean;\n } = {}\n): RetryStrategy {\n const retryInterval = options.retryDelayInMs ?? DEFAULT_CLIENT_RETRY_INTERVAL;\n const maxRetryInterval = options.maxRetryDelayInMs ?? DEFAULT_CLIENT_MAX_RETRY_INTERVAL;\n\n let retryAfterInMs = retryInterval;\n\n return {\n name: \"exponentialRetryStrategy\",\n retry({ retryCount, response, responseError }) {\n const matchedSystemError = isSystemError(responseError);\n const ignoreSystemErrors = matchedSystemError && options.ignoreSystemErrors;\n\n const isExponential = isExponentialRetryResponse(response);\n const ignoreExponentialResponse = isExponential && options.ignoreHttpStatusCodes;\n const unknownResponse = response && (isThrottlingRetryResponse(response) || !isExponential);\n\n if (unknownResponse || ignoreExponentialResponse || ignoreSystemErrors) {\n return { skipStrategy: true };\n }\n\n if (responseError && !matchedSystemError && !isExponential) {\n return { errorToThrow: responseError };\n }\n\n // Exponentially increase the delay each time\n const exponentialDelay = retryAfterInMs * Math.pow(2, retryCount);\n // Don't let the delay exceed the maximum\n const clampedExponentialDelay = Math.min(maxRetryInterval, exponentialDelay);\n // Allow the final value to have some \"jitter\" (within 50% of the delay size) so\n // that retries across multiple clients don't occur simultaneously.\n retryAfterInMs =\n clampedExponentialDelay / 2 + getRandomIntegerInclusive(0, clampedExponentialDelay / 2);\n return { retryAfterInMs };\n },\n };\n}\n\n/**\n * A response is a retry response if it has status codes:\n * - 408, or\n * - Greater or equal than 500, except for 501 and 505.\n */\nexport function isExponentialRetryResponse(response?: PipelineResponse): boolean {\n return Boolean(\n response &&\n response.status !== undefined &&\n (response.status >= 500 || response.status === 408) &&\n response.status !== 501 &&\n response.status !== 505\n );\n}\n\n/**\n * Determines whether an error from a pipeline response was triggered in the network layer.\n */\nexport function isSystemError(err?: RestError): boolean {\n if (!err) {\n return false;\n }\n return (\n err.code === \"ETIMEDOUT\" ||\n err.code === \"ESOCKETTIMEDOUT\" ||\n err.code === \"ECONNREFUSED\" ||\n err.code === \"ECONNRESET\" ||\n err.code === \"ENOENT\" ||\n err.code === \"ENOTFOUND\"\n );\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retryStrategy.js","sourceRoot":"","sources":["../../../src/retryStrategies/retryStrategy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TypeSpecRuntimeLogger } from \"../logger/logger\";\nimport { PipelineResponse } from \"../interfaces\";\nimport { RestError } from \"../restError\";\n\n/**\n * Information provided to the retry strategy about the current progress of the retry policy.\n */\nexport interface RetryInformation {\n /**\n * A {@link PipelineResponse}, if the last retry attempt succeeded.\n */\n response?: PipelineResponse;\n /**\n * A {@link RestError}, if the last retry attempt failed.\n */\n responseError?: RestError;\n /**\n * Total number of retries so far.\n */\n retryCount: number;\n}\n\n/**\n * Properties that can modify the behavior of the retry policy.\n */\nexport interface RetryModifiers {\n /**\n * If true, allows skipping the current strategy from running on the retry policy.\n */\n skipStrategy?: boolean;\n /**\n * Indicates to retry against this URL.\n */\n redirectTo?: string;\n /**\n * Controls whether to retry in a given number of milliseconds.\n * If provided, a new retry will be attempted.\n */\n retryAfterInMs?: number;\n /**\n * Indicates to throw this error instead of retrying.\n */\n errorToThrow?: RestError;\n}\n\n/**\n * A retry strategy is intended to define whether to retry or not, and how to retry.\n */\nexport interface RetryStrategy {\n /**\n * Name of the retry strategy. Used for logging.\n */\n name: string;\n /**\n * Logger. If it's not provided, a default logger for all retry strategies is used.\n */\n logger?: TypeSpecRuntimeLogger;\n /**\n * Function that determines how to proceed with the subsequent requests.\n * @param state - Retry state\n */\n retry(state: RetryInformation): RetryModifiers;\n}\n"]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
import { parseHeaderValueAsNumber } from "../util/helpers";
|
|
4
|
+
/**
|
|
5
|
+
* The header that comes back from services representing
|
|
6
|
+
* the amount of time (minimum) to wait to retry (in seconds or timestamp after which we can retry).
|
|
7
|
+
*/
|
|
8
|
+
const RetryAfterHeader = "Retry-After";
|
|
9
|
+
/**
|
|
10
|
+
* The headers that come back from services representing
|
|
11
|
+
* the amount of time (minimum) to wait to retry.
|
|
12
|
+
*
|
|
13
|
+
* "retry-after-ms", "x-ms-retry-after-ms" : milliseconds
|
|
14
|
+
* "Retry-After" : seconds or timestamp
|
|
15
|
+
*/
|
|
16
|
+
const AllRetryAfterHeaders = ["retry-after-ms", "x-ms-retry-after-ms", RetryAfterHeader];
|
|
17
|
+
/**
|
|
18
|
+
* A response is a throttling retry response if it has a throttling status code (429 or 503),
|
|
19
|
+
* as long as one of the [ "Retry-After" or "retry-after-ms" or "x-ms-retry-after-ms" ] headers has a valid value.
|
|
20
|
+
*
|
|
21
|
+
* Returns the `retryAfterInMs` value if the response is a throttling retry response.
|
|
22
|
+
* If not throttling retry response, returns `undefined`.
|
|
23
|
+
*
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
function getRetryAfterInMs(response) {
|
|
27
|
+
if (!(response && [429, 503].includes(response.status)))
|
|
28
|
+
return undefined;
|
|
29
|
+
try {
|
|
30
|
+
// Headers: "retry-after-ms", "x-ms-retry-after-ms", "Retry-After"
|
|
31
|
+
for (const header of AllRetryAfterHeaders) {
|
|
32
|
+
const retryAfterValue = parseHeaderValueAsNumber(response, header);
|
|
33
|
+
if (retryAfterValue === 0 || retryAfterValue) {
|
|
34
|
+
// "Retry-After" header ==> seconds
|
|
35
|
+
// "retry-after-ms", "x-ms-retry-after-ms" headers ==> milli-seconds
|
|
36
|
+
const multiplyingFactor = header === RetryAfterHeader ? 1000 : 1;
|
|
37
|
+
return retryAfterValue * multiplyingFactor; // in milli-seconds
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// RetryAfterHeader ("Retry-After") has a special case where it might be formatted as a date instead of a number of seconds
|
|
41
|
+
const retryAfterHeader = response.headers.get(RetryAfterHeader);
|
|
42
|
+
if (!retryAfterHeader)
|
|
43
|
+
return;
|
|
44
|
+
const date = Date.parse(retryAfterHeader);
|
|
45
|
+
const diff = date - Date.now();
|
|
46
|
+
// negative diff would mean a date in the past, so retry asap with 0 milliseconds
|
|
47
|
+
return Number.isFinite(diff) ? Math.max(0, diff) : undefined;
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A response is a retry response if it has a throttling status code (429 or 503),
|
|
55
|
+
* as long as one of the [ "Retry-After" or "retry-after-ms" or "x-ms-retry-after-ms" ] headers has a valid value.
|
|
56
|
+
*/
|
|
57
|
+
export function isThrottlingRetryResponse(response) {
|
|
58
|
+
return Number.isFinite(getRetryAfterInMs(response));
|
|
59
|
+
}
|
|
60
|
+
export function throttlingRetryStrategy() {
|
|
61
|
+
return {
|
|
62
|
+
name: "throttlingRetryStrategy",
|
|
63
|
+
retry({ response }) {
|
|
64
|
+
const retryAfterInMs = getRetryAfterInMs(response);
|
|
65
|
+
if (!Number.isFinite(retryAfterInMs)) {
|
|
66
|
+
return { skipStrategy: true };
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
retryAfterInMs,
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=throttlingRetryStrategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throttlingRetryStrategy.js","sourceRoot":"","sources":["../../../src/retryStrategies/throttlingRetryStrategy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAG3D;;;GAGG;AACH,MAAM,gBAAgB,GAAG,aAAa,CAAC;AACvC;;;;;;GAMG;AACH,MAAM,oBAAoB,GAAa,CAAC,gBAAgB,EAAE,qBAAqB,EAAE,gBAAgB,CAAC,CAAC;AAEnG;;;;;;;;GAQG;AACH,SAAS,iBAAiB,CAAC,QAA2B;IACpD,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1E,IAAI;QACF,kEAAkE;QAClE,KAAK,MAAM,MAAM,IAAI,oBAAoB,EAAE;YACzC,MAAM,eAAe,GAAG,wBAAwB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACnE,IAAI,eAAe,KAAK,CAAC,IAAI,eAAe,EAAE;gBAC5C,mCAAmC;gBACnC,oEAAoE;gBACpE,MAAM,iBAAiB,GAAG,MAAM,KAAK,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBACjE,OAAO,eAAe,GAAG,iBAAiB,CAAC,CAAC,mBAAmB;aAChE;SACF;QAED,2HAA2H;QAC3H,MAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAChE,IAAI,CAAC,gBAAgB;YAAE,OAAO;QAE9B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/B,iFAAiF;QACjF,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;KAC9D;IAAC,OAAO,CAAM,EAAE;QACf,OAAO,SAAS,CAAC;KAClB;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,QAA2B;IACnE,OAAO,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,OAAO;QACL,IAAI,EAAE,yBAAyB;QAC/B,KAAK,CAAC,EAAE,QAAQ,EAAE;YAChB,MAAM,cAAc,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YACnD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE;gBACpC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;aAC/B;YACD,OAAO;gBACL,cAAc;aACf,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { PipelineResponse } from \"..\";\nimport { parseHeaderValueAsNumber } from \"../util/helpers\";\nimport { RetryStrategy } from \"./retryStrategy\";\n\n/**\n * The header that comes back from services representing\n * the amount of time (minimum) to wait to retry (in seconds or timestamp after which we can retry).\n */\nconst RetryAfterHeader = \"Retry-After\";\n/**\n * The headers that come back from services representing\n * the amount of time (minimum) to wait to retry.\n *\n * \"retry-after-ms\", \"x-ms-retry-after-ms\" : milliseconds\n * \"Retry-After\" : seconds or timestamp\n */\nconst AllRetryAfterHeaders: string[] = [\"retry-after-ms\", \"x-ms-retry-after-ms\", RetryAfterHeader];\n\n/**\n * A response is a throttling retry response if it has a throttling status code (429 or 503),\n * as long as one of the [ \"Retry-After\" or \"retry-after-ms\" or \"x-ms-retry-after-ms\" ] headers has a valid value.\n *\n * Returns the `retryAfterInMs` value if the response is a throttling retry response.\n * If not throttling retry response, returns `undefined`.\n *\n * @internal\n */\nfunction getRetryAfterInMs(response?: PipelineResponse): number | undefined {\n if (!(response && [429, 503].includes(response.status))) return undefined;\n try {\n // Headers: \"retry-after-ms\", \"x-ms-retry-after-ms\", \"Retry-After\"\n for (const header of AllRetryAfterHeaders) {\n const retryAfterValue = parseHeaderValueAsNumber(response, header);\n if (retryAfterValue === 0 || retryAfterValue) {\n // \"Retry-After\" header ==> seconds\n // \"retry-after-ms\", \"x-ms-retry-after-ms\" headers ==> milli-seconds\n const multiplyingFactor = header === RetryAfterHeader ? 1000 : 1;\n return retryAfterValue * multiplyingFactor; // in milli-seconds\n }\n }\n\n // RetryAfterHeader (\"Retry-After\") has a special case where it might be formatted as a date instead of a number of seconds\n const retryAfterHeader = response.headers.get(RetryAfterHeader);\n if (!retryAfterHeader) return;\n\n const date = Date.parse(retryAfterHeader);\n const diff = date - Date.now();\n // negative diff would mean a date in the past, so retry asap with 0 milliseconds\n return Number.isFinite(diff) ? Math.max(0, diff) : undefined;\n } catch (e: any) {\n return undefined;\n }\n}\n\n/**\n * A response is a retry response if it has a throttling status code (429 or 503),\n * as long as one of the [ \"Retry-After\" or \"retry-after-ms\" or \"x-ms-retry-after-ms\" ] headers has a valid value.\n */\nexport function isThrottlingRetryResponse(response?: PipelineResponse): boolean {\n return Number.isFinite(getRetryAfterInMs(response));\n}\n\nexport function throttlingRetryStrategy(): RetryStrategy {\n return {\n name: \"throttlingRetryStrategy\",\n retry({ response }) {\n const retryAfterInMs = getRetryAfterInMs(response);\n if (!Number.isFinite(retryAfterInMs)) {\n return { skipStrategy: true };\n }\n return {\n retryAfterInMs,\n };\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
import { createTracingContext } from "./tracingContext";
|
|
4
|
+
export function createDefaultTracingSpan() {
|
|
5
|
+
return {
|
|
6
|
+
end: () => {
|
|
7
|
+
// noop
|
|
8
|
+
},
|
|
9
|
+
isRecording: () => false,
|
|
10
|
+
recordException: () => {
|
|
11
|
+
// noop
|
|
12
|
+
},
|
|
13
|
+
setAttribute: () => {
|
|
14
|
+
// noop
|
|
15
|
+
},
|
|
16
|
+
setStatus: () => {
|
|
17
|
+
// noop
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function createDefaultInstrumenter() {
|
|
22
|
+
return {
|
|
23
|
+
createRequestHeaders: () => {
|
|
24
|
+
return {};
|
|
25
|
+
},
|
|
26
|
+
parseTraceparentHeader: () => {
|
|
27
|
+
return undefined;
|
|
28
|
+
},
|
|
29
|
+
startSpan: (_name, spanOptions) => {
|
|
30
|
+
return {
|
|
31
|
+
span: createDefaultTracingSpan(),
|
|
32
|
+
tracingContext: createTracingContext({ parentContext: spanOptions.tracingContext }),
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
withContext(_context, callback, ...callbackArgs) {
|
|
36
|
+
return callback(...callbackArgs);
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** @internal */
|
|
41
|
+
let instrumenterImplementation;
|
|
42
|
+
/**
|
|
43
|
+
* Extends the SDK with support for a given instrumenter implementation.
|
|
44
|
+
*
|
|
45
|
+
* @param instrumenter - The instrumenter implementation to use.
|
|
46
|
+
*/
|
|
47
|
+
export function useInstrumenter(instrumenter) {
|
|
48
|
+
instrumenterImplementation = instrumenter;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Gets the currently set instrumenter, a No-Op instrumenter by default.
|
|
52
|
+
*
|
|
53
|
+
* @returns The currently set instrumenter
|
|
54
|
+
*/
|
|
55
|
+
export function getInstrumenter() {
|
|
56
|
+
if (!instrumenterImplementation) {
|
|
57
|
+
instrumenterImplementation = createDefaultInstrumenter();
|
|
58
|
+
}
|
|
59
|
+
return instrumenterImplementation;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=instrumenter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrumenter.js","sourceRoot":"","sources":["../../../src/tracing/instrumenter.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,UAAU,wBAAwB;IACtC,OAAO;QACL,GAAG,EAAE,GAAG,EAAE;YACR,OAAO;QACT,CAAC;QACD,WAAW,EAAE,GAAG,EAAE,CAAC,KAAK;QACxB,eAAe,EAAE,GAAG,EAAE;YACpB,OAAO;QACT,CAAC;QACD,YAAY,EAAE,GAAG,EAAE;YACjB,OAAO;QACT,CAAC;QACD,SAAS,EAAE,GAAG,EAAE;YACd,OAAO;QACT,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB;IACvC,OAAO;QACL,oBAAoB,EAAE,GAA2B,EAAE;YACjD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,sBAAsB,EAAE,GAA+B,EAAE;YACvD,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,SAAS,EAAE,CACT,KAAa,EACb,WAAoC,EACmB,EAAE;YACzD,OAAO;gBACL,IAAI,EAAE,wBAAwB,EAAE;gBAChC,cAAc,EAAE,oBAAoB,CAAC,EAAE,aAAa,EAAE,WAAW,CAAC,cAAc,EAAE,CAAC;aACpF,CAAC;QACJ,CAAC;QACD,WAAW,CAIT,QAAwB,EACxB,QAAkB,EAClB,GAAG,YAA0B;YAE7B,OAAO,QAAQ,CAAC,GAAG,YAAY,CAAC,CAAC;QACnC,CAAC;KACF,CAAC;AACJ,CAAC;AAED,gBAAgB;AAChB,IAAI,0BAAoD,CAAC;AAEzD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,YAA0B;IACxD,0BAA0B,GAAG,YAAY,CAAC;AAC5C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC,0BAA0B,EAAE;QAC/B,0BAA0B,GAAG,yBAAyB,EAAE,CAAC;KAC1D;IACD,OAAO,0BAA0B,CAAC;AACpC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { Instrumenter, InstrumenterSpanOptions, TracingContext, TracingSpan } from \"./interfaces\";\nimport { createTracingContext } from \"./tracingContext\";\n\nexport function createDefaultTracingSpan(): TracingSpan {\n return {\n end: () => {\n // noop\n },\n isRecording: () => false,\n recordException: () => {\n // noop\n },\n setAttribute: () => {\n // noop\n },\n setStatus: () => {\n // noop\n },\n };\n}\n\nexport function createDefaultInstrumenter(): Instrumenter {\n return {\n createRequestHeaders: (): Record<string, string> => {\n return {};\n },\n parseTraceparentHeader: (): TracingContext | undefined => {\n return undefined;\n },\n startSpan: (\n _name: string,\n spanOptions: InstrumenterSpanOptions\n ): { span: TracingSpan; tracingContext: TracingContext } => {\n return {\n span: createDefaultTracingSpan(),\n tracingContext: createTracingContext({ parentContext: spanOptions.tracingContext }),\n };\n },\n withContext<\n CallbackArgs extends unknown[],\n Callback extends (...args: CallbackArgs) => ReturnType<Callback>\n >(\n _context: TracingContext,\n callback: Callback,\n ...callbackArgs: CallbackArgs\n ): ReturnType<Callback> {\n return callback(...callbackArgs);\n },\n };\n}\n\n/** @internal */\nlet instrumenterImplementation: Instrumenter | undefined;\n\n/**\n * Extends the SDK with support for a given instrumenter implementation.\n *\n * @param instrumenter - The instrumenter implementation to use.\n */\nexport function useInstrumenter(instrumenter: Instrumenter): void {\n instrumenterImplementation = instrumenter;\n}\n\n/**\n * Gets the currently set instrumenter, a No-Op instrumenter by default.\n *\n * @returns The currently set instrumenter\n */\nexport function getInstrumenter(): Instrumenter {\n if (!instrumenterImplementation) {\n instrumenterImplementation = createDefaultInstrumenter();\n }\n return instrumenterImplementation;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../../src/tracing/interfaces.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/**\n * A narrower version of TypeScript 4.5's Awaited type which Recursively\n * unwraps the \"awaited type\", emulating the behavior of `await`.\n */\nexport type Resolved<T> = T extends { then(onfulfilled: infer F): any } // `await` only unwraps object types with a callable `then`. Non-object types are not unwrapped\n ? F extends (value: infer V) => any // if the argument to `then` is callable, extracts the first argument\n ? Resolved<V> // recursively unwrap the value\n : never // the argument to `then` was not callable\n : T; // non-object or non-thenable\n\n/**\n * Represents a client that can integrate with the currently configured {@link Instrumenter}.\n *\n * Create an instance using {@link createTracingClient}.\n */\nexport interface TracingClient {\n /**\n * Wraps a callback in a tracing span, calls the callback, and closes the span.\n *\n * This is the primary interface for using Tracing and will handle error recording as well as setting the status on the span.\n *\n * Both synchronous and asynchronous functions will be awaited in order to reflect the result of the callback on the span.\n *\n * Example:\n *\n * ```ts\n * const myOperationResult = await tracingClient.withSpan(\"myClassName.myOperationName\", options, (updatedOptions) => myOperation(updatedOptions));\n * ```\n * @param name - The name of the span. By convention this should be `${className}.${methodName}`.\n * @param operationOptions - The original options passed to the method. The callback will receive these options with the newly created {@link TracingContext}.\n * @param callback - The callback to be invoked with the updated options and newly created {@link TracingSpan}.\n */\n withSpan<\n Options extends { tracingOptions?: OperationTracingOptions },\n Callback extends (\n updatedOptions: Options,\n span: Omit<TracingSpan, \"end\">\n ) => ReturnType<Callback>\n >(\n name: string,\n operationOptions: Options,\n callback: Callback,\n spanOptions?: TracingSpanOptions\n ): Promise<Resolved<ReturnType<Callback>>>;\n /**\n * Starts a given span but does not set it as the active span.\n *\n * You must end the span using {@link TracingSpan.end}.\n *\n * Most of the time you will want to use {@link withSpan} instead.\n *\n * @param name - The name of the span. By convention this should be `${className}.${methodName}`.\n * @param operationOptions - The original operation options.\n * @param spanOptions - The options to use when creating the span.\n *\n * @returns A {@link TracingSpan} and the updated operation options.\n */\n startSpan<Options extends { tracingOptions?: OperationTracingOptions }>(\n name: string,\n operationOptions?: Options,\n spanOptions?: TracingSpanOptions\n ): {\n span: TracingSpan;\n updatedOptions: OptionsWithTracingContext<Options>;\n };\n /**\n * Wraps a callback with an active context and calls the callback.\n * Depending on the implementation, this may set the globally available active context.\n *\n * Useful when you want to leave the boundaries of the SDK (make a request or callback to user code) and are unable to use the {@link withSpan} API.\n *\n * @param context - The {@link TracingContext} to use as the active context in the scope of the callback.\n * @param callback - The callback to be invoked with the given context set as the globally active context.\n * @param callbackArgs - The callback arguments.\n */\n withContext<\n CallbackArgs extends unknown[],\n Callback extends (...args: CallbackArgs) => ReturnType<Callback>\n >(\n context: TracingContext,\n callback: Callback,\n ...callbackArgs: CallbackArgs\n ): ReturnType<Callback>;\n\n /**\n * Parses a traceparent header value into a {@link TracingSpanContext}.\n *\n * @param traceparentHeader - The traceparent header to parse.\n * @returns An implementation-specific identifier for the span.\n */\n parseTraceparentHeader(traceparentHeader: string): TracingContext | undefined;\n\n /**\n * Creates a set of request headers to propagate tracing information to a backend.\n *\n * @param tracingContext - The context containing the span to propagate.\n * @returns The set of headers to add to a request.\n */\n createRequestHeaders(tracingContext?: TracingContext): Record<string, string>;\n}\n\n/**\n * Options that can be passed to {@link createTracingClient}\n */\nexport interface TracingClientOptions {\n /** The value of the az.namespace tracing attribute on newly created spans. */\n namespace: string;\n /** The name of the package invoking this trace. */\n packageName: string;\n /** An optional version of the package invoking this trace. */\n packageVersion?: string;\n}\n\n/** The kind of span. */\nexport type TracingSpanKind = \"client\" | \"server\" | \"producer\" | \"consumer\" | \"internal\";\n\n/** Options used to configure the newly created span. */\nexport interface TracingSpanOptions {\n /** The kind of span. Implementations should default this to \"client\". */\n spanKind?: TracingSpanKind;\n /** A collection of {@link TracingSpanLink} to link to this span. */\n spanLinks?: TracingSpanLink[];\n /** Initial set of attributes to set on a span. */\n spanAttributes?: { [key: string]: unknown };\n}\n\n/** A pointer from the current {@link TracingSpan} to another span in the same or a different trace. */\nexport interface TracingSpanLink {\n /** The {@link TracingContext} containing the span context to link to. */\n tracingContext: TracingContext;\n /** A set of attributes on the link. */\n attributes?: { [key: string]: unknown };\n}\n\n/**\n * Represents an implementation agnostic instrumenter.\n */\nexport interface Instrumenter {\n /**\n * Creates a new {@link TracingSpan} with the given name and options and sets it on a new context.\n * @param name - The name of the span. By convention this should be `${className}.${methodName}`.\n * @param spanOptions - The options to use when creating the span.\n *\n * @returns A {@link TracingSpan} that can be used to end the span, and the context this span has been set on.\n */\n startSpan(\n name: string,\n spanOptions: InstrumenterSpanOptions\n ): { span: TracingSpan; tracingContext: TracingContext };\n /**\n * Wraps a callback with an active context and calls the callback.\n * Depending on the implementation, this may set the globally available active context.\n *\n * @param context - The {@link TracingContext} to use as the active context in the scope of the callback.\n * @param callback - The callback to be invoked with the given context set as the globally active context.\n * @param callbackArgs - The callback arguments.\n */\n withContext<\n CallbackArgs extends unknown[],\n Callback extends (...args: CallbackArgs) => ReturnType<Callback>\n >(\n context: TracingContext,\n callback: Callback,\n ...callbackArgs: CallbackArgs\n ): ReturnType<Callback>;\n\n /**\n * Provides an implementation-specific method to parse a {@link https://www.w3.org/TR/trace-context/#traceparent-header}\n * into a {@link TracingSpanContext} which can be used to link non-parented spans together.\n */\n parseTraceparentHeader(traceparentHeader: string): TracingContext | undefined;\n /**\n * Provides an implementation-specific method to serialize a {@link TracingSpan} to a set of headers.\n * @param tracingContext - The context containing the span to serialize.\n */\n createRequestHeaders(tracingContext?: TracingContext): Record<string, string>;\n}\n\n/**\n * Options passed to {@link Instrumenter.startSpan} as a superset of {@link TracingSpanOptions}.\n */\nexport interface InstrumenterSpanOptions extends TracingSpanOptions {\n /** The name of the package invoking this trace. */\n packageName: string;\n /** The version of the package invoking this trace. */\n packageVersion?: string;\n /** The current tracing context. Defaults to an implementation-specific \"active\" context. */\n tracingContext?: TracingContext;\n}\n\n/**\n * Status representing a successful operation that can be sent to {@link TracingSpan.setStatus}\n */\nexport type SpanStatusSuccess = { status: \"success\" };\n\n/**\n * Status representing an error that can be sent to {@link TracingSpan.setStatus}\n */\nexport type SpanStatusError = { status: \"error\"; error?: Error | string };\n\n/**\n * Represents the statuses that can be passed to {@link TracingSpan.setStatus}.\n *\n * By default, all spans will be created with status \"unset\".\n */\nexport type SpanStatus = SpanStatusSuccess | SpanStatusError;\n\n/**\n * Represents an implementation agnostic tracing span.\n */\nexport interface TracingSpan {\n /**\n * Sets the status of the span. When an error is provided, it will be recorded on the span as well.\n *\n * @param status - The {@link SpanStatus} to set on the span.\n */\n setStatus(status: SpanStatus): void;\n\n /**\n * Sets a given attribute on a span.\n *\n * @param name - The attribute's name.\n * @param value - The attribute's value to set. May be any non-nullish value.\n */\n setAttribute(name: string, value: unknown): void;\n\n /**\n * Ends the span.\n */\n end(): void;\n\n /**\n * Records an exception on a {@link TracingSpan} without modifying its status.\n *\n * When recording an unhandled exception that should fail the span, please use {@link TracingSpan.setStatus} instead.\n *\n * @param exception - The exception to record on the span.\n *\n */\n recordException(exception: Error | string): void;\n\n /**\n * Returns true if this {@link TracingSpan} is recording information.\n *\n * Depending on the span implementation, this may return false if the span is not being sampled.\n */\n isRecording(): boolean;\n}\n\n/** An immutable context bag of tracing values for the current operation. */\nexport interface TracingContext {\n /**\n * Sets a given object on a context.\n * @param key - The key of the given context value.\n * @param value - The value to set on the context.\n *\n * @returns - A new context with the given value set.\n */\n setValue(key: symbol, value: unknown): TracingContext;\n /**\n * Gets an object from the context if it exists.\n * @param key - The key of the given context value.\n *\n * @returns - The value of the given context value if it exists, otherwise `undefined`.\n */\n getValue(key: symbol): unknown;\n /**\n * Deletes an object from the context if it exists.\n * @param key - The key of the given context value to delete.\n */\n deleteValue(key: symbol): TracingContext;\n}\n\n/**\n * Tracing options to set on an operation.\n */\nexport interface OperationTracingOptions {\n /** The context to use for created Tracing Spans. */\n tracingContext?: TracingContext;\n}\n\n/**\n * A utility type for when we know a TracingContext has been set\n * as part of an operation's options.\n */\nexport type OptionsWithTracingContext<\n Options extends { tracingOptions?: OperationTracingOptions }\n> = Options & {\n tracingOptions: {\n tracingContext: TracingContext;\n };\n};\n"]}
|