From 14842d0ef054c2a5f8fc5f6f0af41b7da9a20457 Mon Sep 17 00:00:00 2001 From: KarishmaGhiya Date: Tue, 11 Feb 2020 13:10:29 -0800 Subject: [PATCH 01/13] Removing external dependency edges for graph (#7332) --- README.md | 2 +- eng/tools/analyze-deps/index.js | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 0637a88de42e..44ee88e894a1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Azure SDK for JavaScript -[![Packages](https://img.shields.io/badge/packages-latest-blue.svg)](https://azure.github.io/azure-sdk/releases/latest/js.html) [![Dependencies](https://img.shields.io/badge/dependencies-analyzed-blue.svg)](https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-js/dependencies/dependencies.html)[![DependencyGraph](https://img.shields.io/badge/dependencies-graph-blue.svg)](https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-js/dependencies/InterdependencyGraph.html) +[![Packages](https://img.shields.io/badge/packages-latest-blue.svg)](https://azure.github.io/azure-sdk/releases/latest/js.html) [![Dependencies](https://img.shields.io/badge/dependencies-report-blue.svg)](https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-js/dependencies/dependencies.html) [![DependencyGraph](https://img.shields.io/badge/dependencies-graph-blue.svg)](https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-js/dependencies/InterdependencyGraph.html) This repository is for active development of the Azure SDK for JavaScript (NodeJS & Browser). For consumers of the SDK we recommend visiting our [public developer docs](https://docs.microsoft.com/en-us/javascript/azure/) or our versioned [developer docs](https://azure.github.io/azure-sdk-for-js). diff --git a/eng/tools/analyze-deps/index.js b/eng/tools/analyze-deps/index.js index 4bfd8cff9a6a..67830b11e8d3 100644 --- a/eng/tools/analyze-deps/index.js +++ b/eng/tools/analyze-deps/index.js @@ -158,17 +158,28 @@ const constructDeps = (pkgs) => { return dependencies; }; -const dumpRushPackages = (rushPackages) => { +const dumpRushPackages = (rushPackages, internalPackages, external) => { const dumpData = {}; for (const [pkgName, pkgInfo] of Object.entries(rushPackages)) { - const deps = Object.entries(pkgInfo.run || {}) - .map(([name, version]) => ({ name, version })) + var newDep = []; + if (external) { + newDep = Object.entries(pkgInfo.run || {}) + .map(([name, version]) => ({ name, version })); + } + else { + for (var name in pkgInfo.run) { + if (internalPackages.includes(name)) { + version = pkgInfo.run[name]; + newDep.push({ name, version }) + } + } + } dumpData[`${pkgName}:${pkgInfo.ver}`] = { name: pkgName, version: pkgInfo.ver, type: 'internal', - deps: deps + deps: newDep }; } return dumpData; @@ -305,7 +316,7 @@ const main = async () => { if (args.dump) { const internalPackages = Object.keys(rushPackages); - const dumpData = dumpRushPackages(context.packages); + const dumpData = dumpRushPackages(context.packages, internalPackages, args.external); const pnpmLock = await readPnpmLock(path.resolve(`${__dirname}/../../../common/config/rush/pnpm-lock.yaml`)); for (const pkgId of Object.keys(dumpData)) { resolveRushPackageDeps(dumpData, internalPackages, pnpmLock, pkgId, args.external); From b64f75b10419f67661fd2eceb10d5ee6a0365232 Mon Sep 17 00:00:00 2001 From: Jeremy Meng Date: Tue, 11 Feb 2020 14:12:24 -0800 Subject: [PATCH 02/13] [core-http] support username and password in proxy url string (#7211) by extracting then removing them from the url and parse the updated url as URLBuilder doesn't support them. --- .../core-http/lib/policies/proxyPolicy.ts | 31 +++++++++++++++++-- .../test/policies/proxyPolicyTests.node.ts | 20 ++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/sdk/core/core-http/lib/policies/proxyPolicy.ts b/sdk/core/core-http/lib/policies/proxyPolicy.ts index 6d6924ea4046..538589b23a29 100644 --- a/sdk/core/core-http/lib/policies/proxyPolicy.ts +++ b/sdk/core/core-http/lib/policies/proxyPolicy.ts @@ -39,10 +39,14 @@ export function getDefaultProxySettings(proxyUrl?: string): ProxySettings | unde } } - const parsedUrl = URLBuilder.parse(proxyUrl); + const { username, password, urlWithoutAuth } = extractAuthFromUrl(proxyUrl); + const parsedUrl = URLBuilder.parse(urlWithoutAuth); + const schema = parsedUrl.getScheme() ? parsedUrl.getScheme() + "://" : ""; return { - host: parsedUrl.getScheme() + "://" + parsedUrl.getHost(), - port: Number.parseInt(parsedUrl.getPort() || "80") + host: schema + parsedUrl.getHost(), + port: Number.parseInt(parsedUrl.getPort() || "80"), + username, + password }; } @@ -57,6 +61,27 @@ export function proxyPolicy(proxySettings?: ProxySettings): RequestPolicyFactory }; } +function extractAuthFromUrl(url: string) : { username?: string, password? : string, urlWithoutAuth: string } { + const atIndex = url.indexOf("@"); + if (atIndex === -1) { + return { urlWithoutAuth: url}; + } + + const schemeIndex = url.indexOf("://") + let authStart = schemeIndex !== -1 ? schemeIndex + 3 : 0; + const auth = url.substring(authStart, atIndex); + const colonIndex = auth.indexOf(":"); + const hasPassword = colonIndex !== -1; + const username = hasPassword ? auth.substring(0, colonIndex) : auth + const password = hasPassword ? auth.substring(colonIndex + 1) : undefined; + const urlWithoutAuth = url.substring(0, authStart) + url.substring(atIndex + 1); + return { + username, + password, + urlWithoutAuth + } +} + export class ProxyPolicy extends BaseRequestPolicy { proxySettings: ProxySettings; diff --git a/sdk/core/core-http/test/policies/proxyPolicyTests.node.ts b/sdk/core/core-http/test/policies/proxyPolicyTests.node.ts index b6bdabaeceba..8c2d09a5b598 100644 --- a/sdk/core/core-http/test/policies/proxyPolicyTests.node.ts +++ b/sdk/core/core-http/test/policies/proxyPolicyTests.node.ts @@ -90,6 +90,26 @@ describe("getDefaultProxySettings", () => { proxySettings.port.should.equal(port); }); + [ + { proxyUrl: "prot://user:pass@proxy.microsoft.com", proxyUrlWithoutAuth: "prot://proxy.microsoft.com", username: "user", password: "pass" }, + { proxyUrl: "prot://user@proxy.microsoft.com", proxyUrlWithoutAuth: "prot://proxy.microsoft.com", username: "user", password: undefined }, + { proxyUrl: "prot://:pass@proxy.microsoft.com", proxyUrlWithoutAuth: "prot://proxy.microsoft.com", username: undefined, password: "pass" }, + { proxyUrl: "prot://proxy.microsoft.com", proxyUrlWithoutAuth: "prot://proxy.microsoft.com", username: undefined, password: undefined }, + { proxyUrl: "user:pass@proxy.microsoft.com", proxyUrlWithoutAuth: "proxy.microsoft.com", username: "user", password: "pass" }, + { proxyUrl: "proxy.microsoft.com", proxyUrlWithoutAuth: "proxy.microsoft.com", username: undefined, password: undefined } + ].forEach((testCase) => { + it(`should return settings with passed proxyUrl : ${testCase.proxyUrl}`, () => { + const proxySettings: ProxySettings = getDefaultProxySettings(testCase.proxyUrl)!; + proxySettings.host.should.equal(testCase.proxyUrlWithoutAuth); + if (testCase.username) { + proxySettings.username!.should.equal(testCase.username); + } + if (testCase.password) { + proxySettings.password!.should.equal(testCase.password); + } + }) + }); + describe("with loadEnvironmentProxyValue", () => { beforeEach(() => { delete process.env[Constants.HTTP_PROXY]; From 1d60887d6b03c4639cdc8fe40470f50a2699cf61 Mon Sep 17 00:00:00 2001 From: KarishmaGhiya Date: Tue, 11 Feb 2020 14:17:21 -0800 Subject: [PATCH 03/13] update typedoc (#7347) --- eng/tools/generate-doc/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/tools/generate-doc/package.json b/eng/tools/generate-doc/package.json index 95165da55e54..d5b6ff3efc79 100644 --- a/eng/tools/generate-doc/package.json +++ b/eng/tools/generate-doc/package.json @@ -12,7 +12,7 @@ "fs-extra": "^8.1.0", "js-yaml": "^3.13.1", "nunjucks": "^3.2.0", - "typedoc": "^0.15.0", + "typedoc": "^0.16.9", "yargs": "^11.1.0", "p-limit": "^2.2.1" } From e47e20863558e912647365bbe60c566c32e96c68 Mon Sep 17 00:00:00 2001 From: Jeff Fisher Date: Tue, 11 Feb 2020 15:00:26 -0800 Subject: [PATCH 04/13] [storage] Fix typings support for TypeScript 3.1 (#7350) --- sdk/storage/storage-blob/api-extractor.json | 4 ++-- sdk/storage/storage-blob/package.json | 16 +++++++++++++--- sdk/storage/storage-blob/tsconfig.json | 2 +- .../storage-file-datalake/api-extractor.json | 4 ++-- sdk/storage/storage-file-datalake/package.json | 16 +++++++++++++--- .../storage-file-datalake/tsconfig.json | 2 +- .../storage-file-share/api-extractor.json | 4 ++-- sdk/storage/storage-file-share/package.json | 16 +++++++++++++--- .../review/storage-file-share.api.md | 4 ++-- sdk/storage/storage-file-share/tsconfig.json | 2 +- sdk/storage/storage-queue/api-extractor.json | 4 ++-- sdk/storage/storage-queue/package.json | 18 ++++++++++++++---- sdk/storage/storage-queue/tsconfig.json | 2 +- 13 files changed, 67 insertions(+), 27 deletions(-) diff --git a/sdk/storage/storage-blob/api-extractor.json b/sdk/storage/storage-blob/api-extractor.json index 5a0fde00d976..9d52d2a63383 100644 --- a/sdk/storage/storage-blob/api-extractor.json +++ b/sdk/storage/storage-blob/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "typings/src/index.d.ts", + "mainEntryPointFilePath": "typings/latest/src/index.d.ts", "docModel": { "enabled": false }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./typings/storage-blob.d.ts" + "publicTrimmedFilePath": "./typings/latest/storage-blob.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/storage/storage-blob/package.json b/sdk/storage/storage-blob/package.json index 76847b0c4be2..ef6e9ff41d02 100644 --- a/sdk/storage/storage-blob/package.json +++ b/sdk/storage/storage-blob/package.json @@ -16,18 +16,26 @@ "os": false, "process": false }, - "types": "./typings/src/index.d.ts", + "types": "./typings/latest/src/index.d.ts", + "typesVersions": { + "<3.6": { + "*": [ + "./typings/3.1/src/index.d.ts" + ] + } + }, "engine": { "node": ">=8.0.0" }, "scripts": { "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", "build:autorest": "autorest ./swagger/README.md --typescript --package-version=12.1.0 --use=@microsoft.azure/autorest.typescript@5.0.1", - "build:es6": "tsc -p tsconfig.json", + "build:es6": "tsc -p tsconfig.json && npm run build:types", "build:nodebrowser": "rollup -c 2>&1", "build:samples": "npm run clean && npm run build:es6 && cross-env ONLY_NODE=true rollup -c 2>&1 && npm run build:prep-samples", "build:prep-samples": "node ../../../common/scripts/prep-samples.js && cd samples && tsc", "build:test": "npm run build:es6 && rollup -c rollup.test.config.js 2>&1", + "build:types": "downlevel-dts typings/latest typings/3.1", "build": "npm run build:es6 && npm run build:nodebrowser && api-extractor run --local", "check-format": "prettier --list-different --config ../../.prettierrc.json \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", "clean": "rimraf dist dist-esm dist-test typings temp browser/*.js* browser/*.zip statistics.html coverage coverage-browser .nyc_output *.tgz *.log test*.xml TEST*.xml", @@ -58,7 +66,8 @@ "dist-esm/src/", "LICENSE", "src/", - "typings/src", + "typings/latest/src", + "typings/3.1/src", "tsconfig.json" ], "repository": { @@ -113,6 +122,7 @@ "assert": "^1.4.1", "cross-env": "^6.0.3", "dotenv": "^8.2.0", + "downlevel-dts": "~0.4.0", "es6-promise": "^4.2.5", "eslint": "^6.1.0", "eslint-config-prettier": "^6.0.0", diff --git a/sdk/storage/storage-blob/tsconfig.json b/sdk/storage/storage-blob/tsconfig.json index eace00058c3d..83d57c81c3fb 100644 --- a/sdk/storage/storage-blob/tsconfig.json +++ b/sdk/storage/storage-blob/tsconfig.json @@ -15,7 +15,7 @@ "declaration": true, "declarationMap": true, "importHelpers": true, - "declarationDir": "./typings", + "declarationDir": "./typings/latest", "lib": ["dom", "es5", "es6", "es7", "esnext"], "esModuleInterop": true }, diff --git a/sdk/storage/storage-file-datalake/api-extractor.json b/sdk/storage/storage-file-datalake/api-extractor.json index 49243c1f3d5b..037aedcda142 100644 --- a/sdk/storage/storage-file-datalake/api-extractor.json +++ b/sdk/storage/storage-file-datalake/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "typings/src/index.d.ts", + "mainEntryPointFilePath": "typings/latest/src/index.d.ts", "docModel": { "enabled": false }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./typings/storage-datalake.d.ts" + "publicTrimmedFilePath": "./typings/latest/storage-datalake.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/storage/storage-file-datalake/package.json b/sdk/storage/storage-file-datalake/package.json index 3ee71d6de363..9924677dcdb7 100644 --- a/sdk/storage/storage-file-datalake/package.json +++ b/sdk/storage/storage-file-datalake/package.json @@ -5,7 +5,14 @@ "sdk-type": "client", "main": "./dist/index.js", "module": "./dist-esm/src/index.js", - "types": "./typings/src/index.d.ts", + "types": "./typings/latest/src/index.d.ts", + "typesVersions": { + "<3.6": { + "*": [ + "./typings/3.1/src/index.d.ts" + ] + } + }, "browser": { "./dist-esm/src/index.js": "./dist-esm/src/index.browser.js", "./dist-esm/src/credentials/StorageSharedKeyCredential.js": "./dist-esm/src/credentials/StorageSharedKeyCredential.browser.js", @@ -21,11 +28,12 @@ "scripts": { "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", "build:autorest": "autorest ./swagger/README.md --typescript --use=@microsoft.azure/autorest.typescript@5.0.1", - "build:es6": "tsc -p tsconfig.json", + "build:es6": "tsc -p tsconfig.json && npm run build:types", "build:nodebrowser": "rollup -c 2>&1", "build:js-samples": "npm run clean && npm run build:es6 && cross-env ONLY_NODE=true rollup -c 2>&1", "build:ts-samples": "npm run clean && cd samples && tsc -p . ", "build:test": "npm run build:es6 && rollup -c rollup.test.config.js 2>&1", + "build:types": "downlevel-dts typings/latest typings/3.1", "build": "npm run build:es6 && npm run build:nodebrowser && api-extractor run --local", "check-format": "prettier --list-different --config ../../.prettierrc.json \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", "clean": "rimraf dist dist-esm dist-test typings temp browser/*.js* browser/*.zip statistics.html coverage coverage-browser .nyc_output *.tgz *.log test*.xml TEST*.xml", @@ -52,7 +60,8 @@ "dist-esm/src/", "LICENSE", "src/", - "typings/src", + "typings/latest/src", + "typings/3.1/src", "tsconfig.json" ], "sideEffects": false, @@ -114,6 +123,7 @@ "assert": "^1.4.1", "cross-env": "^6.0.3", "dotenv": "^8.2.0", + "downlevel-dts": "~0.4.0", "es6-promise": "^4.2.5", "eslint": "^6.1.0", "eslint-config-prettier": "^6.0.0", diff --git a/sdk/storage/storage-file-datalake/tsconfig.json b/sdk/storage/storage-file-datalake/tsconfig.json index e271ee388662..91d7c05371eb 100644 --- a/sdk/storage/storage-file-datalake/tsconfig.json +++ b/sdk/storage/storage-file-datalake/tsconfig.json @@ -15,7 +15,7 @@ "declaration": true, "declarationMap": true, "importHelpers": true, - "declarationDir": "./typings", + "declarationDir": "./typings/latest", "lib": ["dom", "es5", "es6", "es7", "esnext"], "esModuleInterop": true }, diff --git a/sdk/storage/storage-file-share/api-extractor.json b/sdk/storage/storage-file-share/api-extractor.json index 1f5821a81707..c4ac2935a186 100644 --- a/sdk/storage/storage-file-share/api-extractor.json +++ b/sdk/storage/storage-file-share/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "typings/src/index.d.ts", + "mainEntryPointFilePath": "typings/latest/src/index.d.ts", "docModel": { "enabled": false }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./typings/storage-file-share.d.ts" + "publicTrimmedFilePath": "./typings/latest/storage-file-share.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/storage/storage-file-share/package.json b/sdk/storage/storage-file-share/package.json index 5e6d7235f4a6..381d85960734 100644 --- a/sdk/storage/storage-file-share/package.json +++ b/sdk/storage/storage-file-share/package.json @@ -15,18 +15,26 @@ "os": false, "process": false }, - "types": "./typings/src/index.d.ts", + "types": "./typings/latest/src/index.d.ts", + "typesVersions": { + "<3.6": { + "*": [ + "./typings/3.1/src/index.d.ts" + ] + } + }, "engine": { "node": ">=8.0.0" }, "scripts": { "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", "build:autorest": "autorest ./swagger/README.md --typescript --package-version=12.1.0 --use=@microsoft.azure/autorest.typescript@5.0.1", - "build:es6": "tsc -p tsconfig.json", + "build:es6": "tsc -p tsconfig.json && npm run build:types", "build:nodebrowser": "rollup -c 2>&1", "build:samples": "npm run clean && npm run build:es6 && cross-env ONLY_NODE=true rollup -c 2>&1 && npm run build:prep-samples", "build:prep-samples": "node ../../../common/scripts/prep-samples.js && cd samples && tsc", "build:test": "npm run build:es6 && rollup -c rollup.test.config.js 2>&1", + "build:types": "downlevel-dts typings/latest typings/3.1", "build": "npm run build:es6 && npm run build:nodebrowser && api-extractor run --local", "check-format": "prettier --list-different --config ../../.prettierrc.json \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", "clean": "rimraf dist dist-esm dist-test typings temp browser/*.js* browser/*.zip statistics.html coverage coverage-browser .nyc_output *.tgz *.log test*.xml TEST*.xml", @@ -57,7 +65,8 @@ "dist-esm/src/", "LICENSE", "src/", - "typings/src", + "typings/latest/src", + "typings/3.1/src", "tsconfig.json" ], "repository": { @@ -116,6 +125,7 @@ "assert": "^1.4.1", "cross-env": "^6.0.3", "dotenv": "^8.2.0", + "downlevel-dts": "~0.4.0", "es6-promise": "^4.2.5", "eslint": "^6.1.0", "eslint-config-prettier": "^6.0.0", diff --git a/sdk/storage/storage-file-share/review/storage-file-share.api.md b/sdk/storage/storage-file-share/review/storage-file-share.api.md index 9386ba426afa..ab14fc2fe7c4 100644 --- a/sdk/storage/storage-file-share/review/storage-file-share.api.md +++ b/sdk/storage/storage-file-share/review/storage-file-share.api.md @@ -1186,9 +1186,9 @@ export class ShareLeaseClient { acquireLease(duration?: number, options?: LeaseOperationOptions): Promise; breakLease(options?: LeaseOperationOptions): Promise; changeLease(proposedLeaseId: string, options?: LeaseOperationOptions): Promise; - readonly leaseId: string; + get leaseId(): string; releaseLease(options?: LeaseOperationOptions): Promise; - readonly url: string; + get url(): string; } // @public diff --git a/sdk/storage/storage-file-share/tsconfig.json b/sdk/storage/storage-file-share/tsconfig.json index e271ee388662..91d7c05371eb 100644 --- a/sdk/storage/storage-file-share/tsconfig.json +++ b/sdk/storage/storage-file-share/tsconfig.json @@ -15,7 +15,7 @@ "declaration": true, "declarationMap": true, "importHelpers": true, - "declarationDir": "./typings", + "declarationDir": "./typings/latest", "lib": ["dom", "es5", "es6", "es7", "esnext"], "esModuleInterop": true }, diff --git a/sdk/storage/storage-queue/api-extractor.json b/sdk/storage/storage-queue/api-extractor.json index e8123acc7358..97b4304ec111 100644 --- a/sdk/storage/storage-queue/api-extractor.json +++ b/sdk/storage/storage-queue/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "typings/src/index.d.ts", + "mainEntryPointFilePath": "typings/latest/src/index.d.ts", "docModel": { "enabled": false }, @@ -11,7 +11,7 @@ "dtsRollup": { "enabled": true, "untrimmedFilePath": "", - "publicTrimmedFilePath": "./typings/storage-queue.d.ts" + "publicTrimmedFilePath": "./typings/latest/storage-queue.d.ts" }, "messages": { "tsdocMessageReporting": { diff --git a/sdk/storage/storage-queue/package.json b/sdk/storage/storage-queue/package.json index f835ae59313c..ae324389d1da 100644 --- a/sdk/storage/storage-queue/package.json +++ b/sdk/storage/storage-queue/package.json @@ -12,18 +12,26 @@ "os": false, "process": false }, - "types": "./typings/src/index.d.ts", + "types": "./typings/latest/src/index.d.ts", + "typesVersions": { + "<3.6": { + "*": [ + "./typings/3.1/src/index.d.ts" + ] + } + }, "engines": { "node": ">=8.0.0" }, "scripts": { "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", "build:autorest": "autorest ./swagger/README.md --typescript --package-version=12.0.3 --use=@microsoft.azure/autorest.typescript@5.0.1", - "build:es6": "tsc -p tsconfig.json", + "build:es6": "tsc -p tsconfig.json && npm run build:types", "build:nodebrowser": "rollup -c 2>&1", "build:samples": "npm run clean && npm run build:es6 && cross-env ONLY_NODE=true rollup -c 2>&1 && npm run build:prep-samples", "build:prep-samples": "node ../../../common/scripts/prep-samples.js && cd samples && tsc", "build:test": "npm run build:es6 && rollup -c rollup.test.config.js 2>&1", + "build:types": "downlevel-dts typings/latest typings/3.1", "build": "npm run build:es6 && npm run build:nodebrowser && api-extractor run --local", "check-format": "prettier --list-different --config ../../.prettierrc.json \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", "clean": "rimraf dist dist-esm dist-test typings temp browser/*.js* browser/*.zip statistics.html coverage coverage-browser .nyc_output *.tgz *.log test*.xml TEST*.xml", @@ -54,7 +62,8 @@ "dist-esm/src/", "LICENSE", "src/", - "typings/src", + "typings/latest/src", + "typings/3.1/src", "tsconfig.json" ], "repository": { @@ -113,6 +122,7 @@ "assert": "^1.4.1", "cross-env": "^6.0.3", "dotenv": "^8.2.0", + "downlevel-dts": "~0.4.0", "es6-promise": "^4.2.5", "eslint": "^6.1.0", "eslint-config-prettier": "^6.0.0", @@ -151,4 +161,4 @@ "typescript": "~3.7.5", "util": "^0.12.1" } -} \ No newline at end of file +} diff --git a/sdk/storage/storage-queue/tsconfig.json b/sdk/storage/storage-queue/tsconfig.json index e271ee388662..91d7c05371eb 100644 --- a/sdk/storage/storage-queue/tsconfig.json +++ b/sdk/storage/storage-queue/tsconfig.json @@ -15,7 +15,7 @@ "declaration": true, "declarationMap": true, "importHelpers": true, - "declarationDir": "./typings", + "declarationDir": "./typings/latest", "lib": ["dom", "es5", "es6", "es7", "esnext"], "esModuleInterop": true }, From 5848e707e165e6187d5d356f1eea4a58d1462a3a Mon Sep 17 00:00:00 2001 From: Kate Olszewska Date: Tue, 11 Feb 2020 16:21:24 -0800 Subject: [PATCH 05/13] Update root README (#7353) * Update root README - Making it more accessible to people consuming this page on azure.github.io to avoid redirecting to github from docs - Updating the description to point people to the most recent packages * Update README.md --- README.md | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 44ee88e894a1..43674d288728 100644 --- a/README.md +++ b/README.md @@ -10,27 +10,15 @@ For your convenience, each service has a separate set of libraries that you can Each service might have a number of libraries available from each of the following categories: -- [Client - November 2019 Releases](#Client-November-2019-Releases) +- [Client - New Releases](#Client-New-Releases) - [Client - Previous Versions](#Client-Previous-Versions) - [Management](#Management) -### Client: November 2019 Releases +### Client: New Releases New wave of packages that we are announcing as **GA** and several that are currently releasing in **preview** on `npm`. These libraries allow you to use and consume existing resources and interact with them. These libraries share a number of core functionalities found in the Azure Core package such as retries, logging, transport protocols, authentication protocols, etc. Learn more about these libraries by reading [the guidelines](https://azure.github.io/azure-sdk/typescript/guidelines/) that they follow. -The libraries released in the November 2019 GA release: - -- [@azure/storage-blob](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-blob) -- [@azure/storage-queue](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-queue) -- [@azure/keyvault-keys](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/keyvault/keyvault-keys) -- [@azure/keyvault-secrets](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/keyvault/keyvault-secrets) -- [@azure/identity](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/identity/identity) - -The libraries released in the November 2019 preview: -- [@azure/storage-file-share@next](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/storage/storage-file-share) -- [@azure/event-hubs@next](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/eventhub/event-hubs) -- [@azure/keyvault-certificates@next](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/keyvault/keyvault-certificates) -- [@azure/app-configuration@next](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/appconfiguration/app-configuration) +You can find the [most up to date list of all of the new packages on our page](https://azure.github.io/azure-sdk/releases/latest/index.html#javascript-packages) > NOTE: If you need to ensure your code is ready for production use one of the stable, non-preview libraries. From 8c4020efdce34caee5061bf09f66adb55b648a89 Mon Sep 17 00:00:00 2001 From: Steve Faulkner Date: Tue, 11 Feb 2020 18:22:22 -0600 Subject: [PATCH 06/13] [Cosmos] Add support for geospatial indexing and configuration (#7331) --- sdk/cosmosdb/cosmos/CHANGELOG.md | 5 ++++ sdk/cosmosdb/cosmos/package.json | 2 +- .../client/Container/ContainerDefinition.ts | 5 ++++ .../cosmos/src/documents/GeospatialType.ts | 9 +++++++ .../cosmos/src/documents/IndexingPolicy.ts | 26 +++++++++++++++++++ .../cosmos/test/functional/container.spec.ts | 15 +++++++++++ 6 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 sdk/cosmosdb/cosmos/src/documents/GeospatialType.ts diff --git a/sdk/cosmosdb/cosmos/CHANGELOG.md b/sdk/cosmosdb/cosmos/CHANGELOG.md index 3605bdd20364..05a10be85a53 100644 --- a/sdk/cosmosdb/cosmos/CHANGELOG.md +++ b/sdk/cosmosdb/cosmos/CHANGELOG.md @@ -1,5 +1,10 @@ # Release History +## 3.6.0 (2020-2-10) + +- FEATURE: Add support for spatial indexing, bounding boxes, and geospatial configuration +- BUG FIX: Fix bug when passing forceQueryPlan to QueryIterator for non-item resources (#7333) + ## 3.5.4 (2020-1-28) - BUG FIX: Return parsed number instead of string for request charge diff --git a/sdk/cosmosdb/cosmos/package.json b/sdk/cosmosdb/cosmos/package.json index 610aca3f7044..7029763995d9 100644 --- a/sdk/cosmosdb/cosmos/package.json +++ b/sdk/cosmosdb/cosmos/package.json @@ -1,6 +1,6 @@ { "name": "@azure/cosmos", - "version": "3.5.4", + "version": "3.6.0", "description": "Microsoft Azure Cosmos DB Service Node.js SDK for SQL API", "sdk-type": "client", "keywords": [ diff --git a/sdk/cosmosdb/cosmos/src/client/Container/ContainerDefinition.ts b/sdk/cosmosdb/cosmos/src/client/Container/ContainerDefinition.ts index 39ae33194548..0c31e96a721d 100644 --- a/sdk/cosmosdb/cosmos/src/client/Container/ContainerDefinition.ts +++ b/sdk/cosmosdb/cosmos/src/client/Container/ContainerDefinition.ts @@ -3,6 +3,7 @@ import { IndexingPolicy, PartitionKeyDefinition } from "../../documents"; import { ConflictResolutionPolicy } from "../Conflict/ConflictResolutionPolicy"; import { UniqueKeyPolicy } from "./UniqueKeyPolicy"; +import { GeospatialType } from "../../documents/GeospatialType"; export interface ContainerDefinition { /** The id of the container. */ @@ -17,4 +18,8 @@ export interface ContainerDefinition { conflictResolutionPolicy?: ConflictResolutionPolicy; /** Policy for additional keys that must be unique per partition key */ uniqueKeyPolicy?: UniqueKeyPolicy; + /** Geospatial configuration for a collection. Type is set to Geography by default */ + geospatialConfig?: { + type: GeospatialType; + }; } diff --git a/sdk/cosmosdb/cosmos/src/documents/GeospatialType.ts b/sdk/cosmosdb/cosmos/src/documents/GeospatialType.ts new file mode 100644 index 000000000000..3c4125d8ea8d --- /dev/null +++ b/sdk/cosmosdb/cosmos/src/documents/GeospatialType.ts @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +export enum GeospatialType { + /** Represents data in round-earth coordinate system. */ + Geography = "Geography", + /** Represents data in Eucledian(flat) coordinate system. */ + Geometry = "Geometry" +} diff --git a/sdk/cosmosdb/cosmos/src/documents/IndexingPolicy.ts b/sdk/cosmosdb/cosmos/src/documents/IndexingPolicy.ts index a63525a6dbd8..9826dd0929cf 100644 --- a/sdk/cosmosdb/cosmos/src/documents/IndexingPolicy.ts +++ b/sdk/cosmosdb/cosmos/src/documents/IndexingPolicy.ts @@ -10,6 +10,32 @@ export interface IndexingPolicy { includedPaths?: IndexedPath[]; /** An array of {@link IncludedPath} represents the paths to be excluded for indexing. */ excludedPaths?: IndexedPath[]; + spatialIndexes?: SpatialIndex[]; +} + +/* The target data type of a spatial path */ +export enum SpatialType { + LineString = "LineString", + MultiPolygon = "MultiPolygon", + Point = "Point", + Polygon = "Polygon" +} + +export interface SpatialIndex { + /* Path in JSON document to index */ + path: string; + types: SpatialType[]; + /* Bounding box for geometry spatial path */ + boundingBox: { + /* X-coordinate of the lower-left corner of the bounding box. */ + xmin: number; + /* Y-coordinate of the lower-left corner of the bounding box. */ + ymin: number; + /* X-coordinate of the upper-right corner of the bounding box. */ + xmax: number; + /* Y-coordinate of the upper-right corner of the bounding box. */ + ymax: number; + }; } export interface IndexedPath { diff --git a/sdk/cosmosdb/cosmos/test/functional/container.spec.ts b/sdk/cosmosdb/cosmos/test/functional/container.spec.ts index c4835aedc238..647de7c28b44 100644 --- a/sdk/cosmosdb/cosmos/test/functional/container.spec.ts +++ b/sdk/cosmosdb/cosmos/test/functional/container.spec.ts @@ -11,6 +11,8 @@ import { IndexingPolicy, IndexKind } from "../../dist-esm/documents"; +import { SpatialType } from "../../dist-esm/documents/IndexingPolicy"; +import { GeospatialType } from "../../dist-esm/documents/GeospatialType"; import { getTestDatabase, removeAllDatabases } from "../common/TestHelpers"; describe("Containers", function() { @@ -64,6 +66,19 @@ describe("Containers", function() { // Replacing indexing policy is allowed. containerDef.indexingPolicy.indexingMode = IndexingMode.lazy; + containerDef.indexingPolicy.spatialIndexes = [ + { + path: "/region/?", + types: [SpatialType.Polygon], + boundingBox: { + xmin: 0, + ymin: 0, + xmax: 10, + ymax: 10 + } + } + ]; + containerDef.geospatialConfig.type = GeospatialType.Geometry; const { resource: replacedContainer } = await container.replace(containerDef); assert.equal("lazy", replacedContainer.indexingPolicy.indexingMode); From 91f27c8dd33ff2daabcd9c83497db79342e87fd8 Mon Sep 17 00:00:00 2001 From: Azure SDK Bot <53356347+azure-sdk@users.noreply.github.com> Date: Tue, 11 Feb 2020 17:01:06 -0800 Subject: [PATCH 07/13] Increment package version after release of azure-cosmos (#7355) --- sdk/cosmosdb/cosmos/CHANGELOG.md | 3 +++ sdk/cosmosdb/cosmos/package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sdk/cosmosdb/cosmos/CHANGELOG.md b/sdk/cosmosdb/cosmos/CHANGELOG.md index 05a10be85a53..a81060adae8f 100644 --- a/sdk/cosmosdb/cosmos/CHANGELOG.md +++ b/sdk/cosmosdb/cosmos/CHANGELOG.md @@ -1,5 +1,8 @@ # Release History +## 3.6.1 (Unreleased) + + ## 3.6.0 (2020-2-10) - FEATURE: Add support for spatial indexing, bounding boxes, and geospatial configuration diff --git a/sdk/cosmosdb/cosmos/package.json b/sdk/cosmosdb/cosmos/package.json index 7029763995d9..f95d109b1afc 100644 --- a/sdk/cosmosdb/cosmos/package.json +++ b/sdk/cosmosdb/cosmos/package.json @@ -1,6 +1,6 @@ { "name": "@azure/cosmos", - "version": "3.6.0", + "version": "3.6.1", "description": "Microsoft Azure Cosmos DB Service Node.js SDK for SQL API", "sdk-type": "client", "keywords": [ From bdac01417a85688ce850e7f8bcbf3b8c22394edc Mon Sep 17 00:00:00 2001 From: Azure SDK Bot <53356347+azure-sdk@users.noreply.github.com> Date: Tue, 11 Feb 2020 17:01:19 -0800 Subject: [PATCH 08/13] Increment package version after release of azure-event-hubs (#7345) --- sdk/eventhub/event-hubs/CHANGELOG.md | 3 +++ sdk/eventhub/event-hubs/package.json | 2 +- sdk/eventhub/event-hubs/src/util/constants.ts | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sdk/eventhub/event-hubs/CHANGELOG.md b/sdk/eventhub/event-hubs/CHANGELOG.md index 0952d5490869..1318d5685025 100644 --- a/sdk/eventhub/event-hubs/CHANGELOG.md +++ b/sdk/eventhub/event-hubs/CHANGELOG.md @@ -1,5 +1,8 @@ # Release History +## 5.0.2 (Unreleased) + + ## 5.0.1 (2020-02-11) - Fixed a potential issue with deadlock where greedy consumers could diff --git a/sdk/eventhub/event-hubs/package.json b/sdk/eventhub/event-hubs/package.json index f2d2039d6488..03c3fc5cf86f 100644 --- a/sdk/eventhub/event-hubs/package.json +++ b/sdk/eventhub/event-hubs/package.json @@ -1,7 +1,7 @@ { "name": "@azure/event-hubs", "sdk-type": "client", - "version": "5.0.1", + "version": "5.0.2", "description": "Azure Event Hubs SDK for JS.", "author": "Microsoft Corporation", "license": "MIT", diff --git a/sdk/eventhub/event-hubs/src/util/constants.ts b/sdk/eventhub/event-hubs/src/util/constants.ts index 86cebb29f997..57ffc2210ada 100644 --- a/sdk/eventhub/event-hubs/src/util/constants.ts +++ b/sdk/eventhub/event-hubs/src/util/constants.ts @@ -6,5 +6,5 @@ */ export const packageJsonInfo = { name: "@azure/event-hubs", - version: "5.0.1" + version: "5.0.2" }; From cdd72589f1e31d0ea6868d7a0fba248d59bacc43 Mon Sep 17 00:00:00 2001 From: Jeremy Meng Date: Tue, 11 Feb 2020 17:48:15 -0800 Subject: [PATCH 09/13] Shorten timout for storage live tests to 60 minutes (#7292) Even in the case of test timing out the build should be finished under one hour. Shortening the timeout to 60 minutes so we are not wasting build agent resource. --- eng/pipelines/templates/jobs/archetype-sdk-integration.yml | 3 ++- sdk/storage/storage-blob/tests.yml | 1 + sdk/storage/storage-file-datalake/tests.yml | 5 +++-- sdk/storage/storage-file-share/tests.yml | 1 + sdk/storage/storage-queue/tests.yml | 1 + 5 files changed, 8 insertions(+), 3 deletions(-) diff --git a/eng/pipelines/templates/jobs/archetype-sdk-integration.yml b/eng/pipelines/templates/jobs/archetype-sdk-integration.yml index 0b41d234c915..2ffe896b3e3c 100644 --- a/eng/pipelines/templates/jobs/archetype-sdk-integration.yml +++ b/eng/pipelines/templates/jobs/archetype-sdk-integration.yml @@ -5,6 +5,7 @@ parameters: ResourceServiceDirectory: "" EnvVars: {} MaxParallel: 0 + TimeoutInMinutes: 240 Matrix: Linux_Node10: OSVmImage: "ubuntu-16.04" @@ -48,7 +49,7 @@ jobs: pool: vmImage: "$(OSVmImage)" - timeoutInMinutes: 240 + timeoutInMinutes: ${{ parameters.TimeoutInMinutes }} steps: - template: ../steps/common.yml diff --git a/sdk/storage/storage-blob/tests.yml b/sdk/storage/storage-blob/tests.yml index b63d7c1a5b33..cd5387ca81e1 100644 --- a/sdk/storage/storage-blob/tests.yml +++ b/sdk/storage/storage-blob/tests.yml @@ -13,6 +13,7 @@ jobs: parameters: PackageName: "@azure/storage-blob" ResourceServiceDirectory: storage + TimeoutInMinutes: 60 EnvVars: AZURE_CLIENT_ID: $(aad-azure-sdk-test-client-id) AZURE_TENANT_ID: $(aad-azure-sdk-test-tenant-id) diff --git a/sdk/storage/storage-file-datalake/tests.yml b/sdk/storage/storage-file-datalake/tests.yml index 28fb4a6397f9..93093319dd6d 100644 --- a/sdk/storage/storage-file-datalake/tests.yml +++ b/sdk/storage/storage-file-datalake/tests.yml @@ -9,6 +9,7 @@ resources: name: Azure/azure-sdk-tools endpoint: azure jobs: - - template: ../archetype-sdk-tests-storage.yml + - template: ../../../eng/pipelines/templates/jobs/archetype-sdk-integration.yml parameters: - PackageName: "@azure/storage-file-datalake" \ No newline at end of file + PackageName: "@azure/storage-file-datalake" + TimeoutInMinutes: 60 diff --git a/sdk/storage/storage-file-share/tests.yml b/sdk/storage/storage-file-share/tests.yml index 18f916525ec5..9c5283f3e6cf 100644 --- a/sdk/storage/storage-file-share/tests.yml +++ b/sdk/storage/storage-file-share/tests.yml @@ -13,6 +13,7 @@ jobs: parameters: PackageName: "@azure/storage-file-share" ResourceServiceDirectory: storage + TimeoutInMinutes: 60 EnvVars: AZURE_CLIENT_ID: $(aad-azure-sdk-test-client-id) AZURE_TENANT_ID: $(aad-azure-sdk-test-tenant-id) diff --git a/sdk/storage/storage-queue/tests.yml b/sdk/storage/storage-queue/tests.yml index 77681138f793..33e215abd429 100644 --- a/sdk/storage/storage-queue/tests.yml +++ b/sdk/storage/storage-queue/tests.yml @@ -13,6 +13,7 @@ jobs: parameters: PackageName: "@azure/storage-queue" ResourceServiceDirectory: storage + TimeoutInMinutes: 60 Matrix: Linux_Node8: OSVmImage: "ubuntu-16.04" From cf85e5bce9e5a2fc76ad2da3230770bf9dfa9142 Mon Sep 17 00:00:00 2001 From: "openapi-sdkautomation[bot]" <37845953+openapi-sdkautomation[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2020 11:40:40 +0800 Subject: [PATCH 10/13] Generated from 7a434dc02be9f218af645a7e41e602403658e4e2 (#7357) put the latest version to the top --- .../src/dataBoxManagementClientContext.ts | 23 +- sdk/databox/arm-databox/src/models/index.ts | 764 ++++++++++++++- .../arm-databox/src/models/jobsMappers.ts | 3 + sdk/databox/arm-databox/src/models/mappers.ts | 875 +++++++++++++++++- .../arm-databox/src/models/serviceMappers.ts | 33 +- .../arm-databox/src/operations/service.ts | 352 ++++++- 6 files changed, 1978 insertions(+), 72 deletions(-) diff --git a/sdk/databox/arm-databox/src/dataBoxManagementClientContext.ts b/sdk/databox/arm-databox/src/dataBoxManagementClientContext.ts index e935c5d905e8..cda0daa42451 100644 --- a/sdk/databox/arm-databox/src/dataBoxManagementClientContext.ts +++ b/sdk/databox/arm-databox/src/dataBoxManagementClientContext.ts @@ -26,43 +26,36 @@ export class DataBoxManagementClientContext extends msRestAzure.AzureServiceClie * @param subscriptionId The Subscription Id * @param [options] The parameter options */ - constructor( - credentials: msRest.ServiceClientCredentials, - subscriptionId: string, - options?: Models.DataBoxManagementClientOptions - ) { + constructor(credentials: msRest.ServiceClientCredentials, subscriptionId: string, options?: Models.DataBoxManagementClientOptions) { if (credentials == undefined) { - throw new Error("'credentials' cannot be null."); + throw new Error('\'credentials\' cannot be null.'); } if (subscriptionId == undefined) { - throw new Error("'subscriptionId' cannot be null."); + throw new Error('\'subscriptionId\' cannot be null.'); } if (!options) { options = {}; } - if (!options.userAgent) { + if(!options.userAgent) { const defaultUserAgent = msRestAzure.getDefaultUserAgentValue(); options.userAgent = `${packageName}/${packageVersion} ${defaultUserAgent}`; } super(credentials, options); - this.apiVersion = "2018-01-01"; - this.acceptLanguage = "en-US"; + this.apiVersion = '2019-09-01'; + this.acceptLanguage = 'en-US'; this.longRunningOperationRetryTimeout = 30; this.baseUri = options.baseUri || this.baseUri || "https://management.azure.com"; this.requestContentType = "application/json; charset=utf-8"; this.credentials = credentials; this.subscriptionId = subscriptionId; - if (options.acceptLanguage !== null && options.acceptLanguage !== undefined) { + if(options.acceptLanguage !== null && options.acceptLanguage !== undefined) { this.acceptLanguage = options.acceptLanguage; } - if ( - options.longRunningOperationRetryTimeout !== null && - options.longRunningOperationRetryTimeout !== undefined - ) { + if(options.longRunningOperationRetryTimeout !== null && options.longRunningOperationRetryTimeout !== undefined) { this.longRunningOperationRetryTimeout = options.longRunningOperationRetryTimeout; } } diff --git a/sdk/databox/arm-databox/src/models/index.ts b/sdk/databox/arm-databox/src/models/index.ts index 5c5961fa675e..cb6886205c43 100644 --- a/sdk/databox/arm-databox/src/models/index.ts +++ b/sdk/databox/arm-databox/src/models/index.ts @@ -52,6 +52,11 @@ export interface AccountCredentialDetails { * **NOTE: This property will not be serialized. It can only be populated by the server.** */ readonly accountName?: string; + /** + * Data Destination Type. Possible values include: 'StorageAccount', 'ManagedDisk' + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly dataDestinationType?: DataDestinationType; /** * Connection string of the account endpoint to use the account as a storage endpoint on the * device. @@ -115,6 +120,15 @@ export interface ShippingAddress { * Output of the address validation api. */ export interface AddressValidationOutput { + /** + * Error code and message of validation response. + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly error?: ErrorModel; + /** + * Polymorphic Discriminator + */ + validationType: string; /** * The address validation status. Possible values include: 'Valid', 'Invalid', 'Ambiguous' * **NOTE: This property will not be serialized. It can only be populated by the server.** @@ -203,7 +217,7 @@ export interface Sku { } /** - * Map of destination location to service location + * Map of destination location to service location. */ export interface DestinationToServiceLocationMap { /** @@ -381,6 +395,11 @@ export interface CopyProgress { * **NOTE: This property will not be serialized. It can only be populated by the server.** */ readonly storageAccountName?: string; + /** + * Data Destination Type. Possible values include: 'StorageAccount', 'ManagedDisk' + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly dataDestinationType?: DataDestinationType; /** * Id of the account where the data needs to be uploaded. * **NOTE: This property will not be serialized. It can only be populated by the server.** @@ -406,6 +425,99 @@ export interface CopyProgress { * **NOTE: This property will not be serialized. It can only be populated by the server.** */ readonly totalFilesToProcess?: number; + /** + * Number of files not adhering to azure naming conventions which were processed by automatic + * renaming + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly invalidFilesProcessed?: number; + /** + * Total amount of data not adhering to azure naming conventions which were processed by + * automatic renaming + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly invalidFileBytesUploaded?: number; + /** + * Number of folders not adhering to azure naming conventions which were processed by automatic + * renaming + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly renamedContainerCount?: number; + /** + * Number of files which could not be copied + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly filesErroredOut?: number; +} + +/** + * Contains the possible cases for ValidationInputRequest. + */ +export type ValidationInputRequestUnion = ValidationInputRequest | CreateOrderLimitForSubscriptionValidationRequest | DataDestinationDetailsValidationRequest | PreferencesValidationRequest | SkuAvailabilityValidationRequest | SubscriptionIsAllowedToCreateJobValidationRequest | ValidateAddress; + +/** + * Minimum fields that must be present in any type of validation request. + */ +export interface ValidationInputRequest { + /** + * Polymorphic Discriminator + */ + validationType: "ValidationInputRequest"; +} + +/** + * Request to validate create order limit for current subscription. + */ +export interface CreateOrderLimitForSubscriptionValidationRequest { + /** + * Polymorphic Discriminator + */ + validationType: "ValidateCreateOrderLimit"; + /** + * Device type to be used for the job. Possible values include: 'DataBox', 'DataBoxDisk', + * 'DataBoxHeavy' + */ + deviceType: SkuName; +} + +/** + * Contains the possible cases for ValidationInputResponse. + */ +export type ValidationInputResponseUnion = ValidationInputResponse | CreateOrderLimitForSubscriptionValidationResponseProperties | DataDestinationDetailsValidationResponseProperties | PreferencesValidationResponseProperties | SkuAvailabilityValidationResponseProperties | SubscriptionIsAllowedToCreateJobValidationResponseProperties; + +/** + * Minimum properties that should be present in each individual validation response. + */ +export interface ValidationInputResponse { + /** + * Polymorphic Discriminator + */ + validationType: "ValidationInputResponse"; + /** + * Error code and message of validation response. + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly error?: ErrorModel; +} + +/** + * Properties of create order limit for subscription validation response. + */ +export interface CreateOrderLimitForSubscriptionValidationResponseProperties { + /** + * Polymorphic Discriminator + */ + validationType: "ValidateCreateOrderLimit"; + /** + * Error code and message of validation response. + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly error?: ErrorModel; + /** + * Create order limit validation status. Possible values include: 'Valid', 'Invalid', 'Skipped' + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly status?: ValidationStatus; } /** @@ -474,7 +586,8 @@ export interface DataBoxDiskCopyProgress { readonly percentComplete?: number; /** * The Status of the copy. Possible values include: 'NotStarted', 'InProgress', 'Completed', - * 'CompletedWithErrors', 'Failed', 'NotReturned' + * 'CompletedWithErrors', 'Failed', 'NotReturned', 'HardwareError', 'DeviceFormatted', + * 'DeviceMetadataModified', 'StorageAccountNotAccessible', 'UnsupportedData' * **NOTE: This property will not be serialized. It can only be populated by the server.** */ readonly status?: CopyStatus; @@ -496,7 +609,7 @@ export interface JobDetails { /** * The expected size of the data, which needs to be transferred in this job, in terabytes. */ - expectedDataSizeInTeraBytes?: number; + expectedDataSizeInTerabytes?: number; /** * List of stages that run in the job. * **NOTE: This property will not be serialized. It can only be populated by the server.** @@ -561,7 +674,7 @@ export interface DataBoxDiskJobDetails { /** * The expected size of the data, which needs to be transferred in this job, in terabytes. */ - expectedDataSizeInTeraBytes?: number; + expectedDataSizeInTerabytes?: number; /** * List of stages that run in the job. * **NOTE: This property will not be serialized. It can only be populated by the server.** @@ -665,6 +778,10 @@ export interface JobSecrets { * Polymorphic Discriminator */ jobSecretsType: "JobSecrets"; + /** + * Dc Access Security Code for Customer Managed Shipping + */ + dcAccessSecurityCode?: DcAccessSecurityCode; } /** @@ -675,6 +792,10 @@ export interface DataBoxDiskJobSecrets { * Polymorphic Discriminator */ jobSecretsType: "DataBoxDisk"; + /** + * Dc Access Security Code for Customer Managed Shipping + */ + dcAccessSecurityCode?: DcAccessSecurityCode; /** * Contains the list of secrets object for that device. * **NOTE: This property will not be serialized. It can only be populated by the server.** @@ -693,7 +814,7 @@ export interface DataBoxDiskJobSecrets { } /** - * Copy log details for a storage account for DataBoxHeavy + * Copy log details for a storage account for Databox heavy */ export interface DataBoxHeavyAccountCopyLogDetails { /** @@ -713,7 +834,7 @@ export interface DataBoxHeavyAccountCopyLogDetails { } /** - * DataBoxHeavy Device Job Details + * Databox Heavy Device Job Details */ export interface DataBoxHeavyJobDetails { /** @@ -723,7 +844,7 @@ export interface DataBoxHeavyJobDetails { /** * The expected size of the data, which needs to be transferred in this job, in terabytes. */ - expectedDataSizeInTeraBytes?: number; + expectedDataSizeInTerabytes?: number; /** * List of stages that run in the job. * **NOTE: This property will not be serialized. It can only be populated by the server.** @@ -780,10 +901,14 @@ export interface DataBoxHeavyJobDetails { * **NOTE: This property will not be serialized. It can only be populated by the server.** */ readonly copyProgress?: CopyProgress[]; + /** + * Set Device password for unlocking Databox Heavy + */ + devicePassword?: string; } /** - * The secrets related to a DataBoxHeavy. + * The secrets related to a databox heavy. */ export interface DataBoxHeavySecret { /** @@ -814,7 +939,7 @@ export interface DataBoxHeavySecret { } /** - * The secrets related to a DataBoxHeavy job. + * The secrets related to a databox heavy job. */ export interface DataBoxHeavyJobSecrets { /** @@ -822,14 +947,18 @@ export interface DataBoxHeavyJobSecrets { */ jobSecretsType: "DataBoxHeavy"; /** - * Contains the list of secret objects for a DataBoxHeavy job. + * Dc Access Security Code for Customer Managed Shipping + */ + dcAccessSecurityCode?: DcAccessSecurityCode; + /** + * Contains the list of secret objects for a databox heavy job. * **NOTE: This property will not be serialized. It can only be populated by the server.** */ readonly cabinetPodSecrets?: DataBoxHeavySecret[]; } /** - * DataBox Job Details + * Databox Job Details */ export interface DataBoxJobDetails { /** @@ -839,7 +968,7 @@ export interface DataBoxJobDetails { /** * The expected size of the data, which needs to be transferred in this job, in terabytes. */ - expectedDataSizeInTeraBytes?: number; + expectedDataSizeInTerabytes?: number; /** * List of stages that run in the job. * **NOTE: This property will not be serialized. It can only be populated by the server.** @@ -896,6 +1025,10 @@ export interface DataBoxJobDetails { * **NOTE: This property will not be serialized. It can only be populated by the server.** */ readonly copyProgress?: CopyProgress[]; + /** + * Set Device password for unlocking Databox + */ + devicePassword?: string; } /** @@ -930,26 +1063,67 @@ export interface DataBoxSecret { } /** - * The secrets related to a DataBox job. + * The secrets related to a databox job. */ export interface DataboxJobSecrets { /** * Polymorphic Discriminator */ jobSecretsType: "DataBox"; + /** + * Dc Access Security Code for Customer Managed Shipping + */ + dcAccessSecurityCode?: DcAccessSecurityCode; /** * Contains the list of secret objects for a job. */ podSecrets?: DataBoxSecret[]; } +/** + * Contains the possible cases for ScheduleAvailabilityRequest. + */ +export type ScheduleAvailabilityRequestUnion = ScheduleAvailabilityRequest | DataBoxScheduleAvailabilityRequest | DiskScheduleAvailabilityRequest | HeavyScheduleAvailabilityRequest; + +/** + * Request body to get the availability for scheduling orders. + */ +export interface ScheduleAvailabilityRequest { + /** + * Polymorphic Discriminator + */ + skuName: "ScheduleAvailabilityRequest"; + /** + * Location for data transfer. + * For locations check: + * https://management.azure.com/subscriptions/SUBSCRIPTIONID/locations?api-version=2018-01-01 + */ + storageLocation: string; +} + +/** + * Request body to get the availability for scheduling data box orders orders. + */ +export interface DataBoxScheduleAvailabilityRequest { + /** + * Polymorphic Discriminator + */ + skuName: "DataBox"; + /** + * Location for data transfer. + * For locations check: + * https://management.azure.com/subscriptions/SUBSCRIPTIONID/locations?api-version=2018-01-01 + */ + storageLocation: string; +} + /** * Contains the possible cases for DestinationAccountDetails. */ export type DestinationAccountDetailsUnion = DestinationAccountDetails | DestinationManagedDiskDetails | DestinationStorageAccountDetails; /** - * Details of the destination of the data + * Details of the destination storage accounts. */ export interface DestinationAccountDetails { /** @@ -960,6 +1134,63 @@ export interface DestinationAccountDetails { * Arm Id of the destination where the data has to be moved. */ accountId?: string; + /** + * Share password to be shared by all shares in SA. + */ + sharePassword?: string; +} + +/** + * Request to validate data destination details. + */ +export interface DataDestinationDetailsValidationRequest { + /** + * Polymorphic Discriminator + */ + validationType: "ValidateDataDestinationDetails"; + /** + * Destination account details list. + */ + destinationAccountDetails: DestinationAccountDetailsUnion[]; + /** + * Location of stamp or geo. + */ + location: string; +} + +/** + * Properties of data destination details validation response. + */ +export interface DataDestinationDetailsValidationResponseProperties { + /** + * Polymorphic Discriminator + */ + validationType: "ValidateDataDestinationDetails"; + /** + * Error code and message of validation response. + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly error?: ErrorModel; + /** + * Data destination details validation status. Possible values include: 'Valid', 'Invalid', + * 'Skipped' + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly status?: ValidationStatus; +} + +/** + * Dc Access Security code for device. + */ +export interface DcAccessSecurityCode { + /** + * Dc Access Code for dispatching from DC. + */ + forwardDcAccessCode?: string; + /** + * Dc Access code for dropping off at DC. + */ + reverseDcAccessCode?: string; } /** @@ -974,6 +1205,10 @@ export interface DestinationManagedDiskDetails { * Arm Id of the destination where the data has to be moved. */ accountId?: string; + /** + * Share password to be shared by all shares in SA. + */ + sharePassword?: string; /** * Destination Resource Group Id where the Compute disks should be created. */ @@ -996,12 +1231,36 @@ export interface DestinationStorageAccountDetails { * Arm Id of the destination where the data has to be moved. */ accountId?: string; + /** + * Share password to be shared by all shares in SA. + */ + sharePassword?: string; /** * Destination Storage Account Arm Id. */ storageAccountId: string; } +/** + * Request body to get the availability for scheduling disk orders. + */ +export interface DiskScheduleAvailabilityRequest { + /** + * Polymorphic Discriminator + */ + skuName: "DataBoxDisk"; + /** + * Location for data transfer. + * For locations check: + * https://management.azure.com/subscriptions/SUBSCRIPTIONID/locations?api-version=2018-01-01 + */ + storageLocation: string; + /** + * The expected size of the data, which needs to be transferred in this job, in terabytes. + */ + expectedDataSizeInTerabytes: number; +} + /** * Top level error for the job. */ @@ -1018,6 +1277,32 @@ export interface ErrorModel { readonly message?: string; } +/** + * Request body to get the availability for scheduling heavy orders. + */ +export interface HeavyScheduleAvailabilityRequest { + /** + * Polymorphic Discriminator + */ + skuName: "DataBoxHeavy"; + /** + * Location for data transfer. + * For locations check: + * https://management.azure.com/subscriptions/SUBSCRIPTIONID/locations?api-version=2018-01-01 + */ + storageLocation: string; +} + +/** + * Additional delivery info. + */ +export interface JobDeliveryInfo { + /** + * Scheduled date time. + */ + scheduledDateTime?: Date; +} + /** * Job Error Details for providing the information and recommended action. */ @@ -1052,7 +1337,8 @@ export interface JobStages { * Name of the job stage. Possible values include: 'DeviceOrdered', 'DevicePrepared', * 'Dispatched', 'Delivered', 'PickedUp', 'AtAzureDC', 'DataCopy', 'Completed', * 'CompletedWithErrors', 'Cancelled', 'Failed_IssueReportedAtCustomer', - * 'Failed_IssueDetectedAtAzureDC', 'Aborted' + * 'Failed_IssueDetectedAtAzureDC', 'Aborted', 'CompletedWithWarnings', + * 'ReadyToDispatchFromAzureDC', 'ReadyToReceiveAtAzureDC' * **NOTE: This property will not be serialized. It can only be populated by the server.** */ readonly stageName?: StageName; @@ -1105,11 +1391,29 @@ export interface PackageShippingDetails { readonly trackingUrl?: string; } +/** + * Preferences related to the shipment logistics of the sku + */ +export interface TransportPreferences { + /** + * Indicates Shipment Logistics type that the customer preferred. Possible values include: + * 'CustomerManaged', 'MicrosoftManaged' + */ + preferredShipmentType: TransportShipmentTypes; +} + /** * Preferences related to the order */ export interface Preferences { + /** + * Preferred Data Center Region. + */ preferredDataCenterRegion?: string[]; + /** + * Preferences related to the shipment logistics of the sku. + */ + transportPreferences?: TransportPreferences; } /** @@ -1156,7 +1460,8 @@ export interface JobResource extends Resource { * Name of the stage which is in progress. Possible values include: 'DeviceOrdered', * 'DevicePrepared', 'Dispatched', 'Delivered', 'PickedUp', 'AtAzureDC', 'DataCopy', 'Completed', * 'CompletedWithErrors', 'Cancelled', 'Failed_IssueReportedAtCustomer', - * 'Failed_IssueDetectedAtAzureDC', 'Aborted' + * 'Failed_IssueDetectedAtAzureDC', 'Aborted', 'CompletedWithWarnings', + * 'ReadyToDispatchFromAzureDC', 'ReadyToReceiveAtAzureDC' * **NOTE: This property will not be serialized. It can only be populated by the server.** */ readonly status?: StageName; @@ -1179,6 +1484,19 @@ export interface JobResource extends Resource { * **NOTE: This property will not be serialized. It can only be populated by the server.** */ readonly cancellationReason?: string; + /** + * Delivery type of Job. Possible values include: 'NonScheduled', 'Scheduled' + */ + deliveryType?: JobDeliveryType; + /** + * Delivery Info of Job. + */ + deliveryInfo?: JobDeliveryInfo; + /** + * Flag to indicate cancellation of scheduled job. + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly isCancellableWithoutFee?: boolean; /** * Name of the object. * **NOTE: This property will not be serialized. It can only be populated by the server.** @@ -1278,6 +1596,120 @@ export interface Operation { readonly origin?: string; } +/** + * Request to validate preference of transport and data center. + */ +export interface PreferencesValidationRequest { + /** + * Polymorphic Discriminator + */ + validationType: "ValidatePreferences"; + /** + * Preference requested with respect to transport type and data center + */ + preference?: Preferences; + /** + * Device type to be used for the job. Possible values include: 'DataBox', 'DataBoxDisk', + * 'DataBoxHeavy' + */ + deviceType: SkuName; +} + +/** + * Properties of data center and transport preference validation response. + */ +export interface PreferencesValidationResponseProperties { + /** + * Polymorphic Discriminator + */ + validationType: "ValidatePreferences"; + /** + * Error code and message of validation response. + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly error?: ErrorModel; + /** + * Validation status of requested data center and transport. Possible values include: 'Valid', + * 'Invalid', 'Skipped' + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly status?: ValidationStatus; +} + +/** + * Request body to get the transport availability for given sku. + */ +export interface TransportAvailabilityRequest { + /** + * Type of the device. Possible values include: 'DataBox', 'DataBoxDisk', 'DataBoxHeavy' + */ + skuName?: SkuName; +} + +/** + * Request body to get the configuration for the region. + */ +export interface RegionConfigurationRequest { + /** + * Request body to get the availability for scheduling orders. + */ + scheduleAvailabilityRequest?: ScheduleAvailabilityRequestUnion; + /** + * Request body to get the transport availability for given sku. + */ + transportAvailabilityRequest?: TransportAvailabilityRequest; +} + +/** + * Schedule availability response for given sku in a region. + */ +export interface ScheduleAvailabilityResponse { + /** + * List of dates available to schedule + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly availableDates?: Date[] | string[]; +} + +/** + * Transport options availability details for given region. + */ +export interface TransportAvailabilityDetails { + /** + * Transport Shipment Type supported for given region. Possible values include: + * 'CustomerManaged', 'MicrosoftManaged' + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly shipmentType?: TransportShipmentTypes; +} + +/** + * Transport options available for given sku in a region. + */ +export interface TransportAvailabilityResponse { + /** + * List of transport availability details for given region + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly transportAvailabilityDetails?: TransportAvailabilityDetails[]; +} + +/** + * Configuration response specific to a region. + */ +export interface RegionConfigurationResponse { + /** + * Schedule availability for given sku in a region. + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly scheduleAvailabilityResponse?: ScheduleAvailabilityResponse; + /** + * Transport options available for given sku in a region. + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly transportAvailabilityResponse?: TransportAvailabilityResponse; +} + /** * Shipment pick up request details. */ @@ -1314,6 +1746,82 @@ export interface ShipmentPickUpResponse { readonly readyByTime?: Date; } +/** + * Request to validate sku availability. + */ +export interface SkuAvailabilityValidationRequest { + /** + * Polymorphic Discriminator + */ + validationType: "ValidateSkuAvailability"; + /** + * Device type to be used for the job. Possible values include: 'DataBox', 'DataBoxDisk', + * 'DataBoxHeavy' + */ + deviceType: SkuName; + /** + * ISO country code. Country for hardware shipment. For codes check: + * https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements + */ + country: string; + /** + * Location for data transfer. For locations check: + * https://management.azure.com/subscriptions/SUBSCRIPTIONID/locations?api-version=2018-01-01 + */ + location: string; +} + +/** + * Properties of sku availability validation response. + */ +export interface SkuAvailabilityValidationResponseProperties { + /** + * Polymorphic Discriminator + */ + validationType: "ValidateSkuAvailability"; + /** + * Error code and message of validation response. + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly error?: ErrorModel; + /** + * Sku availability validation status. Possible values include: 'Valid', 'Invalid', 'Skipped' + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly status?: ValidationStatus; +} + +/** + * Request to validate subscription permission to create jobs. + */ +export interface SubscriptionIsAllowedToCreateJobValidationRequest { + /** + * Polymorphic Discriminator + */ + validationType: "ValidateSubscriptionIsAllowedToCreateJob"; +} + +/** + * Properties of subscription permission to create job validation response. + */ +export interface SubscriptionIsAllowedToCreateJobValidationResponseProperties { + /** + * Polymorphic Discriminator + */ + validationType: "ValidateSubscriptionIsAllowedToCreateJob"; + /** + * Error code and message of validation response. + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly error?: ErrorModel; + /** + * Validation status of subscription permission to create job. Possible values include: 'Valid', + * 'Invalid', 'Skipped' + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly status?: ValidationStatus; +} + /** * Unencrypted credentials for accessing device. */ @@ -1334,6 +1842,10 @@ export interface UnencryptedCredentials { * The requirements to validate customer address where the device needs to be shipped. */ export interface ValidateAddress { + /** + * Polymorphic Discriminator + */ + validationType: "ValidateAddress"; /** * Shipping address of the customer. */ @@ -1343,6 +1855,61 @@ export interface ValidateAddress { * 'DataBoxHeavy' */ deviceType: SkuName; + /** + * Preferences related to the shipment logistics of the sku. + */ + transportPreferences?: TransportPreferences; +} + +/** + * Contains the possible cases for ValidationRequest. + */ +export type ValidationRequestUnion = ValidationRequest | CreateJobValidations; + +/** + * Input request for all pre job creation validation. + */ +export interface ValidationRequest { + /** + * Polymorphic Discriminator + */ + validationCategory: "ValidationRequest"; + /** + * List of request details contain validationType and its request as key and value respectively. + */ + individualRequestDetails: ValidationInputRequestUnion[]; +} + +/** + * It does all pre-job creation validations. + */ +export interface CreateJobValidations { + /** + * Polymorphic Discriminator + */ + validationCategory: "JobCreationValidation"; + /** + * List of request details contain validationType and its request as key and value respectively. + */ + individualRequestDetails: ValidationInputRequestUnion[]; +} + +/** + * Response of pre job creation validations. + */ +export interface ValidationResponse { + /** + * Overall validation status. Possible values include: 'AllValidToProceed', + * 'InputsRevisitRequired', 'CertainInputValidationsSkipped' + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly status?: OverallValidationStatus; + /** + * List of response details contain validationType and its response as key and value + * respectively. + * **NOTE: This property will not be serialized. It can only be populated by the server.** + */ + readonly individualResponseDetails?: ValidationInputResponseUnion[]; } /** @@ -1397,6 +1964,20 @@ export interface JobsBeginUpdateOptionalParams extends msRest.RequestOptionsBase ifMatch?: string; } +/** + * Optional Parameters. + */ +export interface ServiceRegionConfigurationOptionalParams extends msRest.RequestOptionsBase { + /** + * Request body to get the availability for scheduling orders. + */ + scheduleAvailabilityRequest?: ScheduleAvailabilityRequestUnion; + /** + * Request body to get the transport availability for given sku. + */ + transportAvailabilityRequest?: TransportAvailabilityRequest; +} + /** * An interface representing DataBoxManagementClientOptions. */ @@ -1452,6 +2033,14 @@ export interface AvailableSkusResult extends Array { nextLink?: string; } +/** + * Defines values for DataDestinationType. + * Possible values include: 'StorageAccount', 'ManagedDisk' + * @readonly + * @enum {string} + */ +export type DataDestinationType = 'StorageAccount' | 'ManagedDisk'; + /** * Defines values for ShareDestinationFormatType. * Possible values include: 'UnknownType', 'HCS', 'BlockBlob', 'PageBlob', 'AzureFile', @@ -1511,24 +2100,34 @@ export type SkuDisabledReason = 'None' | 'Country' | 'Region' | 'Feature' | 'Off */ export type NotificationStageName = 'DevicePrepared' | 'Dispatched' | 'Delivered' | 'PickedUp' | 'AtAzureDC' | 'DataCopy'; +/** + * Defines values for ValidationStatus. + * Possible values include: 'Valid', 'Invalid', 'Skipped' + * @readonly + * @enum {string} + */ +export type ValidationStatus = 'Valid' | 'Invalid' | 'Skipped'; + /** * Defines values for CopyStatus. * Possible values include: 'NotStarted', 'InProgress', 'Completed', 'CompletedWithErrors', - * 'Failed', 'NotReturned' + * 'Failed', 'NotReturned', 'HardwareError', 'DeviceFormatted', 'DeviceMetadataModified', + * 'StorageAccountNotAccessible', 'UnsupportedData' * @readonly * @enum {string} */ -export type CopyStatus = 'NotStarted' | 'InProgress' | 'Completed' | 'CompletedWithErrors' | 'Failed' | 'NotReturned'; +export type CopyStatus = 'NotStarted' | 'InProgress' | 'Completed' | 'CompletedWithErrors' | 'Failed' | 'NotReturned' | 'HardwareError' | 'DeviceFormatted' | 'DeviceMetadataModified' | 'StorageAccountNotAccessible' | 'UnsupportedData'; /** * Defines values for StageName. * Possible values include: 'DeviceOrdered', 'DevicePrepared', 'Dispatched', 'Delivered', * 'PickedUp', 'AtAzureDC', 'DataCopy', 'Completed', 'CompletedWithErrors', 'Cancelled', - * 'Failed_IssueReportedAtCustomer', 'Failed_IssueDetectedAtAzureDC', 'Aborted' + * 'Failed_IssueReportedAtCustomer', 'Failed_IssueDetectedAtAzureDC', 'Aborted', + * 'CompletedWithWarnings', 'ReadyToDispatchFromAzureDC', 'ReadyToReceiveAtAzureDC' * @readonly * @enum {string} */ -export type StageName = 'DeviceOrdered' | 'DevicePrepared' | 'Dispatched' | 'Delivered' | 'PickedUp' | 'AtAzureDC' | 'DataCopy' | 'Completed' | 'CompletedWithErrors' | 'Cancelled' | 'Failed_IssueReportedAtCustomer' | 'Failed_IssueDetectedAtAzureDC' | 'Aborted'; +export type StageName = 'DeviceOrdered' | 'DevicePrepared' | 'Dispatched' | 'Delivered' | 'PickedUp' | 'AtAzureDC' | 'DataCopy' | 'Completed' | 'CompletedWithErrors' | 'Cancelled' | 'Failed_IssueReportedAtCustomer' | 'Failed_IssueDetectedAtAzureDC' | 'Aborted' | 'CompletedWithWarnings' | 'ReadyToDispatchFromAzureDC' | 'ReadyToReceiveAtAzureDC'; /** * Defines values for StageStatus. @@ -1539,6 +2138,31 @@ export type StageName = 'DeviceOrdered' | 'DevicePrepared' | 'Dispatched' | 'Del */ export type StageStatus = 'None' | 'InProgress' | 'Succeeded' | 'Failed' | 'Cancelled' | 'Cancelling' | 'SucceededWithErrors'; +/** + * Defines values for TransportShipmentTypes. + * Possible values include: 'CustomerManaged', 'MicrosoftManaged' + * @readonly + * @enum {string} + */ +export type TransportShipmentTypes = 'CustomerManaged' | 'MicrosoftManaged'; + +/** + * Defines values for JobDeliveryType. + * Possible values include: 'NonScheduled', 'Scheduled' + * @readonly + * @enum {string} + */ +export type JobDeliveryType = 'NonScheduled' | 'Scheduled'; + +/** + * Defines values for OverallValidationStatus. + * Possible values include: 'AllValidToProceed', 'InputsRevisitRequired', + * 'CertainInputValidationsSkipped' + * @readonly + * @enum {string} + */ +export type OverallValidationStatus = 'AllValidToProceed' | 'InputsRevisitRequired' | 'CertainInputValidationsSkipped'; + /** * Contains response data for the list operation. */ @@ -1819,6 +2443,26 @@ export type ServiceListAvailableSkusResponse = AvailableSkusResult & { }; }; +/** + * Contains response data for the listAvailableSkusByResourceGroup operation. + */ +export type ServiceListAvailableSkusByResourceGroupResponse = AvailableSkusResult & { + /** + * The underlying HTTP response. + */ + _response: msRest.HttpResponse & { + /** + * The response body as text (string format) + */ + bodyAsText: string; + + /** + * The response body as parsed JSON or XML + */ + parsedBody: AvailableSkusResult; + }; +}; + /** * Contains response data for the validateAddressMethod operation. */ @@ -1839,6 +2483,66 @@ export type ServiceValidateAddressMethodResponse = AddressValidationOutput & { }; }; +/** + * Contains response data for the validateInputsByResourceGroup operation. + */ +export type ServiceValidateInputsByResourceGroupResponse = ValidationResponse & { + /** + * The underlying HTTP response. + */ + _response: msRest.HttpResponse & { + /** + * The response body as text (string format) + */ + bodyAsText: string; + + /** + * The response body as parsed JSON or XML + */ + parsedBody: ValidationResponse; + }; +}; + +/** + * Contains response data for the validateInputs operation. + */ +export type ServiceValidateInputsResponse = ValidationResponse & { + /** + * The underlying HTTP response. + */ + _response: msRest.HttpResponse & { + /** + * The response body as text (string format) + */ + bodyAsText: string; + + /** + * The response body as parsed JSON or XML + */ + parsedBody: ValidationResponse; + }; +}; + +/** + * Contains response data for the regionConfiguration operation. + */ +export type ServiceRegionConfigurationResponse = RegionConfigurationResponse & { + /** + * The underlying HTTP response. + */ + _response: msRest.HttpResponse & { + /** + * The response body as text (string format) + */ + bodyAsText: string; + + /** + * The response body as parsed JSON or XML + */ + parsedBody: RegionConfigurationResponse; + }; +}; + /** * Contains response data for the listAvailableSkusNext operation. */ @@ -1858,3 +2562,23 @@ export type ServiceListAvailableSkusNextResponse = AvailableSkusResult & { parsedBody: AvailableSkusResult; }; }; + +/** + * Contains response data for the listAvailableSkusByResourceGroupNext operation. + */ +export type ServiceListAvailableSkusByResourceGroupNextResponse = AvailableSkusResult & { + /** + * The underlying HTTP response. + */ + _response: msRest.HttpResponse & { + /** + * The response body as text (string format) + */ + bodyAsText: string; + + /** + * The response body as parsed JSON or XML + */ + parsedBody: AvailableSkusResult; + }; +}; diff --git a/sdk/databox/arm-databox/src/models/jobsMappers.ts b/sdk/databox/arm-databox/src/models/jobsMappers.ts index fc490ebc3d3a..5aa3a445167f 100644 --- a/sdk/databox/arm-databox/src/models/jobsMappers.ts +++ b/sdk/databox/arm-databox/src/models/jobsMappers.ts @@ -28,11 +28,13 @@ export { DataBoxJobDetails, DataboxJobSecrets, DataBoxSecret, + DcAccessSecurityCode, DestinationAccountDetails, DestinationManagedDiskDetails, DestinationStorageAccountDetails, DiskSecret, ErrorModel, + JobDeliveryInfo, JobDetails, JobErrorDetails, JobResource, @@ -49,6 +51,7 @@ export { ShipmentPickUpResponse, ShippingAddress, Sku, + TransportPreferences, UnencryptedCredentials, UnencryptedCredentialsList, UpdateJobDetails diff --git a/sdk/databox/arm-databox/src/models/mappers.ts b/sdk/databox/arm-databox/src/models/mappers.ts index e76fec82570c..b8820e4085a4 100644 --- a/sdk/databox/arm-databox/src/models/mappers.ts +++ b/sdk/databox/arm-databox/src/models/mappers.ts @@ -87,6 +87,17 @@ export const AccountCredentialDetails: msRest.CompositeMapper = { name: "String" } }, + dataDestinationType: { + readOnly: true, + serializedName: "dataDestinationType", + type: { + name: "Enum", + allowedValues: [ + "StorageAccount", + "ManagedDisk" + ] + } + }, accountConnectionString: { readOnly: true, serializedName: "accountConnectionString", @@ -195,6 +206,21 @@ export const AddressValidationOutput: msRest.CompositeMapper = { name: "Composite", className: "AddressValidationOutput", modelProperties: { + error: { + readOnly: true, + serializedName: "properties.error", + type: { + name: "Composite", + className: "ErrorModel" + } + }, + validationType: { + required: true, + serializedName: "properties.validationType", + type: { + name: "String" + } + }, validationStatus: { readOnly: true, serializedName: "properties.validationStatus", @@ -678,6 +704,17 @@ export const CopyProgress: msRest.CompositeMapper = { name: "String" } }, + dataDestinationType: { + readOnly: true, + serializedName: "dataDestinationType", + type: { + name: "Enum", + allowedValues: [ + "StorageAccount", + "ManagedDisk" + ] + } + }, accountId: { readOnly: true, serializedName: "accountId", @@ -712,6 +749,136 @@ export const CopyProgress: msRest.CompositeMapper = { type: { name: "Number" } + }, + invalidFilesProcessed: { + readOnly: true, + serializedName: "invalidFilesProcessed", + type: { + name: "Number" + } + }, + invalidFileBytesUploaded: { + readOnly: true, + serializedName: "invalidFileBytesUploaded", + type: { + name: "Number" + } + }, + renamedContainerCount: { + readOnly: true, + serializedName: "renamedContainerCount", + type: { + name: "Number" + } + }, + filesErroredOut: { + readOnly: true, + serializedName: "filesErroredOut", + type: { + name: "Number" + } + } + } + } +}; + +export const ValidationInputRequest: msRest.CompositeMapper = { + serializedName: "ValidationInputRequest", + type: { + name: "Composite", + polymorphicDiscriminator: { + serializedName: "validationType", + clientName: "validationType" + }, + uberParent: "ValidationInputRequest", + className: "ValidationInputRequest", + modelProperties: { + validationType: { + required: true, + serializedName: "validationType", + type: { + name: "String" + } + } + } + } +}; + +export const CreateOrderLimitForSubscriptionValidationRequest: msRest.CompositeMapper = { + serializedName: "ValidateCreateOrderLimit", + type: { + name: "Composite", + polymorphicDiscriminator: ValidationInputRequest.type.polymorphicDiscriminator, + uberParent: "ValidationInputRequest", + className: "CreateOrderLimitForSubscriptionValidationRequest", + modelProperties: { + ...ValidationInputRequest.type.modelProperties, + deviceType: { + required: true, + serializedName: "deviceType", + type: { + name: "Enum", + allowedValues: [ + "DataBox", + "DataBoxDisk", + "DataBoxHeavy" + ] + } + } + } + } +}; + +export const ValidationInputResponse: msRest.CompositeMapper = { + serializedName: "ValidationInputResponse", + type: { + name: "Composite", + polymorphicDiscriminator: { + serializedName: "validationType", + clientName: "validationType" + }, + uberParent: "ValidationInputResponse", + className: "ValidationInputResponse", + modelProperties: { + error: { + readOnly: true, + serializedName: "error", + type: { + name: "Composite", + className: "ErrorModel" + } + }, + validationType: { + required: true, + serializedName: "validationType", + type: { + name: "String" + } + } + } + } +}; + +export const CreateOrderLimitForSubscriptionValidationResponseProperties: msRest.CompositeMapper = { + serializedName: "ValidateCreateOrderLimit", + type: { + name: "Composite", + polymorphicDiscriminator: ValidationInputResponse.type.polymorphicDiscriminator, + uberParent: "ValidationInputResponse", + className: "CreateOrderLimitForSubscriptionValidationResponseProperties", + modelProperties: { + ...ValidationInputResponse.type.modelProperties, + status: { + readOnly: true, + serializedName: "status", + type: { + name: "Enum", + allowedValues: [ + "Valid", + "Invalid", + "Skipped" + ] + } } } } @@ -816,7 +983,12 @@ export const DataBoxDiskCopyProgress: msRest.CompositeMapper = { "Completed", "CompletedWithErrors", "Failed", - "NotReturned" + "NotReturned", + "HardwareError", + "DeviceFormatted", + "DeviceMetadataModified", + "StorageAccountNotAccessible", + "UnsupportedData" ] } } @@ -835,8 +1007,8 @@ export const JobDetails: msRest.CompositeMapper = { uberParent: "JobDetails", className: "JobDetails", modelProperties: { - expectedDataSizeInTeraBytes: { - serializedName: "expectedDataSizeInTeraBytes", + expectedDataSizeInTerabytes: { + serializedName: "expectedDataSizeInTerabytes", type: { name: "Number" } @@ -1047,6 +1219,13 @@ export const JobSecrets: msRest.CompositeMapper = { uberParent: "JobSecrets", className: "JobSecrets", modelProperties: { + dcAccessSecurityCode: { + serializedName: "dcAccessSecurityCode", + type: { + name: "Composite", + className: "DcAccessSecurityCode" + } + }, jobSecretsType: { required: true, serializedName: "jobSecretsType", @@ -1151,6 +1330,12 @@ export const DataBoxHeavyJobDetails: msRest.CompositeMapper = { } } } + }, + devicePassword: { + serializedName: "devicePassword", + type: { + name: "String" + } } } } @@ -1260,6 +1445,12 @@ export const DataBoxJobDetails: msRest.CompositeMapper = { } } } + }, + devicePassword: { + serializedName: "devicePassword", + type: { + name: "String" + } } } } @@ -1347,6 +1538,48 @@ export const DataboxJobSecrets: msRest.CompositeMapper = { } }; +export const ScheduleAvailabilityRequest: msRest.CompositeMapper = { + serializedName: "ScheduleAvailabilityRequest", + type: { + name: "Composite", + polymorphicDiscriminator: { + serializedName: "skuName", + clientName: "skuName" + }, + uberParent: "ScheduleAvailabilityRequest", + className: "ScheduleAvailabilityRequest", + modelProperties: { + storageLocation: { + required: true, + serializedName: "storageLocation", + type: { + name: "String" + } + }, + skuName: { + required: true, + serializedName: "skuName", + type: { + name: "String" + } + } + } + } +}; + +export const DataBoxScheduleAvailabilityRequest: msRest.CompositeMapper = { + serializedName: "DataBox", + type: { + name: "Composite", + polymorphicDiscriminator: ScheduleAvailabilityRequest.type.polymorphicDiscriminator, + uberParent: "ScheduleAvailabilityRequest", + className: "DataBoxScheduleAvailabilityRequest", + modelProperties: { + ...ScheduleAvailabilityRequest.type.modelProperties + } + } +}; + export const DestinationAccountDetails: msRest.CompositeMapper = { serializedName: "DestinationAccountDetails", type: { @@ -1364,6 +1597,12 @@ export const DestinationAccountDetails: msRest.CompositeMapper = { name: "String" } }, + sharePassword: { + serializedName: "sharePassword", + type: { + name: "String" + } + }, dataDestinationType: { required: true, serializedName: "dataDestinationType", @@ -1375,6 +1614,86 @@ export const DestinationAccountDetails: msRest.CompositeMapper = { } }; +export const DataDestinationDetailsValidationRequest: msRest.CompositeMapper = { + serializedName: "ValidateDataDestinationDetails", + type: { + name: "Composite", + polymorphicDiscriminator: ValidationInputRequest.type.polymorphicDiscriminator, + uberParent: "ValidationInputRequest", + className: "DataDestinationDetailsValidationRequest", + modelProperties: { + ...ValidationInputRequest.type.modelProperties, + destinationAccountDetails: { + required: true, + serializedName: "destinationAccountDetails", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "DestinationAccountDetails" + } + } + } + }, + location: { + required: true, + serializedName: "location", + type: { + name: "String" + } + } + } + } +}; + +export const DataDestinationDetailsValidationResponseProperties: msRest.CompositeMapper = { + serializedName: "ValidateDataDestinationDetails", + type: { + name: "Composite", + polymorphicDiscriminator: ValidationInputResponse.type.polymorphicDiscriminator, + uberParent: "ValidationInputResponse", + className: "DataDestinationDetailsValidationResponseProperties", + modelProperties: { + ...ValidationInputResponse.type.modelProperties, + status: { + readOnly: true, + serializedName: "status", + type: { + name: "Enum", + allowedValues: [ + "Valid", + "Invalid", + "Skipped" + ] + } + } + } + } +}; + +export const DcAccessSecurityCode: msRest.CompositeMapper = { + serializedName: "DcAccessSecurityCode", + type: { + name: "Composite", + className: "DcAccessSecurityCode", + modelProperties: { + forwardDcAccessCode: { + serializedName: "forwardDcAccessCode", + type: { + name: "String" + } + }, + reverseDcAccessCode: { + serializedName: "reverseDcAccessCode", + type: { + name: "String" + } + } + } + } +}; + export const DestinationManagedDiskDetails: msRest.CompositeMapper = { serializedName: "ManagedDisk", type: { @@ -1422,6 +1741,26 @@ export const DestinationStorageAccountDetails: msRest.CompositeMapper = { } }; +export const DiskScheduleAvailabilityRequest: msRest.CompositeMapper = { + serializedName: "DataBoxDisk", + type: { + name: "Composite", + polymorphicDiscriminator: ScheduleAvailabilityRequest.type.polymorphicDiscriminator, + uberParent: "ScheduleAvailabilityRequest", + className: "DiskScheduleAvailabilityRequest", + modelProperties: { + ...ScheduleAvailabilityRequest.type.modelProperties, + expectedDataSizeInTerabytes: { + required: true, + serializedName: "expectedDataSizeInTerabytes", + type: { + name: "Number" + } + } + } + } +}; + export const ErrorModel: msRest.CompositeMapper = { serializedName: "Error", type: { @@ -1446,19 +1785,48 @@ export const ErrorModel: msRest.CompositeMapper = { } }; -export const JobErrorDetails: msRest.CompositeMapper = { - serializedName: "JobErrorDetails", +export const HeavyScheduleAvailabilityRequest: msRest.CompositeMapper = { + serializedName: "DataBoxHeavy", type: { name: "Composite", - className: "JobErrorDetails", + polymorphicDiscriminator: ScheduleAvailabilityRequest.type.polymorphicDiscriminator, + uberParent: "ScheduleAvailabilityRequest", + className: "HeavyScheduleAvailabilityRequest", modelProperties: { - errorMessage: { - readOnly: true, - serializedName: "errorMessage", - type: { - name: "String" - } - }, + ...ScheduleAvailabilityRequest.type.modelProperties + } + } +}; + +export const JobDeliveryInfo: msRest.CompositeMapper = { + serializedName: "JobDeliveryInfo", + type: { + name: "Composite", + className: "JobDeliveryInfo", + modelProperties: { + scheduledDateTime: { + serializedName: "scheduledDateTime", + type: { + name: "DateTime" + } + } + } + } +}; + +export const JobErrorDetails: msRest.CompositeMapper = { + serializedName: "JobErrorDetails", + type: { + name: "Composite", + className: "JobErrorDetails", + modelProperties: { + errorMessage: { + readOnly: true, + serializedName: "errorMessage", + type: { + name: "String" + } + }, errorCode: { readOnly: true, serializedName: "errorCode", @@ -1508,7 +1876,10 @@ export const JobStages: msRest.CompositeMapper = { "Cancelled", "Failed_IssueReportedAtCustomer", "Failed_IssueDetectedAtAzureDC", - "Aborted" + "Aborted", + "CompletedWithWarnings", + "ReadyToDispatchFromAzureDC", + "ReadyToReceiveAtAzureDC" ] } }, @@ -1597,6 +1968,27 @@ export const PackageShippingDetails: msRest.CompositeMapper = { } }; +export const TransportPreferences: msRest.CompositeMapper = { + serializedName: "TransportPreferences", + type: { + name: "Composite", + className: "TransportPreferences", + modelProperties: { + preferredShipmentType: { + required: true, + serializedName: "preferredShipmentType", + type: { + name: "Enum", + allowedValues: [ + "CustomerManaged", + "MicrosoftManaged" + ] + } + } + } + } +}; + export const Preferences: msRest.CompositeMapper = { serializedName: "Preferences", type: { @@ -1613,6 +2005,13 @@ export const Preferences: msRest.CompositeMapper = { } } } + }, + transportPreferences: { + serializedName: "transportPreferences", + type: { + name: "Composite", + className: "TransportPreferences" + } } } } @@ -1700,7 +2099,10 @@ export const JobResource: msRest.CompositeMapper = { "Cancelled", "Failed_IssueReportedAtCustomer", "Failed_IssueDetectedAtAzureDC", - "Aborted" + "Aborted", + "CompletedWithWarnings", + "ReadyToDispatchFromAzureDC", + "ReadyToReceiveAtAzureDC" ] } }, @@ -1733,6 +2135,30 @@ export const JobResource: msRest.CompositeMapper = { name: "String" } }, + deliveryType: { + serializedName: "properties.deliveryType", + type: { + name: "Enum", + allowedValues: [ + "NonScheduled", + "Scheduled" + ] + } + }, + deliveryInfo: { + serializedName: "properties.deliveryInfo", + type: { + name: "Composite", + className: "JobDeliveryInfo" + } + }, + isCancellableWithoutFee: { + readOnly: true, + serializedName: "properties.isCancellableWithoutFee", + type: { + name: "Boolean" + } + }, name: { readOnly: true, serializedName: "name", @@ -1895,6 +2321,200 @@ export const Operation: msRest.CompositeMapper = { } }; +export const PreferencesValidationRequest: msRest.CompositeMapper = { + serializedName: "ValidatePreferences", + type: { + name: "Composite", + polymorphicDiscriminator: ValidationInputRequest.type.polymorphicDiscriminator, + uberParent: "ValidationInputRequest", + className: "PreferencesValidationRequest", + modelProperties: { + ...ValidationInputRequest.type.modelProperties, + preference: { + serializedName: "preference", + type: { + name: "Composite", + className: "Preferences" + } + }, + deviceType: { + required: true, + serializedName: "deviceType", + type: { + name: "Enum", + allowedValues: [ + "DataBox", + "DataBoxDisk", + "DataBoxHeavy" + ] + } + } + } + } +}; + +export const PreferencesValidationResponseProperties: msRest.CompositeMapper = { + serializedName: "ValidatePreferences", + type: { + name: "Composite", + polymorphicDiscriminator: ValidationInputResponse.type.polymorphicDiscriminator, + uberParent: "ValidationInputResponse", + className: "PreferencesValidationResponseProperties", + modelProperties: { + ...ValidationInputResponse.type.modelProperties, + status: { + readOnly: true, + serializedName: "status", + type: { + name: "Enum", + allowedValues: [ + "Valid", + "Invalid", + "Skipped" + ] + } + } + } + } +}; + +export const TransportAvailabilityRequest: msRest.CompositeMapper = { + serializedName: "TransportAvailabilityRequest", + type: { + name: "Composite", + className: "TransportAvailabilityRequest", + modelProperties: { + skuName: { + serializedName: "skuName", + type: { + name: "Enum", + allowedValues: [ + "DataBox", + "DataBoxDisk", + "DataBoxHeavy" + ] + } + } + } + } +}; + +export const RegionConfigurationRequest: msRest.CompositeMapper = { + serializedName: "RegionConfigurationRequest", + type: { + name: "Composite", + className: "RegionConfigurationRequest", + modelProperties: { + scheduleAvailabilityRequest: { + serializedName: "scheduleAvailabilityRequest", + type: { + name: "Composite", + className: "ScheduleAvailabilityRequest" + } + }, + transportAvailabilityRequest: { + serializedName: "transportAvailabilityRequest", + type: { + name: "Composite", + className: "TransportAvailabilityRequest" + } + } + } + } +}; + +export const ScheduleAvailabilityResponse: msRest.CompositeMapper = { + serializedName: "ScheduleAvailabilityResponse", + type: { + name: "Composite", + className: "ScheduleAvailabilityResponse", + modelProperties: { + availableDates: { + readOnly: true, + serializedName: "availableDates", + type: { + name: "Sequence", + element: { + type: { + name: "DateTime" + } + } + } + } + } + } +}; + +export const TransportAvailabilityDetails: msRest.CompositeMapper = { + serializedName: "TransportAvailabilityDetails", + type: { + name: "Composite", + className: "TransportAvailabilityDetails", + modelProperties: { + shipmentType: { + readOnly: true, + serializedName: "shipmentType", + type: { + name: "Enum", + allowedValues: [ + "CustomerManaged", + "MicrosoftManaged" + ] + } + } + } + } +}; + +export const TransportAvailabilityResponse: msRest.CompositeMapper = { + serializedName: "TransportAvailabilityResponse", + type: { + name: "Composite", + className: "TransportAvailabilityResponse", + modelProperties: { + transportAvailabilityDetails: { + readOnly: true, + serializedName: "transportAvailabilityDetails", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "TransportAvailabilityDetails" + } + } + } + } + } + } +}; + +export const RegionConfigurationResponse: msRest.CompositeMapper = { + serializedName: "RegionConfigurationResponse", + type: { + name: "Composite", + className: "RegionConfigurationResponse", + modelProperties: { + scheduleAvailabilityResponse: { + readOnly: true, + serializedName: "scheduleAvailabilityResponse", + type: { + name: "Composite", + className: "ScheduleAvailabilityResponse" + } + }, + transportAvailabilityResponse: { + readOnly: true, + serializedName: "transportAvailabilityResponse", + type: { + name: "Composite", + className: "TransportAvailabilityResponse" + } + } + } + } +}; + export const ShipmentPickUpRequest: msRest.CompositeMapper = { serializedName: "ShipmentPickUpRequest", type: { @@ -1950,6 +2570,117 @@ export const ShipmentPickUpResponse: msRest.CompositeMapper = { } }; +export const SkuAvailabilityValidationRequest: msRest.CompositeMapper = { + serializedName: "ValidateSkuAvailability", + type: { + name: "Composite", + polymorphicDiscriminator: ValidationInputRequest.type.polymorphicDiscriminator, + uberParent: "ValidationInputRequest", + className: "SkuAvailabilityValidationRequest", + modelProperties: { + ...ValidationInputRequest.type.modelProperties, + deviceType: { + required: true, + serializedName: "deviceType", + type: { + name: "Enum", + allowedValues: [ + "DataBox", + "DataBoxDisk", + "DataBoxHeavy" + ] + } + }, + transferType: { + required: true, + isConstant: true, + serializedName: "transferType", + defaultValue: 'ImportToAzure', + type: { + name: "String" + } + }, + country: { + required: true, + serializedName: "country", + type: { + name: "String" + } + }, + location: { + required: true, + serializedName: "location", + type: { + name: "String" + } + } + } + } +}; + +export const SkuAvailabilityValidationResponseProperties: msRest.CompositeMapper = { + serializedName: "ValidateSkuAvailability", + type: { + name: "Composite", + polymorphicDiscriminator: ValidationInputResponse.type.polymorphicDiscriminator, + uberParent: "ValidationInputResponse", + className: "SkuAvailabilityValidationResponseProperties", + modelProperties: { + ...ValidationInputResponse.type.modelProperties, + status: { + readOnly: true, + serializedName: "status", + type: { + name: "Enum", + allowedValues: [ + "Valid", + "Invalid", + "Skipped" + ] + } + } + } + } +}; + +export const SubscriptionIsAllowedToCreateJobValidationRequest: msRest.CompositeMapper = { + serializedName: "ValidateSubscriptionIsAllowedToCreateJob", + type: { + name: "Composite", + polymorphicDiscriminator: ValidationInputRequest.type.polymorphicDiscriminator, + uberParent: "ValidationInputRequest", + className: "SubscriptionIsAllowedToCreateJobValidationRequest", + modelProperties: { + ...ValidationInputRequest.type.modelProperties + } + } +}; + +export const SubscriptionIsAllowedToCreateJobValidationResponseProperties: msRest.CompositeMapper = { + serializedName: "ValidateSubscriptionIsAllowedToCreateJob", + type: { + name: "Composite", + polymorphicDiscriminator: ValidationInputResponse.type.polymorphicDiscriminator, + uberParent: "ValidationInputResponse", + className: "SubscriptionIsAllowedToCreateJobValidationResponseProperties", + modelProperties: { + ...ValidationInputResponse.type.modelProperties, + status: { + readOnly: true, + serializedName: "status", + type: { + name: "Enum", + allowedValues: [ + "Valid", + "Invalid", + "Skipped" + ] + } + } + } + } +}; + export const UnencryptedCredentials: msRest.CompositeMapper = { serializedName: "UnencryptedCredentials", type: { @@ -1979,8 +2710,11 @@ export const ValidateAddress: msRest.CompositeMapper = { serializedName: "ValidateAddress", type: { name: "Composite", + polymorphicDiscriminator: ValidationInputRequest.type.polymorphicDiscriminator, + uberParent: "ValidationInputRequest", className: "ValidateAddress", modelProperties: { + ...ValidationInputRequest.type.modelProperties, shippingAddress: { required: true, serializedName: "shippingAddress", @@ -2000,6 +2734,96 @@ export const ValidateAddress: msRest.CompositeMapper = { "DataBoxHeavy" ] } + }, + transportPreferences: { + serializedName: "transportPreferences", + type: { + name: "Composite", + className: "TransportPreferences" + } + } + } + } +}; + +export const ValidationRequest: msRest.CompositeMapper = { + serializedName: "ValidationRequest", + type: { + name: "Composite", + polymorphicDiscriminator: { + serializedName: "validationCategory", + clientName: "validationCategory" + }, + uberParent: "ValidationRequest", + className: "ValidationRequest", + modelProperties: { + individualRequestDetails: { + required: true, + serializedName: "individualRequestDetails", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "ValidationInputRequest" + } + } + } + }, + validationCategory: { + required: true, + serializedName: "validationCategory", + type: { + name: "String" + } + } + } + } +}; + +export const CreateJobValidations: msRest.CompositeMapper = { + serializedName: "JobCreationValidation", + type: { + name: "Composite", + polymorphicDiscriminator: ValidationRequest.type.polymorphicDiscriminator, + uberParent: "ValidationRequest", + className: "CreateJobValidations", + modelProperties: { + ...ValidationRequest.type.modelProperties + } + } +}; + +export const ValidationResponse: msRest.CompositeMapper = { + serializedName: "ValidationResponse", + type: { + name: "Composite", + className: "ValidationResponse", + modelProperties: { + status: { + readOnly: true, + serializedName: "properties.status", + type: { + name: "Enum", + allowedValues: [ + "AllValidToProceed", + "InputsRevisitRequired", + "CertainInputValidationsSkipped" + ] + } + }, + individualResponseDetails: { + readOnly: true, + serializedName: "properties.individualResponseDetails", + type: { + name: "Sequence", + element: { + type: { + name: "Composite", + className: "ValidationInputResponse" + } + } + } } } } @@ -2115,6 +2939,8 @@ export const AvailableSkusResult: msRest.CompositeMapper = { export const discriminators = { 'CopyLogDetails' : CopyLogDetails, + 'ValidationInputRequest.ValidateCreateOrderLimit' : CreateOrderLimitForSubscriptionValidationRequest, + 'ValidationInputResponse.ValidateCreateOrderLimit' : CreateOrderLimitForSubscriptionValidationResponseProperties, 'CopyLogDetails.DataBox' : DataBoxAccountCopyLogDetails, 'CopyLogDetails.DataBoxDisk' : DataBoxDiskCopyLogDetails, 'JobDetails.DataBoxDisk' : DataBoxDiskJobDetails, @@ -2124,10 +2950,27 @@ export const discriminators = { 'JobSecrets.DataBoxHeavy' : DataBoxHeavyJobSecrets, 'JobDetails.DataBox' : DataBoxJobDetails, 'JobSecrets.DataBox' : DataboxJobSecrets, + 'ScheduleAvailabilityRequest.DataBox' : DataBoxScheduleAvailabilityRequest, 'DestinationAccountDetails' : DestinationAccountDetails, + 'ValidationInputRequest.ValidateDataDestinationDetails' : DataDestinationDetailsValidationRequest, + 'ValidationInputResponse.ValidateDataDestinationDetails' : DataDestinationDetailsValidationResponseProperties, 'DestinationAccountDetails.ManagedDisk' : DestinationManagedDiskDetails, 'DestinationAccountDetails.StorageAccount' : DestinationStorageAccountDetails, + 'ScheduleAvailabilityRequest.DataBoxDisk' : DiskScheduleAvailabilityRequest, + 'ScheduleAvailabilityRequest.DataBoxHeavy' : HeavyScheduleAvailabilityRequest, 'JobDetails' : JobDetails, - 'JobSecrets' : JobSecrets + 'JobSecrets' : JobSecrets, + 'ValidationInputRequest.ValidatePreferences' : PreferencesValidationRequest, + 'ValidationInputResponse.ValidatePreferences' : PreferencesValidationResponseProperties, + 'ScheduleAvailabilityRequest' : ScheduleAvailabilityRequest, + 'ValidationInputRequest.ValidateSkuAvailability' : SkuAvailabilityValidationRequest, + 'ValidationInputResponse.ValidateSkuAvailability' : SkuAvailabilityValidationResponseProperties, + 'ValidationInputRequest.ValidateSubscriptionIsAllowedToCreateJob' : SubscriptionIsAllowedToCreateJobValidationRequest, + 'ValidationInputResponse.ValidateSubscriptionIsAllowedToCreateJob' : SubscriptionIsAllowedToCreateJobValidationResponseProperties, + 'ValidationInputRequest.ValidateAddress' : ValidateAddress, + 'ValidationInputRequest' : ValidationInputRequest, + 'ValidationInputResponse' : ValidationInputResponse, + 'ValidationRequest' : ValidationRequest, + 'ValidationRequest.JobCreationValidation' : CreateJobValidations }; diff --git a/sdk/databox/arm-databox/src/models/serviceMappers.ts b/sdk/databox/arm-databox/src/models/serviceMappers.ts index 2d1898f209bf..42db69bd2f00 100644 --- a/sdk/databox/arm-databox/src/models/serviceMappers.ts +++ b/sdk/databox/arm-databox/src/models/serviceMappers.ts @@ -12,11 +12,42 @@ export { AvailableSkuRequest, AvailableSkusResult, CloudError, + CreateJobValidations, + CreateOrderLimitForSubscriptionValidationRequest, + CreateOrderLimitForSubscriptionValidationResponseProperties, + DataBoxScheduleAvailabilityRequest, + DataDestinationDetailsValidationRequest, + DataDestinationDetailsValidationResponseProperties, + DestinationAccountDetails, + DestinationManagedDiskDetails, + DestinationStorageAccountDetails, DestinationToServiceLocationMap, + DiskScheduleAvailabilityRequest, + ErrorModel, + HeavyScheduleAvailabilityRequest, + Preferences, + PreferencesValidationRequest, + PreferencesValidationResponseProperties, + RegionConfigurationRequest, + RegionConfigurationResponse, + ScheduleAvailabilityRequest, + ScheduleAvailabilityResponse, ShippingAddress, Sku, + SkuAvailabilityValidationRequest, + SkuAvailabilityValidationResponseProperties, SkuCapacity, SkuCost, SkuInformation, - ValidateAddress + SubscriptionIsAllowedToCreateJobValidationRequest, + SubscriptionIsAllowedToCreateJobValidationResponseProperties, + TransportAvailabilityDetails, + TransportAvailabilityRequest, + TransportAvailabilityResponse, + TransportPreferences, + ValidateAddress, + ValidationInputRequest, + ValidationInputResponse, + ValidationRequest, + ValidationResponse } from "../models/mappers"; diff --git a/sdk/databox/arm-databox/src/operations/service.ts b/sdk/databox/arm-databox/src/operations/service.ts index 8395b5e80c48..8ccece21381d 100644 --- a/sdk/databox/arm-databox/src/operations/service.ts +++ b/sdk/databox/arm-databox/src/operations/service.ts @@ -59,44 +59,174 @@ export class Service { } /** - * This method validates the customer shipping address and provide alternate addresses if any. + * This method provides the list of available skus for the given subscription, resource group and + * location. + * @param resourceGroupName The Resource Group Name * @param location The location of the resource - * @param shippingAddress Shipping address of the customer. - * @param deviceType Device type to be used for the job. Possible values include: 'DataBox', - * 'DataBoxDisk', 'DataBoxHeavy' + * @param availableSkuRequest Filters for showing the available skus. + * @param [options] The optional parameters + * @returns Promise + */ + listAvailableSkusByResourceGroup(resourceGroupName: string, location: string, availableSkuRequest: Models.AvailableSkuRequest, options?: msRest.RequestOptionsBase): Promise; + /** + * @param resourceGroupName The Resource Group Name + * @param location The location of the resource + * @param availableSkuRequest Filters for showing the available skus. + * @param callback The callback + */ + listAvailableSkusByResourceGroup(resourceGroupName: string, location: string, availableSkuRequest: Models.AvailableSkuRequest, callback: msRest.ServiceCallback): void; + /** + * @param resourceGroupName The Resource Group Name + * @param location The location of the resource + * @param availableSkuRequest Filters for showing the available skus. + * @param options The optional parameters + * @param callback The callback + */ + listAvailableSkusByResourceGroup(resourceGroupName: string, location: string, availableSkuRequest: Models.AvailableSkuRequest, options: msRest.RequestOptionsBase, callback: msRest.ServiceCallback): void; + listAvailableSkusByResourceGroup(resourceGroupName: string, location: string, availableSkuRequest: Models.AvailableSkuRequest, options?: msRest.RequestOptionsBase | msRest.ServiceCallback, callback?: msRest.ServiceCallback): Promise { + return this.client.sendOperationRequest( + { + resourceGroupName, + location, + availableSkuRequest, + options + }, + listAvailableSkusByResourceGroupOperationSpec, + callback) as Promise; + } + + /** + * [DEPRECATED NOTICE: This operation will soon be removed] This method validates the customer + * shipping address and provide alternate addresses if any. + * @param location The location of the resource + * @param validateAddress Shipping address of the customer. * @param [options] The optional parameters + * @deprecated This operation is deprecated. Please do not use it any longer. * @returns Promise */ - validateAddressMethod(location: string, shippingAddress: Models.ShippingAddress, deviceType: Models.SkuName, options?: msRest.RequestOptionsBase): Promise; + validateAddressMethod(location: string, validateAddress: Models.ValidateAddress, options?: msRest.RequestOptionsBase): Promise; /** * @param location The location of the resource - * @param shippingAddress Shipping address of the customer. - * @param deviceType Device type to be used for the job. Possible values include: 'DataBox', - * 'DataBoxDisk', 'DataBoxHeavy' + * @param validateAddress Shipping address of the customer. * @param callback The callback + * @deprecated This operation is deprecated. Please do not use it any longer. */ - validateAddressMethod(location: string, shippingAddress: Models.ShippingAddress, deviceType: Models.SkuName, callback: msRest.ServiceCallback): void; + validateAddressMethod(location: string, validateAddress: Models.ValidateAddress, callback: msRest.ServiceCallback): void; /** * @param location The location of the resource - * @param shippingAddress Shipping address of the customer. - * @param deviceType Device type to be used for the job. Possible values include: 'DataBox', - * 'DataBoxDisk', 'DataBoxHeavy' + * @param validateAddress Shipping address of the customer. * @param options The optional parameters * @param callback The callback + * @deprecated This operation is deprecated. Please do not use it any longer. */ - validateAddressMethod(location: string, shippingAddress: Models.ShippingAddress, deviceType: Models.SkuName, options: msRest.RequestOptionsBase, callback: msRest.ServiceCallback): void; - validateAddressMethod(location: string, shippingAddress: Models.ShippingAddress, deviceType: Models.SkuName, options?: msRest.RequestOptionsBase | msRest.ServiceCallback, callback?: msRest.ServiceCallback): Promise { + validateAddressMethod(location: string, validateAddress: Models.ValidateAddress, options: msRest.RequestOptionsBase, callback: msRest.ServiceCallback): void; + validateAddressMethod(location: string, validateAddress: Models.ValidateAddress, options?: msRest.RequestOptionsBase | msRest.ServiceCallback, callback?: msRest.ServiceCallback): Promise { return this.client.sendOperationRequest( { location, - shippingAddress, - deviceType, + validateAddress, options }, validateAddressMethodOperationSpec, callback) as Promise; } + /** + * This method does all necessary pre-job creation validation under resource group. + * @param resourceGroupName The Resource Group Name + * @param location The location of the resource + * @param validationRequest Inputs of the customer. + * @param [options] The optional parameters + * @returns Promise + */ + validateInputsByResourceGroup(resourceGroupName: string, location: string, validationRequest: Models.ValidationRequestUnion, options?: msRest.RequestOptionsBase): Promise; + /** + * @param resourceGroupName The Resource Group Name + * @param location The location of the resource + * @param validationRequest Inputs of the customer. + * @param callback The callback + */ + validateInputsByResourceGroup(resourceGroupName: string, location: string, validationRequest: Models.ValidationRequestUnion, callback: msRest.ServiceCallback): void; + /** + * @param resourceGroupName The Resource Group Name + * @param location The location of the resource + * @param validationRequest Inputs of the customer. + * @param options The optional parameters + * @param callback The callback + */ + validateInputsByResourceGroup(resourceGroupName: string, location: string, validationRequest: Models.ValidationRequestUnion, options: msRest.RequestOptionsBase, callback: msRest.ServiceCallback): void; + validateInputsByResourceGroup(resourceGroupName: string, location: string, validationRequest: Models.ValidationRequestUnion, options?: msRest.RequestOptionsBase | msRest.ServiceCallback, callback?: msRest.ServiceCallback): Promise { + return this.client.sendOperationRequest( + { + resourceGroupName, + location, + validationRequest, + options + }, + validateInputsByResourceGroupOperationSpec, + callback) as Promise; + } + + /** + * This method does all necessary pre-job creation validation under subscription. + * @param location The location of the resource + * @param validationRequest Inputs of the customer. + * @param [options] The optional parameters + * @returns Promise + */ + validateInputs(location: string, validationRequest: Models.ValidationRequestUnion, options?: msRest.RequestOptionsBase): Promise; + /** + * @param location The location of the resource + * @param validationRequest Inputs of the customer. + * @param callback The callback + */ + validateInputs(location: string, validationRequest: Models.ValidationRequestUnion, callback: msRest.ServiceCallback): void; + /** + * @param location The location of the resource + * @param validationRequest Inputs of the customer. + * @param options The optional parameters + * @param callback The callback + */ + validateInputs(location: string, validationRequest: Models.ValidationRequestUnion, options: msRest.RequestOptionsBase, callback: msRest.ServiceCallback): void; + validateInputs(location: string, validationRequest: Models.ValidationRequestUnion, options?: msRest.RequestOptionsBase | msRest.ServiceCallback, callback?: msRest.ServiceCallback): Promise { + return this.client.sendOperationRequest( + { + location, + validationRequest, + options + }, + validateInputsOperationSpec, + callback) as Promise; + } + + /** + * This API provides configuration details specific to given region/location. + * @param location The location of the resource + * @param [options] The optional parameters + * @returns Promise + */ + regionConfiguration(location: string, options?: Models.ServiceRegionConfigurationOptionalParams): Promise; + /** + * @param location The location of the resource + * @param callback The callback + */ + regionConfiguration(location: string, callback: msRest.ServiceCallback): void; + /** + * @param location The location of the resource + * @param options The optional parameters + * @param callback The callback + */ + regionConfiguration(location: string, options: Models.ServiceRegionConfigurationOptionalParams, callback: msRest.ServiceCallback): void; + regionConfiguration(location: string, options?: Models.ServiceRegionConfigurationOptionalParams | msRest.ServiceCallback, callback?: msRest.ServiceCallback): Promise { + return this.client.sendOperationRequest( + { + location, + options + }, + regionConfigurationOperationSpec, + callback) as Promise; + } + /** * This method provides the list of available skus for the given subscription and location. * @param nextPageLink The NextLink from the previous successful call to List operation. @@ -124,6 +254,35 @@ export class Service { listAvailableSkusNextOperationSpec, callback) as Promise; } + + /** + * This method provides the list of available skus for the given subscription, resource group and + * location. + * @param nextPageLink The NextLink from the previous successful call to List operation. + * @param [options] The optional parameters + * @returns Promise + */ + listAvailableSkusByResourceGroupNext(nextPageLink: string, options?: msRest.RequestOptionsBase): Promise; + /** + * @param nextPageLink The NextLink from the previous successful call to List operation. + * @param callback The callback + */ + listAvailableSkusByResourceGroupNext(nextPageLink: string, callback: msRest.ServiceCallback): void; + /** + * @param nextPageLink The NextLink from the previous successful call to List operation. + * @param options The optional parameters + * @param callback The callback + */ + listAvailableSkusByResourceGroupNext(nextPageLink: string, options: msRest.RequestOptionsBase, callback: msRest.ServiceCallback): void; + listAvailableSkusByResourceGroupNext(nextPageLink: string, options?: msRest.RequestOptionsBase | msRest.ServiceCallback, callback?: msRest.ServiceCallback): Promise { + return this.client.sendOperationRequest( + { + nextPageLink, + options + }, + listAvailableSkusByResourceGroupNextOperationSpec, + callback) as Promise; + } } // Operation Specifications @@ -159,6 +318,38 @@ const listAvailableSkusOperationSpec: msRest.OperationSpec = { serializer }; +const listAvailableSkusByResourceGroupOperationSpec: msRest.OperationSpec = { + httpMethod: "POST", + path: "subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DataBox/locations/{location}/availableSkus", + urlParameters: [ + Parameters.subscriptionId, + Parameters.resourceGroupName, + Parameters.location + ], + queryParameters: [ + Parameters.apiVersion + ], + headerParameters: [ + Parameters.acceptLanguage + ], + requestBody: { + parameterPath: "availableSkuRequest", + mapper: { + ...Mappers.AvailableSkuRequest, + required: true + } + }, + responses: { + 200: { + bodyMapper: Mappers.AvailableSkusResult + }, + default: { + bodyMapper: Mappers.CloudError + } + }, + serializer +}; + const validateAddressMethodOperationSpec: msRest.OperationSpec = { httpMethod: "POST", path: "subscriptions/{subscriptionId}/providers/Microsoft.DataBox/locations/{location}/validateAddress", @@ -173,10 +364,7 @@ const validateAddressMethodOperationSpec: msRest.OperationSpec = { Parameters.acceptLanguage ], requestBody: { - parameterPath: { - shippingAddress: "shippingAddress", - deviceType: "deviceType" - }, + parameterPath: "validateAddress", mapper: { ...Mappers.ValidateAddress, required: true @@ -193,6 +381,109 @@ const validateAddressMethodOperationSpec: msRest.OperationSpec = { serializer }; +const validateInputsByResourceGroupOperationSpec: msRest.OperationSpec = { + httpMethod: "POST", + path: "subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DataBox/locations/{location}/validateInputs", + urlParameters: [ + Parameters.subscriptionId, + Parameters.resourceGroupName, + Parameters.location + ], + queryParameters: [ + Parameters.apiVersion + ], + headerParameters: [ + Parameters.acceptLanguage + ], + requestBody: { + parameterPath: "validationRequest", + mapper: { + ...Mappers.ValidationRequest, + required: true + } + }, + responses: { + 200: { + bodyMapper: Mappers.ValidationResponse + }, + default: { + bodyMapper: Mappers.CloudError + } + }, + serializer +}; + +const validateInputsOperationSpec: msRest.OperationSpec = { + httpMethod: "POST", + path: "subscriptions/{subscriptionId}/providers/Microsoft.DataBox/locations/{location}/validateInputs", + urlParameters: [ + Parameters.subscriptionId, + Parameters.location + ], + queryParameters: [ + Parameters.apiVersion + ], + headerParameters: [ + Parameters.acceptLanguage + ], + requestBody: { + parameterPath: "validationRequest", + mapper: { + ...Mappers.ValidationRequest, + required: true + } + }, + responses: { + 200: { + bodyMapper: Mappers.ValidationResponse + }, + default: { + bodyMapper: Mappers.CloudError + } + }, + serializer +}; + +const regionConfigurationOperationSpec: msRest.OperationSpec = { + httpMethod: "POST", + path: "subscriptions/{subscriptionId}/providers/Microsoft.DataBox/locations/{location}/regionConfiguration", + urlParameters: [ + Parameters.subscriptionId, + Parameters.location + ], + queryParameters: [ + Parameters.apiVersion + ], + headerParameters: [ + Parameters.acceptLanguage + ], + requestBody: { + parameterPath: { + scheduleAvailabilityRequest: [ + "options", + "scheduleAvailabilityRequest" + ], + transportAvailabilityRequest: [ + "options", + "transportAvailabilityRequest" + ] + }, + mapper: { + ...Mappers.RegionConfigurationRequest, + required: true + } + }, + responses: { + 200: { + bodyMapper: Mappers.RegionConfigurationResponse + }, + default: { + bodyMapper: Mappers.CloudError + } + }, + serializer +}; + const listAvailableSkusNextOperationSpec: msRest.OperationSpec = { httpMethod: "POST", baseUrl: "https://management.azure.com", @@ -213,3 +504,24 @@ const listAvailableSkusNextOperationSpec: msRest.OperationSpec = { }, serializer }; + +const listAvailableSkusByResourceGroupNextOperationSpec: msRest.OperationSpec = { + httpMethod: "POST", + baseUrl: "https://management.azure.com", + path: "{nextLink}", + urlParameters: [ + Parameters.nextPageLink + ], + headerParameters: [ + Parameters.acceptLanguage + ], + responses: { + 200: { + bodyMapper: Mappers.AvailableSkusResult + }, + default: { + bodyMapper: Mappers.CloudError + } + }, + serializer +}; From 7f419324be04bdfdbc5a45862dd73d82e1cc4e27 Mon Sep 17 00:00:00 2001 From: Wei Dong <40835867+dw511214992@users.noreply.github.com> Date: Wed, 12 Feb 2020 20:20:19 +0800 Subject: [PATCH 11/13] Databox release (#7358) * bump version of databox * Revert "bump version of databox" This reverts commit 338c6e3b8d40be6f04c0bc20c99711d6036304cd. * bump version of databox * Revert "bump version of databox" This reverts commit 14ba907f309d52c192e8caad4874596d46d0cd82. * bump version of databox --- sdk/databox/arm-databox/package.json | 2 +- sdk/databox/arm-databox/src/dataBoxManagementClientContext.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/databox/arm-databox/package.json b/sdk/databox/arm-databox/package.json index 664a0ea1fe0a..4609f88a04ca 100644 --- a/sdk/databox/arm-databox/package.json +++ b/sdk/databox/arm-databox/package.json @@ -2,7 +2,7 @@ "name": "@azure/arm-databox", "author": "Microsoft Corporation", "description": "DataBoxManagementClient Library with typescript type definitions for node.js and browser.", - "version": "3.0.0", + "version": "4.0.0", "dependencies": { "@azure/ms-rest-azure-js": "^2.0.1", "@azure/ms-rest-js": "^2.0.4", diff --git a/sdk/databox/arm-databox/src/dataBoxManagementClientContext.ts b/sdk/databox/arm-databox/src/dataBoxManagementClientContext.ts index cda0daa42451..c96e85eca2a9 100644 --- a/sdk/databox/arm-databox/src/dataBoxManagementClientContext.ts +++ b/sdk/databox/arm-databox/src/dataBoxManagementClientContext.ts @@ -13,7 +13,7 @@ import * as msRest from "@azure/ms-rest-js"; import * as msRestAzure from "@azure/ms-rest-azure-js"; const packageName = "@azure/arm-databox"; -const packageVersion = "3.0.0"; +const packageVersion = "4.0.0"; export class DataBoxManagementClientContext extends msRestAzure.AzureServiceClient { credentials: msRest.ServiceClientCredentials; From 7669ba7cc17f7aa454e695359aedea0551fcd9a5 Mon Sep 17 00:00:00 2001 From: Harsha Nalluru Date: Wed, 12 Feb 2020 10:46:47 -0800 Subject: [PATCH 12/13] [Service Bus] Merge feature/service-bus-track-2 into master (#7312) * Pin core-amqp version to preview.1 * Update lock file * Fix merge conflicts * [Service Bus] Update to use core-amqp (#5324) * Use core-amqp in atom management client, comment tests that use token provider * [Service Bus] Update to use latest core-amqp (#6861) * [Service Bus] Update constructors to add overloads and use Azure Identity (#5436) * sync-versions: rhea-promise and @azure/core-amqp for service-bus * resolve merge conflicts appropriately * API Report File for "@azure/service-bus" * Address feedback * SERVICEBUS_CONNECTION_STRING_BROWSER remove from karma.conf * update pnpm-lock file * update API Report File for "@azure/service-bus" * remove rhea and rhea-promise dependencies * add "rhea-promise" back Co-authored-by: Ramya Rao Co-authored-by: ramya0820 <45977823+ramya0820@users.noreply.github.com> --- common/config/rush/common-versions.json | 3 - common/config/rush/pnpm-lock.yaml | 81 +++---- sdk/servicebus/service-bus/README.md | 4 +- sdk/servicebus/service-bus/karma.conf.js | 6 +- sdk/servicebus/service-bus/package.json | 12 +- .../service-bus/review/service-bus.api.md | 31 ++- .../service-bus/src/clientEntityContext.ts | 8 +- .../service-bus/src/connectionContext.ts | 11 +- .../service-bus/src/core/batchingReceiver.ts | 12 +- .../service-bus/src/core/linkEntity.ts | 55 ++++- .../service-bus/src/core/managementClient.ts | 25 +-- .../service-bus/src/core/messageReceiver.ts | 24 ++- .../service-bus/src/core/messageSender.ts | 28 +-- sdk/servicebus/service-bus/src/index.ts | 8 +- .../src/serviceBusAtomManagementClient.ts | 7 +- .../service-bus/src/serviceBusClient.ts | 177 +++++---------- .../service-bus/src/serviceBusMessage.ts | 2 +- .../service-bus/src/session/messageSession.ts | 20 +- .../service-bus/src/session/sessionManager.ts | 15 +- .../src/util/concurrentExpiringMap.ts | 2 +- .../service-bus/src/util/constants.ts | 2 +- sdk/servicebus/service-bus/test/README.md | 6 +- .../service-bus/test/atomManagement.spec.ts | 2 +- .../service-bus/test/batchReceiver.spec.ts | 2 +- .../test/perf/service-bus/receive.ts | 2 +- .../service-bus/test/perf/service-bus/send.ts | 2 +- .../service-bus/test/renewLock.spec.ts | 4 +- .../test/renewLockSessions.spec.ts | 9 +- .../service-bus/test/serviceBusClient.spec.ts | 203 ++++++++++-------- .../test/streamingReceiver.spec.ts | 37 ++-- ...ress_fixedNumberOfClientsMultipleQueues.ts | 2 +- .../stress_fixedNumberOfClientsSingleQueue.ts | 2 +- .../stress/stress_messageAutolockRenewal.ts | 4 +- ...messageLockRenewalBatchingThenStreaming.ts | 4 +- .../stress/stress_messageManualLockRenewal.ts | 4 +- .../stress/stress_messageRandomDisposition.ts | 4 +- ...tress_messageRandomDispositionOnSession.ts | 4 +- .../stress/stress_sessionAutolockRenewal.ts | 4 +- .../stress/stress_sessionManualLockRenewal.ts | 4 +- .../test/stress/stress_sessionState.ts | 2 +- .../test/stress/stress_singleClient.ts | 2 +- .../stress/stress_singleMessageComplete.ts | 4 +- .../service-bus/test/topicFilters.spec.ts | 8 +- .../test/utils/aadUtils.browser.ts | 4 - .../service-bus/test/utils/aadUtils.ts | 21 -- .../service-bus/test/utils/envVarUtils.ts | 18 +- .../service-bus/test/utils/testUtils.ts | 13 +- sdk/servicebus/service-bus/tests.yml | 9 +- 48 files changed, 430 insertions(+), 483 deletions(-) delete mode 100644 sdk/servicebus/service-bus/test/utils/aadUtils.browser.ts delete mode 100644 sdk/servicebus/service-bus/test/utils/aadUtils.ts diff --git a/common/config/rush/common-versions.json b/common/config/rush/common-versions.json index 6db47e061f6c..48d288dca8e9 100644 --- a/common/config/rush/common-versions.json +++ b/common/config/rush/common-versions.json @@ -49,9 +49,6 @@ // "typescript": [ // "~2.4.0" // ] - // Following is required to allow for backward compatibility with Service Bus Track 1 - // TODO: Remove this once Service Bus is updated to use current depenedencies as part of Track 2 - "rhea-promise": ["^0.1.15"], // Following is required to allow for backward compatibility with Event Processor Host Track 1 "@azure/event-hubs": ["^2.1.4"] } diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index e3c15d056d50..d2532245fb07 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -35,27 +35,6 @@ packages: dev: false resolution: integrity: sha512-wP2Jw6uPp8DEDy0n4KNidvwzDjyVV2xnycEIq7nPzj1rHyb/r+t3OPeNT1INZePP2wy5ZqlwyuyOMTi0ePyY1A== - /@azure/amqp-common/1.0.0-preview.10: - dependencies: - '@azure/ms-rest-nodeauth': 0.9.3 - '@types/async-lock': 1.1.1 - '@types/is-buffer': 2.0.0 - async-lock: 1.2.2 - buffer: 5.4.3 - debug: 3.2.6 - events: 3.1.0 - is-buffer: 2.0.4 - jssha: 2.3.1 - process: 0.11.10 - rhea: 1.0.18 - rhea-promise: 0.1.15 - stream-browserify: 2.0.2 - tslib: 1.10.0 - url: 0.11.0 - util: 0.11.1 - dev: false - resolution: - integrity: sha512-1Qm74g99Rrb7xBzl5UFKLA9/DZEfiwmlgc5XX8Alwknkzua4Mf2XPaky3vuXMZ03ClG4Sbhl4U9NleQ83SrEzA== /@azure/amqp-common/1.0.0-preview.9: dependencies: '@azure/ms-rest-nodeauth': 0.9.3 @@ -8058,7 +8037,7 @@ packages: dev: false name: '@rush-temp/abort-controller' resolution: - integrity: sha512-Xla0VK+eEW8lnCzVyAL5++AoKQgNU1zHAUmoHSyMUCMpSG3KaUQiyOpfNyOG29yJ1r9I0z71m30NzRZtHFm39Q== + integrity: sha512-DO1D00rXpn1zUunQUSSF6VF1CU3nTbSMnoJo4y1y7/HoDjwgvq2Lifu64PscEv8Xs/EqejGGQUldCTlkwJ/wfw== tarball: 'file:projects/abort-controller.tgz' version: 0.0.0 'file:projects/ai-text-analytics.tgz': @@ -8118,7 +8097,7 @@ packages: dev: false name: '@rush-temp/ai-text-analytics' resolution: - integrity: sha512-fqA10W69RAm4E1lXTZEX3wiCTIYcMG4BfLFL+VwKLdSIewSmK76a52JegKuKEMc6j05twqBDUyIiwbxGV9nG+g== + integrity: sha512-s4AvJH9H5CinaWgZKeL8P2UwpEL7sa5g4J51gAe/Y1AidxkZpqDLlD2m3aR6Ci/ioWwvrgzMCoz/vLvBEp0Frg== tarball: 'file:projects/ai-text-analytics.tgz' version: 0.0.0 'file:projects/app-configuration.tgz': @@ -8160,7 +8139,7 @@ packages: dev: false name: '@rush-temp/app-configuration' resolution: - integrity: sha512-oEvsSxFsumlUtpdWYLzhq20CKy9MmR34FYKbMQrhUBLHAloc+pznexh4u2/3OSdYcugDKgeicwkL35axbgGYKg== + integrity: sha512-zDI0h0tRBSFYpt6gYADkDF6OIIMgmxlFvtfQ3kg8/87lX14ci06bfDC7AFE7Sjx4qSgLmsWmJRjNSMJgdnMivg== tarball: 'file:projects/app-configuration.tgz' version: 0.0.0 'file:projects/core-amqp.tgz': @@ -8228,7 +8207,7 @@ packages: dev: false name: '@rush-temp/core-amqp' resolution: - integrity: sha512-MhzxdzNAk3nDK+vSqVlrFWn9WzAlnYZKgixZopFUeLbNXKtTIuknEm4sbDQ8n/1svgzMDWN0PlsWnFYBW0WnBg== + integrity: sha512-9Z/u0i3Cu8SPqpRIWOFwraYSyrhspg/wiDBYgVcwSOHK0hA4oyUA+Y/CgqWtLm+luuTLNNJgRjFveAcxQ4OjTA== tarball: 'file:projects/core-amqp.tgz' version: 0.0.0 'file:projects/core-arm.tgz': @@ -8262,7 +8241,7 @@ packages: dev: false name: '@rush-temp/core-arm' resolution: - integrity: sha512-gMo5M4yZopVded6wxND2JEGB6LyYP6FPbQYlPyhPFy36scETuxnOzg9d965CYEaLS/pa1Y8m73NvYPntfsFrAg== + integrity: sha512-0pn2mZyXmj//Y/nBrZacADv0y5cxhrtTmSDh7lJKBkO1mikLkWocQzfkXVQf2zDoZXRSqK5EDICnRx34Iij6og== tarball: 'file:projects/core-arm.tgz' version: 0.0.0 'file:projects/core-asynciterator-polyfill.tgz': @@ -8280,7 +8259,7 @@ packages: dev: false name: '@rush-temp/core-asynciterator-polyfill' resolution: - integrity: sha512-wcvU9xzocDcf6JqxBwlUIbDtU8XGBkq8n5TjQ4QYlRSFOUqjEX64a6XdMQr4dcga+OSoZw/QV/12HYPuUypK9w== + integrity: sha512-jDLggg/4sSiSb9xXQUsivEzh+w65cXOMPe/kPArXFs+LmAHaK1Et7soO3hxgmVW7AZ/5lVp8jcfW3hDXbKIFXQ== tarball: 'file:projects/core-asynciterator-polyfill.tgz' version: 0.0.0 'file:projects/core-auth.tgz': @@ -8321,7 +8300,7 @@ packages: dev: false name: '@rush-temp/core-auth' resolution: - integrity: sha512-SUk7DhjxjZhru6S3LTYJ7ZQjYaTKzrseBnzH632m9cRNiyYKN64ZQy7LlYBuvlFIFUL+6j3unoZlyEThr4SwfA== + integrity: sha512-s/939eY3zDHWsLuxyKMR6PfnRaA8fYeoDeAas83xmrRQwU5Nnj2YMfjWl8RwlUrLk4nJ2Hdi2nSZVp2UzCLyuw== tarball: 'file:projects/core-auth.tgz' version: 0.0.0 'file:projects/core-http.tgz': @@ -8398,7 +8377,7 @@ packages: dev: false name: '@rush-temp/core-http' resolution: - integrity: sha512-Kkoja/RR+gTqQ3X7gjfiPpewtxKfj+tWnUlV95zcjlMQxqzbQ/j6lcH29NHhv52FznxnUhqzUvxYY05cs1cfXQ== + integrity: sha512-Upl8IMRO2gVy5hXFCz3YK0u90oSG2JVuf9fZ8ReWtRYvx9vcAFMvpFMEO0xrZnT7WKzdaT0sBcSs7pe8neHHAQ== tarball: 'file:projects/core-http.tgz' version: 0.0.0 'file:projects/core-lro.tgz': @@ -8454,7 +8433,7 @@ packages: dev: false name: '@rush-temp/core-lro' resolution: - integrity: sha512-N+7SM1Yhnch618EhTBBoxQZRddrh+yqQhVuBJV0knDjtiC+nz+coerWGZ77T9tkTSgw4esZtZDn+MdTfQlKY0A== + integrity: sha512-HzwPk4vzJPaKNDjWArURsZuV7oYXPjVd4ccxHSwTEJ2sSctuSUb3IMXinsNOKjJCHvTYJM6lNkESCuWIyDOTQQ== tarball: 'file:projects/core-lro.tgz' version: 0.0.0 'file:projects/core-paging.tgz': @@ -8472,7 +8451,7 @@ packages: dev: false name: '@rush-temp/core-paging' resolution: - integrity: sha512-HtQeUV6/jtHxcEJSGOLfZj58FrapAsPl4Lirod7Yib/yXMrDIBYkkkI3Wwx5mGap+6ChPvmsBeskFIii1ZKcJg== + integrity: sha512-rRAaeqAsySfmVMMf46j6TljIPw2xVRZBVuyU9wrvQKJb1VzIEBZayG1jm9iTyyqUdFOEMn759//IfYP7KkhJNQ== tarball: 'file:projects/core-paging.tgz' version: 0.0.0 'file:projects/core-tracing.tgz': @@ -8513,7 +8492,7 @@ packages: dev: false name: '@rush-temp/core-tracing' resolution: - integrity: sha512-RWETP32JH6m1gxq4dQKAe572XiKX+bLAlU3/fUxPZPbscLNtphMy/E2DRzyvDCBEQfL+C49MxZIzEoy8ECdKgw== + integrity: sha512-SJ+L9sNBKGjTh1Ye4OWZ1aqXJ534jIKQwi5eDRa6irbh1jSZsNUmSMnBxzkM3+0kfQZ8YP7jm6sjPykaOJ4hUQ== tarball: 'file:projects/core-tracing.tgz' version: 0.0.0 'file:projects/cosmos.tgz': @@ -8575,7 +8554,7 @@ packages: dev: false name: '@rush-temp/cosmos' resolution: - integrity: sha512-DKhpoSSi/f/Aq6de+2s/IpX1C5FQbVfBdK063cXTE1SCamCwzYdf6/SLLbWeEVadUgz4wFgBTIy9Ta3Zz79qUQ== + integrity: sha512-GRoPrAKiHI521c+rxNT791bVFShNn6YefMT78uX5GqvTkxZa1jY3t5B2IdISXe0w1egUKwqImF2etEza6/pRZw== tarball: 'file:projects/cosmos.tgz' version: 0.0.0 'file:projects/event-hubs.tgz': @@ -8655,7 +8634,7 @@ packages: dev: false name: '@rush-temp/event-hubs' resolution: - integrity: sha512-ADxIBYXDACt52yTU4wn0dcR2pyKLNTlly7yIAD0e43929abQYDaznlMDTzGmjFtfPd3I3ndgc9LThNtse2Ks3A== + integrity: sha512-7Hy1SDsby9EVOhWljTSZ6Z0BWd+YQqtrH5lXeIMxTRxVMP/0IxN2a69X/kSYm2Ey5nJ2Xf6I+lGhNRbJt2xTCw== tarball: 'file:projects/event-hubs.tgz' version: 0.0.0 'file:projects/event-processor-host.tgz': @@ -8713,7 +8692,7 @@ packages: dev: false name: '@rush-temp/event-processor-host' resolution: - integrity: sha512-SXJ4EJcxMdnl7GQuy7f7YXS4FLEcmojM48uJKlVQpbdFRSPZczCm8NAA8GGXJmJjVdq+nB388bYk2H724/ZTrA== + integrity: sha512-UKQZiZyDo3uX1TvimdPeny6Yc0s0t9foQLx1sap3CMzASBIocWrMXwYmxHWn3n8sRlOmMtqXNyJIy/1zru3+9A== tarball: 'file:projects/event-processor-host.tgz' version: 0.0.0 'file:projects/eventhubs-checkpointstore-blob.tgz': @@ -8778,7 +8757,7 @@ packages: dev: false name: '@rush-temp/eventhubs-checkpointstore-blob' resolution: - integrity: sha512-gjOffb+0MIjYerROkRE9jsYsEhRK8srYiK+JJbf8Qm4rcmz1cHOnbzO9CecOJ/p0abxOUhWDddaf8v2vPoeftg== + integrity: sha512-lxxp1rmltAR87zw3K+swxDYnmXNHEOvxY7mW7cPSekQKfIIlzg/j83ZFluvO7481/HJR9JOabMcFS/VHxhPrgA== tarball: 'file:projects/eventhubs-checkpointstore-blob.tgz' version: 0.0.0 'file:projects/identity.tgz': @@ -8834,7 +8813,7 @@ packages: dev: false name: '@rush-temp/identity' resolution: - integrity: sha512-mBOEy+pEAVgeJK+b9LM88IdJEnqqOdrEOIMVdprLpYzAILVVQ2dRLsO+bC5d3TfNK7ZttHz/jRmiGmRDanqobA== + integrity: sha512-QOB2CcVr5P9knbZUzUVF3N1RpaJzjzwStfMspqmyDmpIdt4YOyXR5510/JuDBztGJE15Qk7m9dMUdnyVO7EoEg== tarball: 'file:projects/identity.tgz' version: 0.0.0 'file:projects/keyvault-certificates.tgz': @@ -8900,7 +8879,7 @@ packages: dev: false name: '@rush-temp/keyvault-certificates' resolution: - integrity: sha512-HWTB3OFSaGPknGpAlUsMwPtznCjrGmQvyi5nwOPFLOGNklQTZIChUu3xlv7u/mm9woH7GDPIHJgFEf1N9kmTmg== + integrity: sha512-rev0ttXaoWIXgv7V0j0bWSlpW6mzJGO8s/FjprXf13cFaHrGL+mIilvY21TQ/PsYtX4H+B4MHzBBWv2rdCr4bg== tarball: 'file:projects/keyvault-certificates.tgz' version: 0.0.0 'file:projects/keyvault-keys.tgz': @@ -8966,7 +8945,7 @@ packages: dev: false name: '@rush-temp/keyvault-keys' resolution: - integrity: sha512-hOvqlTGoEqwfvhUq7f/GzbLoWibGlncvQwNuVzkS1nm1/L4ECnJY+nePpj/uC4jZ5fAPiz4B6iFtiWN8RxBDRQ== + integrity: sha512-4b5tCgtBSD3JTbMZaxyCAId+4EiRrtCApPIzg3EEZJgc1jXtJoycQbE12D9y9IizuHtHwxOk7fA93o6b61xpsg== tarball: 'file:projects/keyvault-keys.tgz' version: 0.0.0 'file:projects/keyvault-secrets.tgz': @@ -9032,7 +9011,7 @@ packages: dev: false name: '@rush-temp/keyvault-secrets' resolution: - integrity: sha512-76XNhCuQ+WVwljPMLrTJhBuu3mD5uBZ/IJB3WaUMpe+CP0t3puLXXoTQXy07+3mKmUcDqISasbVb1wATZfylyg== + integrity: sha512-aJVju6YZCSpff4Pu6kT84sbKZirJbEblQNqUM0T3485sohXv7kLiiN2mms7mHr7NlYbXT/KUVmBj8ro5X7w0hw== tarball: 'file:projects/keyvault-secrets.tgz' version: 0.0.0 'file:projects/logger.tgz': @@ -9086,12 +9065,12 @@ packages: dev: false name: '@rush-temp/logger' resolution: - integrity: sha512-pEEw8s5yGhWD//xsHeJ68St44jvF7ByD6xgdI9MjUfmv86sdCdGb9Nx9SoPK9E3MS917ttPf36uqIfFwnfWs2Q== + integrity: sha512-GCfPJg0YTmoF//OugUXBNudk+xG5zmVM0BDuBPU4aDRqIXGMuLJU6B4bHcSKar+Pp765IaboHZs4RzZuLOH02g== tarball: 'file:projects/logger.tgz' version: 0.0.0 'file:projects/service-bus.tgz': dependencies: - '@azure/amqp-common': 1.0.0-preview.10 + '@azure/amqp-common': 1.0.0-preview.9 '@azure/eslint-plugin-azure-sdk': 2.0.1_303bc1d883bbfc108111733cb7ab69e3 '@azure/ms-rest-nodeauth': 0.9.3 '@microsoft/api-extractor': 7.7.8 @@ -9154,7 +9133,7 @@ packages: promise: 8.0.3 puppeteer: 2.1.1 rhea: 1.0.18 - rhea-promise: 0.1.15 + rhea-promise: 1.0.0 rimraf: 3.0.1 rollup: 1.31.0 rollup-plugin-shim: 1.0.0 @@ -9167,7 +9146,7 @@ packages: dev: false name: '@rush-temp/service-bus' resolution: - integrity: sha512-GoJsi+/mi4U/jHoL0CEadcHpttm7DzEmnJhZApIEYBA1UqIN8CMZchDwMFSPA0y4ma2oEfZJWCDBPwOU0PRz9w== + integrity: sha512-a+61RsOAF8Y6oWHo65+Sr1RHj8g3rdlqFIxT8k/aUid99zNhyfXj+d3B/H8AlVPqghP4oVkW4d+Y4ss6WlUYJA== tarball: 'file:projects/service-bus.tgz' version: 0.0.0 'file:projects/storage-blob.tgz': @@ -9228,7 +9207,7 @@ packages: dev: false name: '@rush-temp/storage-blob' resolution: - integrity: sha512-C4qCp2+U6+uWu3X5SKvXYGCYmX5UIuH/TjsQBqBwCr4bkNUxvs90E3QLzh8CS35JcTPt7kLtcg4cZml41IWg7g== + integrity: sha512-lEP6M8gBMa0lo09vTP23CkzHXpID+MFTP9CABeoCVbl+GTUcagIfPpgwQnYyUkICzkXz7+nK9V8AWoLfaTn0TA== tarball: 'file:projects/storage-blob.tgz' version: 0.0.0 'file:projects/storage-file-datalake.tgz': @@ -9297,7 +9276,7 @@ packages: dev: false name: '@rush-temp/storage-file-datalake' resolution: - integrity: sha512-q7y9BkD1DaI1D+4ki8/8Qjsd3T3wikezl5jQnNb6yaBJPPgQqkPX+d9d7QzXfhEzcimJWZ1X4IplyZUu3MxJ9g== + integrity: sha512-f/jaSqr2gkQ6Dlz//6fPvFbRxwRCbIkiq3pL1xkTvFF3c5y1pcF3lG1R48ZhnsSwpKuWDl0vfPEiM/4eWttbHQ== tarball: 'file:projects/storage-file-datalake.tgz' version: 0.0.0 'file:projects/storage-file-share.tgz': @@ -9358,7 +9337,7 @@ packages: dev: false name: '@rush-temp/storage-file-share' resolution: - integrity: sha512-x9NFeJIsOWCLb0xAEYcH0SykV8YgLEhEwObxq49k7iej28Q75OarDUfAhW2eIOx0vt1EfhOYj0PBTiOtO4z6OA== + integrity: sha512-DJy4BcoAO/SElZYfGfL5Kdvt6A/Z0QkJ6pxZ7J0WyDFsjXEYroWnjLnNTU8T8akAMYWEVrm5j1b6eCueGUxing== tarball: 'file:projects/storage-file-share.tgz' version: 0.0.0 'file:projects/storage-queue.tgz': @@ -9418,7 +9397,7 @@ packages: dev: false name: '@rush-temp/storage-queue' resolution: - integrity: sha512-Y//E3m5VZRYZm6FlwOAcisq4hJi7z0MTqVh9ofhdg7Hc45qr31DBd8Ci8dn03poqaS3dSIGOTBObpYyfGB9Qgw== + integrity: sha512-c2VKjOl+42FNBg0R1HVYtsfuiHWPANnRTzigDkBVYG9U6QIFAVE2/mWfQLdAQE/fEOjKL5swQSVeEwRLjXXHmQ== tarball: 'file:projects/storage-queue.tgz' version: 0.0.0 'file:projects/template.tgz': @@ -9469,7 +9448,7 @@ packages: dev: false name: '@rush-temp/template' resolution: - integrity: sha512-Vw/0dXj2DcQ1NX0U+d/B2W7slh9HuoExmSU5EL0/BJClWsgIjJykyQ+wmwXafNF5lV/ltMPy7Rv+XbLft7K/tw== + integrity: sha512-eRzyhbFcnQZQgh8mnwyLFrZoP/wGTFoneLug+5s2AVEENNmr6+PQjEJVTg+dTlgfWG5gJP3meWTgHke3jcRt0A== tarball: 'file:projects/template.tgz' version: 0.0.0 'file:projects/test-utils-recorder.tgz': @@ -9524,7 +9503,7 @@ packages: dev: false name: '@rush-temp/test-utils-recorder' resolution: - integrity: sha512-BDMvFHxK4sXDE9cDKdYu+dNxmkpseGf/iGu+r6c4X0YBKYJ/eH9tKbOhXPi9sXjFgQeUkbPc0vRGsj+HS+/gsQ== + integrity: sha512-e8WwVJqQFHP560TcUW/m9GxzGq7LPpfLb++v/zC0vfjK+6aA7QRWTApUzlr+tyKqUG/bhEaNGMC+7KVOJyN2XQ== tarball: 'file:projects/test-utils-recorder.tgz' version: 0.0.0 'file:projects/testhub.tgz': @@ -9545,7 +9524,7 @@ packages: dev: false name: '@rush-temp/testhub' resolution: - integrity: sha512-dW7m2LfMTGWZVxeZCvuHSzjBQBmz1868xK4zIx5AQifXDsBDrrQ3wdPHnarQV4yI0wcyzcI0QnVzRJ42++O4Hg== + integrity: sha512-guDU8PdEdKCVnGxNd1JEkmqukDoc1wodkEqQCWpY1+bX4ZT+ZY520gfVcMeMHYCEO8TAAhScGNke/y7p9qBArA== tarball: 'file:projects/testhub.tgz' version: 0.0.0 registry: '' diff --git a/sdk/servicebus/service-bus/README.md b/sdk/servicebus/service-bus/README.md index d678f47f8cd3..83fc52f04837 100644 --- a/sdk/servicebus/service-bus/README.md +++ b/sdk/servicebus/service-bus/README.md @@ -211,13 +211,13 @@ export DEBUG=azure*,rhea* - If you are **not interested in viewing the message transformation** (which consumes lot of console/disk space) then you can set the `DEBUG` environment variable as follows: ```bash -export DEBUG=azure*,rhea*,-rhea:raw,-rhea:message,-azure:amqp-common:datatransformer +export DEBUG=azure*,rhea*,-rhea:raw,-rhea:message,-azure:core-amqp:datatransformer ``` - If you are interested only in **errors**, then you can set the `DEBUG` environment variable as follows: ```bash -export DEBUG=azure:service-bus:error,azure-amqp-common:error,rhea-promise:error,rhea:events,rhea:frames,rhea:io,rhea:flow +export DEBUG=azure:service-bus:error,azure-core-amqp:error,rhea-promise:error,rhea:events,rhea:frames,rhea:io,rhea:flow ``` ### Logging to a file diff --git a/sdk/servicebus/service-bus/karma.conf.js b/sdk/servicebus/service-bus/karma.conf.js index 69c0de01ce12..fca58d64e696 100644 --- a/sdk/servicebus/service-bus/karma.conf.js +++ b/sdk/servicebus/service-bus/karma.conf.js @@ -49,9 +49,9 @@ module.exports = function(config) { // https://www.npmjs.com/package/karma-env-preprocessor envPreprocessor: [ "SERVICEBUS_CONNECTION_STRING", - "AAD_CLIENT_ID", - "AAD_CLIENT_SECRET", - "AAD_TENANT_ID" + "AZURE_CLIENT_ID", + "AZURE_CLIENT_SECRET", + "AZURE_TENANT_ID" ], // test results reporter to use diff --git a/sdk/servicebus/service-bus/package.json b/sdk/servicebus/service-bus/package.json index 81170af1f69d..fa2e339f193e 100644 --- a/sdk/servicebus/service-bus/package.json +++ b/sdk/servicebus/service-bus/package.json @@ -2,7 +2,7 @@ "name": "@azure/service-bus", "sdk-type": "client", "author": "Microsoft Corporation", - "version": "1.1.3", + "version": "2.0.0-preview.1", "license": "MIT", "description": "Azure Service Bus SDK for Node.js", "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/servicebus/service-bus", @@ -20,7 +20,6 @@ "module": "dist-esm/src/index.js", "browser": { "./dist/index.js": "./browser/service-bus.js", - "./dist-esm/test/utils/aadUtils.js": "./dist-esm/test/utils/aadUtils.browser.js", "./dist-esm/src/util/crypto.js": "./dist-esm/src/util/crypto.browser.js", "./dist-esm/src/util/parseUrl.js": "./dist-esm/src/util/parseUrl.browser.js", "buffer": "buffer", @@ -78,9 +77,8 @@ ] }, "dependencies": { - "@azure/amqp-common": "1.0.0-preview.10", + "@azure/core-amqp": "^1.0.1", "@azure/core-http": "^1.0.0", - "@azure/ms-rest-nodeauth": "^0.9.2", "@opentelemetry/types": "^0.2.0", "@types/is-buffer": "^2.0.0", "@types/long": "^4.0.0", @@ -89,12 +87,12 @@ "is-buffer": "^2.0.3", "long": "^4.0.0", "process": "^0.11.10", - "rhea": "^1.0.18", - "rhea-promise": "^0.1.15", - "tslib": "^1.10.0" + "tslib": "^1.10.0", + "rhea-promise": "^1.0.0" }, "devDependencies": { "@azure/eslint-plugin-azure-sdk": "^2.0.1", + "@azure/identity": "^1.0.0", "@microsoft/api-extractor": "^7.5.4", "@rollup/plugin-commonjs": "^11.0.1", "@rollup/plugin-inject": "^4.0.0", diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index 8c16f2a87610..b8ced41b2b83 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -4,21 +4,17 @@ ```ts -import { AmqpMessage } from '@azure/amqp-common'; -import { ApplicationTokenCredentials } from '@azure/ms-rest-nodeauth'; -import { DataTransformer } from '@azure/amqp-common'; -import { DefaultDataTransformer } from '@azure/amqp-common'; -import { delay } from '@azure/amqp-common'; +import { AmqpMessage } from '@azure/core-amqp'; +import { DataTransformer } from '@azure/core-amqp'; +import { DefaultDataTransformer } from '@azure/core-amqp'; +import { delay } from '@azure/core-amqp'; import { Delivery } from 'rhea-promise'; -import { DeviceTokenCredentials } from '@azure/ms-rest-nodeauth'; import { HttpOperationResponse } from '@azure/core-http'; import Long from 'long'; -import { MessagingError } from '@azure/amqp-common'; -import { MSITokenCredentials } from '@azure/ms-rest-nodeauth'; -import { TokenInfo } from '@azure/amqp-common'; -import { TokenProvider } from '@azure/amqp-common'; -import { TokenType } from '@azure/amqp-common'; -import { UserTokenCredentials } from '@azure/ms-rest-nodeauth'; +import { MessagingError } from '@azure/core-amqp'; +import { RetryOptions } from '@azure/core-amqp'; +import { TokenCredential } from '@azure/core-amqp'; +import { TokenType } from '@azure/core-amqp'; import { WebSocketImpl } from 'rhea-promise'; // @public @@ -192,6 +188,8 @@ export class Receiver { renewMessageLock(lockTokenOrMessage: string | ServiceBusMessage): Promise; } +export { RetryOptions } + // @public export interface RuleDescription { action?: string; @@ -249,10 +247,9 @@ export class Sender { // @public export class ServiceBusClient { + constructor(connectionString: string, options?: ServiceBusClientOptions); + constructor(host: string, credential: TokenCredential, options?: ServiceBusClientOptions); close(): Promise; - static createFromAadTokenCredentials(host: string, credentials: ApplicationTokenCredentials | UserTokenCredentials | DeviceTokenCredentials | MSITokenCredentials, options?: ServiceBusClientOptions): ServiceBusClient; - static createFromConnectionString(connectionString: string, options?: ServiceBusClientOptions): ServiceBusClient; - static createFromTokenProvider(host: string, tokenProvider: TokenProvider, options?: ServiceBusClientOptions): ServiceBusClient; createQueueClient(queueName: string): QueueClient; createSubscriptionClient(topicName: string, subscriptionName: string): SubscriptionClient; createTopicClient(topicName: string): TopicClient; @@ -419,9 +416,7 @@ export interface SubscriptionOptions { userMetadata?: string; } -export { TokenInfo } - -export { TokenProvider } +export { TokenCredential } export { TokenType } diff --git a/sdk/servicebus/service-bus/src/clientEntityContext.ts b/sdk/servicebus/service-bus/src/clientEntityContext.ts index ab2b33815e5b..57d2fb93d8fb 100644 --- a/sdk/servicebus/service-bus/src/clientEntityContext.ts +++ b/sdk/servicebus/service-bus/src/clientEntityContext.ts @@ -13,11 +13,12 @@ import { ConcurrentExpiringMap } from "./util/concurrentExpiringMap"; import { MessageReceiver } from "./core/messageReceiver"; import { MessageSession } from "./session/messageSession"; import { SessionManager } from "./session/sessionManager"; +import { MessagingError } from "@azure/core-amqp"; /** * @interface ClientEntityContext * Provides contextual information like the underlying amqp connection, cbs session, - * management session, tokenProvider, senders, receivers, etc. about the ServiceBus client. + * management session, tokenCredential, senders, receivers, etc. about the ServiceBus client. * @internal */ export interface ClientEntityContextBase { @@ -148,10 +149,11 @@ export namespace ClientEntityContext { (entityContext as ClientEntityContext).getReceiver = (name: string, sessionId?: string) => { if (sessionId != undefined && entityContext.expiredMessageSessions[sessionId]) { - const error = new Error( + const error = new MessagingError( `The session lock has expired on the session with id ${sessionId}.` ); - error.name = "SessionLockLostError"; + error.code = "SessionLockLostError"; + error.retryable = false; log.error( "[%s] Failed to find receiver '%s' as the session with id '%s' is expired", entityContext.namespace.connectionId, diff --git a/sdk/servicebus/service-bus/src/connectionContext.ts b/sdk/servicebus/service-bus/src/connectionContext.ts index 5a572e641371..d50845d01477 100644 --- a/sdk/servicebus/service-bus/src/connectionContext.ts +++ b/sdk/servicebus/service-bus/src/connectionContext.ts @@ -11,8 +11,9 @@ import { CreateConnectionContextBaseParameters, Dictionary, delay, - TokenProvider -} from "@azure/amqp-common"; + TokenCredential, + SharedKeyCredential +} from "@azure/core-amqp"; import { ServiceBusClientOptions } from "./serviceBusClient"; import { ClientEntityContext } from "./clientEntityContext"; import { OnAmqpEvent, EventContext, ConnectionEvents } from "rhea-promise"; @@ -21,7 +22,7 @@ import { OnAmqpEvent, EventContext, ConnectionEvents } from "rhea-promise"; * @internal * @interface ConnectionContext * Provides contextual information like the underlying amqp connection, cbs session, management session, - * tokenProvider, senders, receivers, etc. about the ServiceBus client. + * tokenCredential, senders, receivers, etc. about the ServiceBus client. */ export interface ConnectionContext extends ConnectionContextBase { /** @@ -45,13 +46,13 @@ export namespace ConnectionContext { export function create( config: ConnectionConfig, - tokenProvider: TokenProvider, + tokenCredential: SharedKeyCredential | TokenCredential, options?: ServiceBusClientOptions ): ConnectionContext { if (!options) options = {}; const parameters: CreateConnectionContextBaseParameters = { config: config, - tokenProvider: tokenProvider, + tokenCredential: tokenCredential, dataTransformer: options.dataTransformer, isEntityPathRequired: false, connectionProperties: { diff --git a/sdk/servicebus/service-bus/src/core/batchingReceiver.ts b/sdk/servicebus/service-bus/src/core/batchingReceiver.ts index 71a0d9569bbb..de57886b56f0 100644 --- a/sdk/servicebus/service-bus/src/core/batchingReceiver.ts +++ b/sdk/servicebus/service-bus/src/core/batchingReceiver.ts @@ -2,7 +2,7 @@ // Licensed under the MIT License. import * as log from "../log"; -import { Constants, translate, MessagingError } from "@azure/amqp-common"; +import { Constants, translate, MessagingError } from "@azure/core-amqp"; import { ReceiverEvents, EventContext, OnAmqpEvent, SessionEvents, AmqpError } from "rhea-promise"; import { ServiceBusMessage, ReceiveMode } from "../serviceBusMessage"; import { @@ -77,7 +77,7 @@ export class BatchingReceiver extends MessageReceiver { throwErrorIfConnectionClosed(this._context.namespace); if (maxWaitTimeInSeconds == null) { - maxWaitTimeInSeconds = Constants.defaultOperationTimeoutInSeconds; + maxWaitTimeInSeconds = Constants.defaultOperationTimeoutInMs / 1000; } const brokeredMessages: ServiceBusMessage[] = []; @@ -95,7 +95,7 @@ export class BatchingReceiver extends MessageReceiver { receiver.session.removeListener(SessionEvents.sessionError, onSessionError); const sessionError = context.session && context.session.error; - let error = new MessagingError("An error occurred while receiving messages."); + let error: Error | MessagingError; if (sessionError) { error = translate(sessionError); log.error( @@ -104,6 +104,8 @@ export class BatchingReceiver extends MessageReceiver { this.name, error ); + } else { + error = new MessagingError("An error occurred while receiving messages."); } if (totalWaitTimer) { clearTimeout(totalWaitTimer); @@ -276,7 +278,7 @@ export class BatchingReceiver extends MessageReceiver { receiver.session.removeListener(SessionEvents.sessionError, onSessionError); const receiverError = context.receiver && context.receiver.error; - let error = new MessagingError("An error occurred while receiving messages."); + let error: Error | MessagingError; if (receiverError) { error = translate(receiverError); log.error( @@ -285,6 +287,8 @@ export class BatchingReceiver extends MessageReceiver { this.name, error ); + } else { + error = new MessagingError("An error occurred while receiving messages."); } if (totalWaitTimer) { clearTimeout(totalWaitTimer); diff --git a/sdk/servicebus/service-bus/src/core/linkEntity.ts b/sdk/servicebus/service-bus/src/core/linkEntity.ts index 26e957a40905..8a40f54b5992 100644 --- a/sdk/servicebus/service-bus/src/core/linkEntity.ts +++ b/sdk/servicebus/service-bus/src/core/linkEntity.ts @@ -1,7 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { defaultLock } from "@azure/amqp-common"; +import { + defaultLock, + TokenType, + AccessToken, + Constants, + SharedKeyCredential +} from "@azure/core-amqp"; import { ClientEntityContext } from "../clientEntityContext"; import * as log from "../log"; import { Sender, Receiver } from "rhea-promise"; @@ -81,6 +87,11 @@ export class LinkEntity { * @protected */ protected _tokenRenewalTimer?: NodeJS.Timer; + /** + * @property _tokenTimeout Indicates token timeout + * @protected + */ + protected _tokenTimeout?: number; /** * Creates a new ClientEntity instance. * @constructor @@ -118,7 +129,24 @@ export class LinkEntity { await defaultLock.acquire(this._context.namespace.cbsSession.cbsLock, () => { return this._context.namespace.cbsSession.init(); }); - const tokenObject = await this._context.namespace.tokenProvider.getToken(this.audience); + let tokenObject: AccessToken; + let tokenType: TokenType; + if (this._context.namespace.tokenCredential instanceof SharedKeyCredential) { + tokenObject = this._context.namespace.tokenCredential.getToken(this.audience); + tokenType = TokenType.CbsTokenTypeSas; + // renew sas token in every 45 minutess + this._tokenTimeout = (3600 - 900) * 1000; + } else { + const aadToken = await this._context.namespace.tokenCredential.getToken( + Constants.aadServiceBusScope + ); + if (!aadToken) { + throw new Error(`Failed to get token from the provided "TokenCredential" object`); + } + tokenObject = aadToken; + tokenType = TokenType.CbsTokenTypeJwt; + this._tokenTimeout = tokenObject.expiresOnTimestamp - Date.now() - 2 * 60 * 1000; + } log.link( "[%s] %s: calling negotiateClaim for audience '%s'.", this._context.namespace.connectionId, @@ -134,8 +162,15 @@ export class LinkEntity { this.name, this.address ); + if (!tokenObject) { + throw new Error("Token cannot be null"); + } await defaultLock.acquire(this._context.namespace.negotiateClaimLock, () => { - return this._context.namespace.cbsSession.negotiateClaim(this.audience, tokenObject); + return this._context.namespace.cbsSession.negotiateClaim( + this.audience, + tokenObject, + tokenType + ); }); log.link( "[%s] Negotiated claim for %s '%s' with with address: %s", @@ -155,15 +190,13 @@ export class LinkEntity { * @returns {void} */ protected async _ensureTokenRenewal(): Promise { - const tokenValidTimeInSeconds = this._context.namespace.tokenProvider.tokenValidTimeInSeconds; - const tokenRenewalMarginInSeconds = this._context.namespace.tokenProvider - .tokenRenewalMarginInSeconds; - const nextRenewalTimeout = (tokenValidTimeInSeconds - tokenRenewalMarginInSeconds) * 1000; + if (!this._tokenTimeout) { + return; + } this._tokenRenewalTimer = setTimeout(async () => { try { await this._negotiateClaim(true); } catch (err) { - // TODO: May be add some retries over here before emitting the error. log.error( "[%s] %s '%s' with address %s, an error occurred while renewing the token: %O", this._context.namespace.connectionId, @@ -173,15 +206,15 @@ export class LinkEntity { err ); } - }, nextRenewalTimeout); + }, this._tokenTimeout); log.link( "[%s] %s '%s' with address %s, has next token renewal in %d seconds @(%s).", this._context.namespace.connectionId, this._type, this.name, this.address, - nextRenewalTimeout / 1000, - new Date(Date.now() + nextRenewalTimeout).toString() + this._tokenTimeout / 1000, + new Date(Date.now() + this._tokenTimeout).toString() ); } diff --git a/sdk/servicebus/service-bus/src/core/managementClient.ts b/sdk/servicebus/service-bus/src/core/managementClient.ts index a583608b884b..8ff3b3e6c551 100644 --- a/sdk/servicebus/service-bus/src/core/managementClient.ts +++ b/sdk/servicebus/service-bus/src/core/managementClient.ts @@ -20,8 +20,9 @@ import { RequestResponseLink, ConditionErrorNameMapper, AmqpMessage, - SendRequestOptions -} from "@azure/amqp-common"; + SendRequestOptions, + MessagingError +} from "@azure/core-amqp"; import { ClientEntityContext } from "../clientEntityContext"; import { ReceivedMessageInfo, @@ -240,12 +241,12 @@ export class ManagementClient extends LinkEntity { sropt, rxopt ); - this._mgmtReqResLink.sender.on(SenderEvents.senderError, (context: EventContext) => { + this._mgmtReqResLink!.sender.on(SenderEvents.senderError, (context: EventContext) => { const id = context.connection.options.id; const ehError = translate(context.sender!.error!); log.error("[%s] An error occurred on the $management sender link.. %O", id, ehError); }); - this._mgmtReqResLink.receiver.on(ReceiverEvents.receiverError, (context: EventContext) => { + this._mgmtReqResLink!.receiver.on(ReceiverEvents.receiverError, (context: EventContext) => { const id = context.connection.options.id; const ehError = translate(context.receiver!.error!); log.error("[%s] An error occurred on the $management receiver link.. %O", id, ehError); @@ -253,8 +254,8 @@ export class ManagementClient extends LinkEntity { log.mgmt( "[%s] Created sender '%s' and receiver '%s' links for $management endpoint.", this._context.namespace.connectionId, - this._mgmtReqResLink.sender.name, - this._mgmtReqResLink.receiver.name + this._mgmtReqResLink!.sender.name, + this._mgmtReqResLink!.receiver.name ); await this._ensureTokenRenewal(); } @@ -446,14 +447,14 @@ export class ManagementClient extends LinkEntity { } } } catch (err) { - const error = translate(err); + const error = translate(err) as MessagingError; log.error( "An error occurred while sending the request to peek messages to " + "$management endpoint: %O", error ); // statusCode == 404 then do not throw - if (error.name !== ConditionErrorNameMapper["com.microsoft:message-not-found"]) { + if (error.code !== ConditionErrorNameMapper["com.microsoft:message-not-found"]) { throw error; } } @@ -477,9 +478,7 @@ export class ManagementClient extends LinkEntity { async renewLock(lockToken: string, options?: SendRequestOptions): Promise { throwErrorIfConnectionClosed(this._context.namespace); if (!options) options = {}; - if (options.delayInSeconds == null) options.delayInSeconds = 1; - if (options.timeoutInSeconds == null) options.timeoutInSeconds = 5; - if (options.times == null) options.times = 5; + if (options.timeoutInMs == null) options.timeoutInMs = 5000; try { const messageBody: any = {}; @@ -881,9 +880,7 @@ export class ManagementClient extends LinkEntity { async renewSessionLock(sessionId: string, options?: SendRequestOptions): Promise { throwErrorIfConnectionClosed(this._context.namespace); if (!options) options = {}; - if (options.delayInSeconds == null) options.delayInSeconds = 1; - if (options.timeoutInSeconds == null) options.timeoutInSeconds = 5; - if (options.times == null) options.times = 5; + if (options.timeoutInMs == null) options.timeoutInMs = 5000; try { const messageBody: any = {}; messageBody[Constants.sessionIdMapKey] = sessionId; diff --git a/sdk/servicebus/service-bus/src/core/messageReceiver.ts b/sdk/servicebus/service-bus/src/core/messageReceiver.ts index 43268836ebf6..fd9d84f63756 100644 --- a/sdk/servicebus/service-bus/src/core/messageReceiver.ts +++ b/sdk/servicebus/service-bus/src/core/messageReceiver.ts @@ -10,7 +10,7 @@ import { RetryConfig, ConditionErrorNameMapper, ErrorNameConditionMapper -} from "@azure/amqp-common"; +} from "@azure/core-amqp"; import { Receiver, OnAmqpEvent, @@ -474,11 +474,11 @@ export class MessageReceiver extends LinkEntity { // Do not want renewLock to happen unnecessarily, while abandoning the message. Hence, // doing this here. Otherwise, this should be done in finally. this._clearMessageLockRenewTimer(bMessage.messageId as string); - const error = translate(err); + const error = translate(err) as MessagingError; // Nothing much to do if user's message handler throws. Let us try abandoning the message. if ( !bMessage.delivery.remote_settled && - error.name !== ConditionErrorNameMapper["com.microsoft:message-lock-lost"] && + error.code !== ConditionErrorNameMapper["com.microsoft:message-lock-lost"] && this.receiveMode === ReceiveMode.peekLock && this.isOpen() // only try to abandon the messages if the connection is still open ) { @@ -547,7 +547,7 @@ export class MessageReceiver extends LinkEntity { const receiver = this._receiver || context.receiver!; const receiverError = context.receiver && context.receiver.error; if (receiverError) { - const sbError = translate(receiverError); + const sbError = translate(receiverError) as MessagingError; log.error( "[%s] An error occurred for Receiver '%s': %O.", connectionId, @@ -587,7 +587,7 @@ export class MessageReceiver extends LinkEntity { const receiver = this._receiver || context.receiver!; const sessionError = context.session && context.session.error; if (sessionError) { - const sbError = translate(sessionError); + const sbError = translate(sessionError) as MessagingError; log.error( "[%s] An error occurred on the session for Receiver '%s': %O.", connectionId, @@ -875,7 +875,7 @@ export class MessageReceiver extends LinkEntity { // We should attempt to reopen only when the receiver(sdk) did not initiate the close let shouldReopen = false; if (receiverError && !wasCloseInitiated) { - const translatedError = translate(receiverError); + const translatedError = translate(receiverError) as MessagingError; if (translatedError.retryable) { shouldReopen = true; log.error( @@ -948,9 +948,11 @@ export class MessageReceiver extends LinkEntity { }), connectionId: connectionId, operationType: RetryOperationType.receiverLink, - times: Constants.defaultConnectionRetryAttempts, - connectionHost: this._context.namespace.config.host, - delayInSeconds: 15 + retryOptions: { + maxRetries: Constants.defaultMaxRetriesForConnection, + retryDelayInMs: 15000 + }, + connectionHost: this._context.namespace.config.host }; if (!this.wasCloseInitiated) { await retry(config); @@ -1031,7 +1033,7 @@ export class MessageReceiver extends LinkEntity { "Hence rejecting the promise with timeout error.", this._context.namespace.connectionId, delivery.id, - Constants.defaultOperationTimeoutInSeconds * 1000 + Constants.defaultOperationTimeoutInMs ); const e: AmqpError = { @@ -1041,7 +1043,7 @@ export class MessageReceiver extends LinkEntity { "message may or may not be successful" }; return reject(translate(e)); - }, Constants.defaultOperationTimeoutInSeconds * 1000); + }, Constants.defaultOperationTimeoutInMs); this._deliveryDispositionMap.set(delivery.id, { resolve: resolve, reject: reject, diff --git a/sdk/servicebus/service-bus/src/core/messageSender.ts b/sdk/servicebus/service-bus/src/core/messageSender.ts index 57b428288f21..1c18ee964681 100644 --- a/sdk/servicebus/service-bus/src/core/messageSender.ts +++ b/sdk/servicebus/service-bus/src/core/messageSender.ts @@ -23,9 +23,9 @@ import { RetryConfig, RetryOperationType, Constants, - randomNumberFromInterval, - delay -} from "@azure/amqp-common"; + delay, + MessagingError +} from "@azure/core-amqp"; import { SendableMessageInfo, toAmqpMessage, @@ -374,10 +374,7 @@ export class MessageSender extends LinkEntity { this._sender!.on(SenderEvents.rejected, onRejected); this._sender!.on(SenderEvents.modified, onModified); this._sender!.on(SenderEvents.released, onReleased); - waitTimer = setTimeout( - actionAfterTimeout, - Constants.defaultOperationTimeoutInSeconds * 1000 - ); + waitTimer = setTimeout(actionAfterTimeout, Constants.defaultOperationTimeoutInMs); try { const delivery = this._sender!.send( encodedMessage, @@ -408,13 +405,14 @@ export class MessageSender extends LinkEntity { } }); - const jitterInSeconds = randomNumberFromInterval(1, 4); const config: RetryConfig = { operation: sendEventPromise, connectionId: this._context.namespace.connectionId!, operationType: RetryOperationType.sendMessage, - times: Constants.defaultRetryAttempts, - delayInSeconds: Constants.defaultDelayBetweenOperationRetriesInSeconds + jitterInSeconds + retryOptions: { + maxRetries: Constants.defaultMaxRetries, + retryDelayInMs: Constants.defaultDelayBetweenOperationRetriesInMs + } }; return retry(config); @@ -499,7 +497,7 @@ export class MessageSender extends LinkEntity { // We should attempt to reopen only when the sender(sdk) did not initiate the close let shouldReopen = false; if (senderError && !wasCloseInitiated) { - const translatedError = translate(senderError); + const translatedError = translate(senderError) as MessagingError; if (translatedError.retryable) { shouldReopen = true; log.error( @@ -555,9 +553,11 @@ export class MessageSender extends LinkEntity { operation: () => this._init(options), connectionId: this._context.namespace.connectionId!, operationType: RetryOperationType.senderLink, - times: Constants.defaultConnectionRetryAttempts, - connectionHost: this._context.namespace.config.host, - delayInSeconds: 15 + retryOptions: { + maxRetries: Constants.defaultMaxRetriesForConnection, + retryDelayInMs: 15000 + }, + connectionHost: this._context.namespace.config.host }; return retry(config); }); diff --git a/sdk/servicebus/service-bus/src/index.ts b/sdk/servicebus/service-bus/src/index.ts index 38f261e98982..623de70f31e4 100644 --- a/sdk/servicebus/service-bus/src/index.ts +++ b/sdk/servicebus/service-bus/src/index.ts @@ -6,14 +6,14 @@ export { ServiceBusClient, ServiceBusClientOptions } from "./serviceBusClient"; export { - TokenInfo, TokenType, - TokenProvider, DefaultDataTransformer, + TokenCredential, DataTransformer, delay, - MessagingError -} from "@azure/amqp-common"; + MessagingError, + RetryOptions +} from "@azure/core-amqp"; export { QueueClient } from "./queueClient"; export { TopicClient } from "./topicClient"; diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 6607e256458c..d098e616b425 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -16,7 +16,7 @@ import { RestError } from "@azure/core-http"; -import { SasTokenProvider, parseConnectionString } from "@azure/amqp-common"; +import { parseConnectionString, SharedKeyCredential } from "@azure/core-amqp"; import { AtomXmlSerializer, executeAtomXmlOperation } from "./util/atomXmlHelper"; @@ -350,7 +350,7 @@ export class ServiceBusAtomManagementClient extends ServiceClient { /** * SAS token provider used to generate tokens as required for the various operations. */ - private sasTokenProvider: SasTokenProvider; + private sasTokenProvider: SharedKeyCredential; /** * Initializes a new instance of the ServiceBusManagementClient class. @@ -387,8 +387,7 @@ export class ServiceBusAtomManagementClient extends ServiceClient { this.endpoint = (connectionString.match("Endpoint=sb://(.*)/;") || "")[1]; this.endpointWithProtocol = connectionStringObj.Endpoint; - this.sasTokenProvider = new SasTokenProvider( - connectionStringObj.Endpoint, + this.sasTokenProvider = new SharedKeyCredential( connectionStringObj.SharedAccessKeyName, connectionStringObj.SharedAccessKey ); diff --git a/sdk/servicebus/service-bus/src/serviceBusClient.ts b/sdk/servicebus/service-bus/src/serviceBusClient.ts index 126daf43d001..cb43d24ea26d 100644 --- a/sdk/servicebus/service-bus/src/serviceBusClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusClient.ts @@ -3,13 +3,6 @@ import * as log from "./log"; -import { - ApplicationTokenCredentials, - DeviceTokenCredentials, - UserTokenCredentials, - MSITokenCredentials -} from "@azure/ms-rest-nodeauth"; - import { WebSocketImpl } from "rhea-promise"; import { ConnectionContext } from "./connectionContext"; import { QueueClient } from "./queueClient"; @@ -17,12 +10,11 @@ import { TopicClient } from "./topicClient"; import { ConnectionConfig, DataTransformer, - TokenProvider, - AadTokenProvider, - SasTokenProvider -} from "@azure/amqp-common"; + TokenCredential, + SharedKeyCredential, + isTokenCredential +} from "@azure/core-amqp"; import { SubscriptionClient } from "./subscriptionClient"; -import { isNode } from "./util/utils"; /** * Describes the options that can be provided while creating the ServiceBusClient. @@ -65,25 +57,68 @@ export class ServiceBusClient { */ private _context: ConnectionContext; + /** + * Creates a ServiceBusClient for the Service Bus Namespace represented in the given connection + * string. + * @param connectionString - Connection string of the form + * 'Endpoint=sb://my-servicebus-namespace.servicebus.windows.net/;SharedAccessKeyName=my-SA-name;SharedAccessKey=my-SA-key' + * @param options Options to control ways to interact with the + * Service Bus Namespace. + * @returns ServiceBusClient + */ + constructor(connectionString: string, options?: ServiceBusClientOptions); + /** * Instantiates a ServiceBusClient to interact with a Service Bus Namespace. * * @constructor - * @param {ConnectionConfig} config - The connection configuration needed to connect to the - * Service Bus Namespace. - * @param {TokenProvider} [tokenProvider] - The token provider that provides the token for - * authentication. - * @param {ServiceBusClientOptions} - Options to control ways to interact with the Service Bus + * @param host - The host name for the Service Bus namespace. This is likely to be similar to + * .servicebus.windows.net + * @param credential - credential that implements the TokenCredential interface. + * @param options - Options to control ways to interact with the Service Bus * Namespace. */ - private constructor( - config: ConnectionConfig, - tokenProvider: TokenProvider, + constructor(host: string, credential: TokenCredential, options?: ServiceBusClientOptions); + + constructor( + hostOrConnectionString: string, + credentialOrServiceBusClientOptions?: TokenCredential | ServiceBusClientOptions, options?: ServiceBusClientOptions ) { - if (!options) options = {}; + let config; + let credential; + + if (!isTokenCredential(credentialOrServiceBusClientOptions)) { + // connectionString and options based constructor was invoked + config = ConnectionConfig.create(hostOrConnectionString); + + options = credentialOrServiceBusClientOptions as ServiceBusClientOptions; + config.webSocket = options && options.webSocket; + config.webSocketEndpointPath = "$servicebus/websocket"; + config.webSocketConstructorOptions = options && options.webSocketConstructorOptions; + + // Since connectionstring was passed, create a SharedKeyCredential + credential = new SharedKeyCredential(config.sharedAccessKeyName, config.sharedAccessKey); + + ConnectionConfig.validate(config); + } else { + // host, credential and options based constructor was invoked + credential = credentialOrServiceBusClientOptions as TokenCredential; + + hostOrConnectionString = String(hostOrConnectionString); + if (!hostOrConnectionString.endsWith("/")) { + hostOrConnectionString += "/"; + } + const connectionString = `Endpoint=sb://${hostOrConnectionString};SharedAccessKeyName=defaultKeyName;SharedAccessKey=defaultKeyValue;`; + config = ConnectionConfig.create(connectionString); + } + + if (!options) { + options = {}; + } + this.name = config.endpoint; - this._context = ConnectionContext.create(config, tokenProvider, options); + this._context = ConnectionContext.create(config, credential, options); } /** @@ -161,102 +196,4 @@ export class ServiceBusClient { throw errObj; } } - - /** - * Creates a ServiceBusClient for the Service Bus Namespace represented in the given connection - * string. - * @param {string} connectionString - Connection string of the form - * 'Endpoint=sb://my-servicebus-namespace.servicebus.windows.net/;SharedAccessKeyName=my-SA-name;SharedAccessKey=my-SA-key' - * @param {ServiceBusClientOptions} [options] Options to control ways to interact with the - * Service Bus Namespace. - * @returns {ServiceBusClient} - */ - static createFromConnectionString( - connectionString: string, - options?: ServiceBusClientOptions - ): ServiceBusClient { - const config = ConnectionConfig.create(connectionString); - - config.webSocket = options && options.webSocket; - config.webSocketEndpointPath = "$servicebus/websocket"; - config.webSocketConstructorOptions = options && options.webSocketConstructorOptions; - - ConnectionConfig.validate(config); - const tokenProvider = new SasTokenProvider( - config.endpoint, - config.sharedAccessKeyName, - config.sharedAccessKey - ); - return new ServiceBusClient(config, tokenProvider, options); - } - - /** - * Creates a ServiceBusClient for the Service Bus Namespace represented by the given host using - * the given TokenProvider. - * @param {string} host - Fully qualified domain name for Servicebus. Most likely, - * `.servicebus.windows.net`. - * @param {TokenProvider} tokenProvider - Your custom implementation of the {@link https://github.com/Azure/amqp-common-js/blob/master/lib/auth/token.ts Token Provider} - * interface. - * @param {ServiceBusClientOptions} options - Options to control ways to interact with the - * Service Bus Namespace. - * @returns {ServiceBusClient} - */ - static createFromTokenProvider( - host: string, - tokenProvider: TokenProvider, - options?: ServiceBusClientOptions - ): ServiceBusClient { - host = String(host); - if (!tokenProvider) { - throw new TypeError('Missing parameter "tokenProvider"'); - } - if (!host.endsWith("/")) host += "/"; - const connectionString = - `Endpoint=sb://${host};SharedAccessKeyName=defaultKeyName;` + - `SharedAccessKey=defaultKeyValue`; - const config = ConnectionConfig.create(connectionString); - - config.webSocket = options && options.webSocket; - config.webSocketEndpointPath = "$servicebus/websocket"; - config.webSocketConstructorOptions = options && options.webSocketConstructorOptions; - - ConnectionConfig.validate(config); - return new ServiceBusClient(config, tokenProvider, options); - } - - /** - * Creates a ServiceBusClient for the Service Bus Namespace represented by the given host using - * the TokenCredentials generated using the `@azure/ms-rest-nodeauth` library. - * @param {string} host - Fully qualified domain name for ServiceBus. - * Most likely, {yournamespace}.servicebus.windows.net - * @param {ServiceClientCredentials} credentials - The Token credentials generated by using the - * `@azure/ms-rest-nodeauth` library. It can be one of the following: - * - ApplicationTokenCredentials - * - UserTokenCredentials - * - DeviceTokenCredentials - * - MSITokenCredentials - * Token audience (or resource in case of MSI based credentials) to use when creating the credentials is https://servicebus.azure.net/ - * @param {ServiceBusClientOptions} options - Options to control ways to interact with the - * Service Bus Namespace. - * @returns {ServiceBusClient} - * @throws Error if `createFromAadTokenCredentials` is accessed in browser context, as AAD support is not present in browser. - */ - static createFromAadTokenCredentials( - host: string, - credentials: - | ApplicationTokenCredentials - | UserTokenCredentials - | DeviceTokenCredentials - | MSITokenCredentials, - options?: ServiceBusClientOptions - ): ServiceBusClient { - if (!isNode) { - throw new Error( - "`createFromAadTokenCredentials` cannot be used to create ServiceBusClient as AAD support is not present in browser." - ); - } - host = String(host); - const tokenProvider = new AadTokenProvider(credentials); - return ServiceBusClient.createFromTokenProvider(host, tokenProvider, options); - } } diff --git a/sdk/servicebus/service-bus/src/serviceBusMessage.ts b/sdk/servicebus/service-bus/src/serviceBusMessage.ts index 8cc04e65314b..7228caea6fe7 100644 --- a/sdk/servicebus/service-bus/src/serviceBusMessage.ts +++ b/sdk/servicebus/service-bus/src/serviceBusMessage.ts @@ -9,7 +9,7 @@ import { MessageAnnotations, DeliveryAnnotations } from "rhea-promise"; -import { Constants, AmqpMessage, translate, ErrorNameConditionMapper } from "@azure/amqp-common"; +import { Constants, AmqpMessage, translate, ErrorNameConditionMapper } from "@azure/core-amqp"; import * as log from "./log"; import { ClientEntityContext } from "./clientEntityContext"; import { reorderLockToken } from "../src/util/utils"; diff --git a/sdk/servicebus/service-bus/src/session/messageSession.ts b/sdk/servicebus/service-bus/src/session/messageSession.ts index 82ebd69c5079..3a6b637eb50d 100644 --- a/sdk/servicebus/service-bus/src/session/messageSession.ts +++ b/sdk/servicebus/service-bus/src/session/messageSession.ts @@ -7,7 +7,7 @@ import { ErrorNameConditionMapper, MessagingError, Func -} from "@azure/amqp-common"; +} from "@azure/core-amqp"; import { Receiver, OnAmqpEvent, @@ -280,9 +280,7 @@ export class MessageSession extends LinkEntity { this.sessionLockedUntilUtc = await this._context.managementClient!.renewSessionLock( this.sessionId!, { - delayInSeconds: 0, - timeoutInSeconds: 10, - times: 4 + timeoutInMs: 10000 } ); log.receiver( @@ -551,8 +549,8 @@ export class MessageSession extends LinkEntity { const connectionId = this._context.namespace.connectionId; const receiverError = context.receiver && context.receiver.error; if (receiverError) { - const sbError = translate(receiverError); - if (sbError.name === "SessionLockLostError") { + const sbError = translate(receiverError) as MessagingError; + if (sbError.code === "SessionLockLostError") { this._context.expiredMessageSessions[this.sessionId!] = true; sbError.message = `The session lock has expired on the session with id ${this.sessionId}.`; } @@ -587,8 +585,8 @@ export class MessageSession extends LinkEntity { const receiver = this._receiver || context.receiver!; let isClosedDueToExpiry = false; if (receiverError) { - const sbError = translate(receiverError); - if (sbError.name === "SessionLockLostError") { + const sbError = translate(receiverError) as MessagingError; + if (sbError.code === "SessionLockLostError") { isClosedDueToExpiry = true; } log.error( @@ -929,7 +927,7 @@ export class MessageSession extends LinkEntity { maxWaitTimeInSeconds?: number ): Promise { if (maxWaitTimeInSeconds == null) { - maxWaitTimeInSeconds = Constants.defaultOperationTimeoutInSeconds; + maxWaitTimeInSeconds = Constants.defaultOperationTimeoutInMs / 1000; } const brokeredMessages: ServiceBusMessage[] = []; @@ -1150,7 +1148,7 @@ export class MessageSession extends LinkEntity { "Hence rejecting the promise with timeout error", this._context.namespace.connectionId, delivery.id, - Constants.defaultOperationTimeoutInSeconds * 1000 + Constants.defaultOperationTimeoutInMs ); const e: AmqpError = { @@ -1160,7 +1158,7 @@ export class MessageSession extends LinkEntity { "message may or may not be successful" }; return reject(translate(e)); - }, Constants.defaultOperationTimeoutInSeconds * 1000); + }, Constants.defaultOperationTimeoutInMs); this._deliveryDispositionMap.set(delivery.id, { resolve: resolve, reject: reject, diff --git a/sdk/servicebus/service-bus/src/session/sessionManager.ts b/sdk/servicebus/service-bus/src/session/sessionManager.ts index 5530c306aa6b..bd255627bcc5 100644 --- a/sdk/servicebus/service-bus/src/session/sessionManager.ts +++ b/sdk/servicebus/service-bus/src/session/sessionManager.ts @@ -7,7 +7,7 @@ import { ClientEntityContext } from "../clientEntityContext"; import { getProcessorCount } from "../util/utils"; import * as log from "../log"; import { Semaphore } from "../util/semaphore"; -import { delay, ConditionErrorNameMapper, Constants } from "@azure/amqp-common"; +import { delay, ConditionErrorNameMapper, Constants, MessagingError } from "@azure/core-amqp"; /** * @internal @@ -151,7 +151,10 @@ export class SessionManager { error ); await closeMessageSession(messageSession); - if (error.name !== ConditionErrorNameMapper["com.microsoft:message-wait-timeout"]) { + if ( + (error as MessagingError).code !== + ConditionErrorNameMapper["com.microsoft:message-wait-timeout"] + ) { // notify the user about the error. onError(error); } @@ -178,9 +181,9 @@ export class SessionManager { // the Promise is rejected. The "microsoft.timeout" error occurs when timeout happens on // the server side and ServiceBus sends a detach frame due to which the Promise is rejected. if ( - err.name === ConditionErrorNameMapper["amqp:operation-timeout"] || - err.name === ConditionErrorNameMapper["com.microsoft:timeout"] || - err.name === ConditionErrorNameMapper["com.microsoft:session-cannot-be-locked"] + err.code === "OperationTimeoutError" || + err.code === ConditionErrorNameMapper["com.microsoft:timeout"] || + err.code === ConditionErrorNameMapper["com.microsoft:session-cannot-be-locked"] ) { // No point in delaying if cancel has been requested. if (!this._isCancelRequested) { @@ -239,7 +242,7 @@ export class SessionManager { // We are explicitly configuring the messageSession to timeout in 60 seconds (if not provided // by the user) when no new messages are received. if (!options.newMessageWaitTimeoutInSeconds) { - options.newMessageWaitTimeoutInSeconds = Constants.defaultOperationTimeoutInSeconds; + options.newMessageWaitTimeoutInSeconds = Constants.defaultOperationTimeoutInMs / 1000; } this._maxConcurrentSessionsSemaphore = new Semaphore(this.maxConcurrenSessions); this._maxPendingAcceptSessionsSemaphore = new Semaphore( diff --git a/sdk/servicebus/service-bus/src/util/concurrentExpiringMap.ts b/sdk/servicebus/service-bus/src/util/concurrentExpiringMap.ts index 0afd31e4d086..3dc898f6d2a6 100644 --- a/sdk/servicebus/service-bus/src/util/concurrentExpiringMap.ts +++ b/sdk/servicebus/service-bus/src/util/concurrentExpiringMap.ts @@ -2,7 +2,7 @@ // Licensed under the MIT License. import { generate_uuid } from "rhea-promise"; -import { delay, AsyncLock } from "@azure/amqp-common"; +import { delay, AsyncLock } from "@azure/core-amqp"; import * as log from "../log"; /** diff --git a/sdk/servicebus/service-bus/src/util/constants.ts b/sdk/servicebus/service-bus/src/util/constants.ts index dc1ca18a3f1e..408d5d885493 100644 --- a/sdk/servicebus/service-bus/src/util/constants.ts +++ b/sdk/servicebus/service-bus/src/util/constants.ts @@ -3,7 +3,7 @@ export const packageJsonInfo = { name: "@azure/service-bus", - version: "1.1.3" + version: "2.0.0-preview.1" }; export const messageDispositionTimeout = 20000; diff --git a/sdk/servicebus/service-bus/test/README.md b/sdk/servicebus/service-bus/test/README.md index 38c936b47697..5b42d8f8a4ac 100644 --- a/sdk/servicebus/service-bus/test/README.md +++ b/sdk/servicebus/service-bus/test/README.md @@ -35,9 +35,9 @@ Go through the following setup in order to correctly setup the AAD credentials f Populate the following variables along with the above mentioned environment variables in the `.env`. ``` -AAD_CLIENT_ID="" -AAD_CLIENT_SECRET="" -AAD_TENANT_ID="" +AZURE_CLIENT_ID="" +AZURE_CLIENT_SECRET="" +AZURE_TENANT_ID="" ``` ## Run all tests diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index 0183dec1df88..076be79732c7 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -20,7 +20,7 @@ const env = getEnvVars(); import { EntityNames } from "./utils/testUtils"; -import { parseConnectionString } from "@azure/amqp-common"; +import { parseConnectionString } from "@azure/core-amqp"; import { recreateQueue, recreateTopic, recreateSubscription } from "./utils/managementUtils"; const serviceBusAtomManagementClient: ServiceBusAtomManagementClient = new ServiceBusAtomManagementClient( diff --git a/sdk/servicebus/service-bus/test/batchReceiver.spec.ts b/sdk/servicebus/service-bus/test/batchReceiver.spec.ts index 6c14f8983570..07b01068b3c4 100644 --- a/sdk/servicebus/service-bus/test/batchReceiver.spec.ts +++ b/sdk/servicebus/service-bus/test/batchReceiver.spec.ts @@ -687,7 +687,7 @@ describe("Batch Receiver - Settle deadlettered message", function(): void { const deadLetterMsg = await deadLetterMessage(testMessage); await deadLetterMsg.deadLetter().catch((err) => { - should.equal(err.name, "InvalidOperationError", "ErrorName is different than expected"); + should.equal(err.code, "InvalidOperationError", "Error code is different than expected"); errorWasThrown = true; }); diff --git a/sdk/servicebus/service-bus/test/perf/service-bus/receive.ts b/sdk/servicebus/service-bus/test/perf/service-bus/receive.ts index 5a84d14a5955..d9e4f0c189a4 100644 --- a/sdk/servicebus/service-bus/test/perf/service-bus/receive.ts +++ b/sdk/servicebus/service-bus/test/perf/service-bus/receive.ts @@ -41,7 +41,7 @@ async function RunTest( maxConcurrentCalls: number, messages: number ): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(entityPath); const receiver = client.createReceiver(ReceiveMode.receiveAndDelete); diff --git a/sdk/servicebus/service-bus/test/perf/service-bus/send.ts b/sdk/servicebus/service-bus/test/perf/service-bus/send.ts index 40970568082a..2ec9d571b7d0 100644 --- a/sdk/servicebus/service-bus/test/perf/service-bus/send.ts +++ b/sdk/servicebus/service-bus/test/perf/service-bus/send.ts @@ -42,7 +42,7 @@ async function RunTest( maxInflight: number, messages: number ): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(entityPath); const sender = client.createSender(); diff --git a/sdk/servicebus/service-bus/test/renewLock.spec.ts b/sdk/servicebus/service-bus/test/renewLock.spec.ts index 980acdab015e..45e3e88e5e22 100644 --- a/sdk/servicebus/service-bus/test/renewLock.spec.ts +++ b/sdk/servicebus/service-bus/test/renewLock.spec.ts @@ -315,7 +315,7 @@ async function testBatchReceiverManualLockRenewalErrorOnLockExpiry( let errorWasThrown: boolean = false; await msgs[0].complete().catch((err) => { - should.equal(err.name, "MessageLockLostError", "ErrorName is different than expected"); + should.equal(err.code, "MessageLockLostError", "Error code is different than expected"); errorWasThrown = true; }); @@ -433,7 +433,7 @@ async function testAutoLockRenewalConfigBehavior( let errorWasThrown: boolean = false; await brokeredMessage.complete().catch((err) => { - should.equal(err.name, "MessageLockLostError", "ErrorName is different than expected"); + should.equal(err.code, "MessageLockLostError", "Error code is different than expected"); errorWasThrown = true; }); diff --git a/sdk/servicebus/service-bus/test/renewLockSessions.spec.ts b/sdk/servicebus/service-bus/test/renewLockSessions.spec.ts index 8ed067c41db3..d2c707a4d180 100644 --- a/sdk/servicebus/service-bus/test/renewLockSessions.spec.ts +++ b/sdk/servicebus/service-bus/test/renewLockSessions.spec.ts @@ -23,7 +23,8 @@ import { getSenderReceiverClients, TestClientType, TestMessage, - getServiceBusClient + getServiceBusClient, + isMessagingError } from "./utils/testUtils"; let sbClient: ServiceBusClient; @@ -328,7 +329,7 @@ async function testBatchReceiverManualLockRenewalErrorOnLockExpiry( let errorWasThrown: boolean = false; await msgs[0].complete().catch((err) => { - should.equal(err.name, "SessionLockLostError", "ErrorName is different than expected"); + should.equal(err.code, "SessionLockLostError", "Error code is different than expected"); errorWasThrown = true; }); @@ -461,7 +462,7 @@ async function testAutoLockRenewalConfigBehavior( } }, (err: MessagingError | Error) => { - if (err.name === "SessionLockLostError") { + if (isMessagingError(err) && err.code === "SessionLockLostError") { sessionLockLostErrorThrown = true; } else { onError(err); @@ -482,7 +483,7 @@ async function testAutoLockRenewalConfigBehavior( let errorWasThrown: boolean = false; await messagesReceived[0].complete().catch((err) => { - should.equal(err.name, "SessionLockLostError", "ErrorName is different than expected"); + should.equal(err.code, "SessionLockLostError", "Error code is different than expected"); errorWasThrown = true; }); diff --git a/sdk/servicebus/service-bus/test/serviceBusClient.spec.ts b/sdk/servicebus/service-bus/test/serviceBusClient.spec.ts index 970bb04dc02b..1878c31d2b7d 100644 --- a/sdk/servicebus/service-bus/test/serviceBusClient.spec.ts +++ b/sdk/servicebus/service-bus/test/serviceBusClient.spec.ts @@ -14,7 +14,8 @@ import { SessionReceiver, SubscriptionClient, TopicClient, - ServiceBusMessage + ServiceBusMessage, + MessagingError } from "../src"; import { getClientClosedErrorMsg, @@ -28,16 +29,21 @@ import { getSenderReceiverClients, purge, TestMessage, - getServiceBusClient + getServiceBusClient, + isMessagingError } from "./utils/testUtils"; import { ClientType } from "../src/client"; import { DispositionType } from "../src/serviceBusMessage"; -import { getEnvVars, isNode } from "./utils/envVarUtils"; -import { getTokenCredentialsFromAAD } from "./utils/aadUtils"; const should = chai.should(); chai.use(chaiAsPromised); +import { EnvVarNames, getEnvVars, isNode } from "../test/utils/envVarUtils"; +import * as dotenv from "dotenv"; +dotenv.config(); + +import { EnvironmentCredential } from "@azure/identity"; + describe("Create ServiceBusClient and Queue/Topic/Subscription Clients #RunInBrowser", function(): void { let sbClient: ServiceBusClient; @@ -48,7 +54,7 @@ describe("Create ServiceBusClient and Queue/Topic/Subscription Clients #RunInBro }); it("Creates an Namespace from a connection string", function(): void { - sbClient = ServiceBusClient.createFromConnectionString( + sbClient = new ServiceBusClient( "Endpoint=sb://a;SharedAccessKeyName=b;SharedAccessKey=c;EntityPath=d" ); sbClient.should.be.an.instanceof(ServiceBusClient); @@ -56,7 +62,7 @@ describe("Create ServiceBusClient and Queue/Topic/Subscription Clients #RunInBro }); it("Creates clients after coercing name to string", function(): void { - sbClient = ServiceBusClient.createFromConnectionString( + sbClient = new ServiceBusClient( "Endpoint=sb://a;SharedAccessKeyName=b;SharedAccessKey=c;EntityPath=d" ); const queueClient = sbClient.createQueueClient(1 as any); @@ -68,29 +74,13 @@ describe("Create ServiceBusClient and Queue/Topic/Subscription Clients #RunInBro const subscriptionClient = sbClient.createSubscriptionClient(1 as any, 2 as any); should.equal(subscriptionClient.entityPath, "1/Subscriptions/2"); }); - - it("Missing tokenProvider in createFromTokenProvider", function(): void { - let caughtError: Error | undefined; - try { - sbClient = ServiceBusClient.createFromTokenProvider("somestring", undefined as any); - } catch (error) { - caughtError = error; - } - should.equal(caughtError && caughtError.name, "TypeError"); - should.equal(caughtError && caughtError.message, `Missing parameter "tokenProvider"`); - }); - - it("Coerces input to string for host in createFromTokenProvider", function(): void { - sbClient = ServiceBusClient.createFromTokenProvider(123 as any, {} as any); - should.equal(sbClient.name, "sb://123/", "Name of the namespace is different than expected"); - }); }); describe("Errors with non existing Namespace #RunInBrowser", function(): void { let sbClient: ServiceBusClient; let errorWasThrown: boolean; beforeEach(() => { - sbClient = ServiceBusClient.createFromConnectionString( + sbClient = new ServiceBusClient( "Endpoint=sb://a;SharedAccessKeyName=b;SharedAccessKey=c;EntityPath=d" ); errorWasThrown = false; @@ -99,9 +89,14 @@ describe("Errors with non existing Namespace #RunInBrowser", function(): void { return sbClient.close(); }); - const testError = (err: Error): void => { - should.equal(err.name, "ServiceCommunicationError", "ErrorName is different than expected"); - errorWasThrown = true; + const testError = (err: Error | MessagingError): void => { + const expectedErrCode = isNode ? "ENOTFOUND" : "ServiceCommunicationError"; + if (!isMessagingError(err)) { + should.equal(true, false, "Error expected to be instance of MessagingError"); + } else { + should.equal(err.code, expectedErrCode, "Error code is different than expected"); + errorWasThrown = true; + } }; it("throws error when sending data via a queueClient to a non existing namespace", async function(): Promise< @@ -151,7 +146,7 @@ describe("Errors with non existing Namespace #RunInBrowser", function(): void { should.equal(errorWasThrown, true, "Error thrown flag must be true"); }); - it("throws error when receving batch data via a queueClient from a non existing namespace", async function(): Promise< + it("throws error when receiving batch data via a queueClient from a non existing namespace", async function(): Promise< void > { const client = sbClient.createQueueClient("some-name"); @@ -161,7 +156,7 @@ describe("Errors with non existing Namespace #RunInBrowser", function(): void { should.equal(errorWasThrown, true, "Error thrown flag must be true"); }); - it("throws error when receving batch data via a subscriptionClient from a non existing namespace", async function(): Promise< + it("throws error when receiving batch data via a subscriptionClient from a non existing namespace", async function(): Promise< void > { const client = sbClient.createSubscriptionClient("some-topic-name", "some-subscription-name"); @@ -171,7 +166,7 @@ describe("Errors with non existing Namespace #RunInBrowser", function(): void { should.equal(errorWasThrown, true, "Error thrown flag must be true"); }); - it("throws error when receving streaming data via a queueClient from a non existing namespace", async function(): Promise< + it("throws error when receiving streaming data via a queueClient from a non existing namespace", async function(): Promise< void > { const client = sbClient.createQueueClient("some-name"); @@ -199,15 +194,23 @@ describe("Errors with non existing Queue/Topic/Subscription", async function(): return sbClient.close(); }); - const testError = (err: Error, entityPath: string): void => { - should.equal(err.name, "MessagingEntityNotFoundError", "ErrorName is different than expected"); - should.equal( - err.message.startsWith( - `The messaging entity '${sbClient.name}${entityPath}' could not be found.` - ), - true - ); - errorWasThrown = true; + const testError = (err: Error | MessagingError, entityPath: string): void => { + if (!isMessagingError(err)) { + should.equal(true, false, "Error expected to be instance of MessagingError"); + } else { + should.equal( + err.code, + "MessagingEntityNotFoundError", + "Error code is different than expected" + ); + should.equal( + err.message.startsWith( + `The messaging entity '${sbClient.name}${entityPath}' could not be found.` + ), + true + ); + errorWasThrown = true; + } }; it("throws error when sending data to a non existing queue #RunInBrowser", async function(): Promise< @@ -278,7 +281,7 @@ describe("Errors with non existing Queue/Topic/Subscription", async function(): should.equal(errorWasThrown, true, "Error thrown flag must be true"); }); - it("throws error when receving streaming data from a non existing queue #RunInBrowser", async function(): Promise< + it("throws error when receiving streaming data from a non existing queue #RunInBrowser", async function(): Promise< void > { const client = sbClient.createQueueClient("some-name"); @@ -293,7 +296,7 @@ describe("Errors with non existing Queue/Topic/Subscription", async function(): should.equal(errorWasThrown, true, "Error thrown flag must be true"); }); - it("throws error when receving streaming data from a non existing subscription", async function(): Promise< + it("throws error when receiving streaming data from a non existing subscription", async function(): Promise< void > { const client = sbClient.createSubscriptionClient("some-topic-name", "some-subscription-name"); @@ -311,7 +314,7 @@ describe("Errors with non existing Queue/Topic/Subscription", async function(): }); }); -describe("Test createFromAadTokenCredentials", function(): void { +describe("Test ServiceBusClient creation #RunInBrowser", function(): void { let sbClient: ServiceBusClient; let errorWasThrown: boolean = false; @@ -320,69 +323,91 @@ describe("Test createFromAadTokenCredentials", function(): void { "Endpoint=sb://((.*).servicebus.windows.net)" ) || "")[1]; - async function testCreateFromAadTokenCredentials(host: string, tokenCreds: any): Promise { - const testMessages = TestMessage.getSample(); - sbClient = ServiceBusClient.createFromAadTokenCredentials(host, tokenCreds); - sbClient.should.be.an.instanceof(ServiceBusClient); - const clients = await getSenderReceiverClients( - sbClient, - TestClientType.UnpartitionedQueue, - TestClientType.UnpartitionedQueue + /** + * Utility to create EnvironmentCredential using `@azure/identity` + */ + function getDefaultTokenCredential() { + should.exist( + env[EnvVarNames.AZURE_CLIENT_ID], + "define AZURE_CLIENT_ID in your environment before running integration tests." ); - - const sender = clients.senderClient.createSender(); - const receiver = await clients.receiverClient.createReceiver(ReceiveMode.peekLock); - await sender.send(testMessages); - const msgs = await receiver.receiveMessages(1); - - should.equal(Array.isArray(msgs), true, "`ReceivedMessages` is not an array"); - should.equal(msgs[0].body, testMessages.body, "MessageBody is different than expected"); - should.equal(msgs.length, 1, "Unexpected number of messages"); + should.exist( + env[EnvVarNames.AZURE_TENANT_ID], + "define AZURE_TENANT_ID in your environment before running integration tests." + ); + should.exist( + env[EnvVarNames.AZURE_CLIENT_SECRET], + "define AZURE_CLIENT_SECRET in your environment before running integration tests." + ); + should.exist( + env[EnvVarNames.SERVICEBUS_CONNECTION_STRING], + "define EVENTHUB_CONNECTION_STRING in your environment before running integration tests." + ); + return new EnvironmentCredential(); } - it("throws error when using `CreateFromAadTokenCredentials` in browser #RunInBrowser", async function(): Promise< - void - > { - // We use the `!isNode` check here to ensure this test is run only in browser only - // as by default all tests run in Node - if (!isNode) { - const credentials: any = {}; - await testCreateFromAadTokenCredentials(serviceBusEndpoint, credentials).catch((err) => { - errorWasThrown = true; - should.equal( - err.message, - "`createFromAadTokenCredentials` cannot be used to create ServiceBusClient as AAD support is not present in browser." - ); - }); - should.equal(errorWasThrown, true, "Error thrown flag must be true"); + it("throws error for invalid tokenCredentials", async function(): Promise { + try { + new ServiceBusClient(serviceBusEndpoint, [] as any); + } catch (err) { + errorWasThrown = true; + should.equal( + err.message, + "Connection string malformed: each part of the connection string must have an `=` assignment.", + // "'credentials' is a required parameter and must be an implementation of TokenCredential when using host based constructor overload.", + "ErrorMessage is different than expected" + ); } + should.equal(errorWasThrown, true, "Error thrown flag must be true"); }); - it("throws error for invalid tokenCredentials", async function(): Promise { - await testCreateFromAadTokenCredentials(serviceBusEndpoint, "").catch((err) => { + it("throws error for undefined tokenCredentials", async function(): Promise { + try { + new ServiceBusClient(serviceBusEndpoint, undefined as any); + } catch (err) { errorWasThrown = true; should.equal( err.message, - "'credentials' is a required parameter and must be an instance of ApplicationTokenCredentials | UserTokenCredentials | DeviceTokenCredentials | MSITokenCredentials.", + "Connection string malformed: each part of the connection string must have an `=` assignment.", + // "'credentials' is a required parameter and must be an implementation of TokenCredential when using host based constructor overload.", "ErrorMessage is different than expected" ); - }); + } should.equal(errorWasThrown, true, "Error thrown flag must be true"); }); - it("Coerces input to string for host in createFromAadTokenCredentials", async function(): Promise< - void - > { - const tokenCreds = await getTokenCredentialsFromAAD(); - sbClient = ServiceBusClient.createFromAadTokenCredentials(123 as any, tokenCreds); - should.equal(sbClient.name, "sb://123/", "Name of the namespace is different than expected"); - }); + if (isNode) { + it("Coerces input to string for host in credential based constructor", async function(): Promise< + void + > { + const tokenCreds = getDefaultTokenCredential(); + sbClient = new ServiceBusClient(123 as any, tokenCreds); + should.equal(sbClient.name, "sb://123/", "Name of the namespace is different than expected"); + }); - it("sends a message to the ServiceBus entity", async function(): Promise { - const tokenCreds = await getTokenCredentialsFromAAD(); - await testCreateFromAadTokenCredentials(serviceBusEndpoint, tokenCreds); - await sbClient.close(); - }); + it("sends a message to the ServiceBus entity", async function(): Promise { + const tokenCreds = getDefaultTokenCredential(); + const sbClient = new ServiceBusClient(serviceBusEndpoint, tokenCreds); + + sbClient.should.be.an.instanceof(ServiceBusClient); + const clients = await getSenderReceiverClients( + sbClient, + TestClientType.UnpartitionedQueue, + TestClientType.UnpartitionedQueue + ); + + const sender = clients.senderClient.createSender(); + const receiver = await clients.receiverClient.createReceiver(ReceiveMode.peekLock); + const testMessages = TestMessage.getSample(); + await sender.send(testMessages); + const msgs = await receiver.receiveMessages(1); + + should.equal(Array.isArray(msgs), true, "`ReceivedMessages` is not an array"); + should.equal(msgs[0].body, testMessages.body, "MessageBody is different than expected"); + should.equal(msgs.length, 1, "Unexpected number of messages"); + await sbClient.close(); + }); + } }); describe("Errors after close()", function(): void { diff --git a/sdk/servicebus/service-bus/test/streamingReceiver.spec.ts b/sdk/servicebus/service-bus/test/streamingReceiver.spec.ts index 6b7c391f1500..e9ae6709ada0 100644 --- a/sdk/servicebus/service-bus/test/streamingReceiver.spec.ts +++ b/sdk/servicebus/service-bus/test/streamingReceiver.spec.ts @@ -25,10 +25,12 @@ import { TestMessage, getServiceBusClient } from "./utils/testUtils"; -import { SasTokenProvider, TokenInfo, parseConnectionString } from "@azure/amqp-common"; -import { getEnvVars, EnvVarNames } from "./utils/envVarUtils"; import { StreamingReceiver } from "../src/core/streamingReceiver"; +import { AccessToken, parseConnectionString, TokenCredential } from "@azure/core-amqp"; +import { getEnvVars, EnvVarNames } from "./utils/envVarUtils"; +import { EnvironmentCredential } from "@azure/identity"; + const should = chai.should(); chai.use(chaiAsPromised); @@ -867,34 +869,26 @@ describe("Streaming - Failed init should not cache recevier", function(): void { await afterEachTest(); }); - class TestTokenProvider extends SasTokenProvider { + class TestTokenCredential extends EnvironmentCredential implements TokenCredential { private firstCall = true; static errorMessage = "This is a faulty token provider."; - constructor(connectionObject: { - Endpoint: string; - SharedAccessKeyName: string; - SharedAccessKey: string; - }) { - super( - connectionObject.Endpoint, - connectionObject.SharedAccessKeyName, - connectionObject.SharedAccessKey - ); + constructor() { + super(); } - async getToken(audience: string): Promise { + async getToken(audience: string): Promise { if (this.firstCall) { this.firstCall = false; - throw new Error(TestTokenProvider.errorMessage); + throw new Error(TestTokenCredential.errorMessage); } return super.getToken(audience); } } - it("UnPartitioned Queue: Receiver is not cached when not initialized #RunInBrowser", async function(): Promise< + it("UnPartitioned Queue: Receiver is not cached when not initialized", async function(): Promise< void > { - const env = getEnvVars(); + const env: any = getEnvVars(); // Send a message using service bus client created with connection string sbClient = getServiceBusClient(); @@ -913,11 +907,8 @@ describe("Streaming - Failed init should not cache recevier", function(): void { SharedAccessKeyName: string; SharedAccessKey: string; } = parseConnectionString(env[EnvVarNames.SERVICEBUS_CONNECTION_STRING]); - const tokenProvider = new TestTokenProvider(connectionObject); - sbClient = ServiceBusClient.createFromTokenProvider( - connectionObject.Endpoint.substr(5), - tokenProvider - ); + const tokenProvider = new TestTokenCredential(); + sbClient = new ServiceBusClient(connectionObject.Endpoint.substr(5), tokenProvider); clients = await getSenderReceiverClients( sbClient, TestClientType.UnpartitionedQueue, @@ -940,7 +931,7 @@ describe("Streaming - Failed init should not cache recevier", function(): void { should.equal(errCheck, true, "Expected error to be thrown, but no error found."); should.equal( actualError!.message, - TestTokenProvider.errorMessage, + TestTokenCredential.errorMessage, "Expected error from token provider, but unexpected error found." ); should.equal( diff --git a/sdk/servicebus/service-bus/test/stress/stress_fixedNumberOfClientsMultipleQueues.ts b/sdk/servicebus/service-bus/test/stress/stress_fixedNumberOfClientsMultipleQueues.ts index 5dbaba859eb9..435a6465047e 100644 --- a/sdk/servicebus/service-bus/test/stress/stress_fixedNumberOfClientsMultipleQueues.ts +++ b/sdk/servicebus/service-bus/test/stress/stress_fixedNumberOfClientsMultipleQueues.ts @@ -34,7 +34,7 @@ async function main(): Promise { } async function sendReceiveMessages(): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const clients = []; const senders = []; diff --git a/sdk/servicebus/service-bus/test/stress/stress_fixedNumberOfClientsSingleQueue.ts b/sdk/servicebus/service-bus/test/stress/stress_fixedNumberOfClientsSingleQueue.ts index 7edccdf52d95..ef8040ec2258 100644 --- a/sdk/servicebus/service-bus/test/stress/stress_fixedNumberOfClientsSingleQueue.ts +++ b/sdk/servicebus/service-bus/test/stress/stress_fixedNumberOfClientsSingleQueue.ts @@ -36,7 +36,7 @@ async function main(): Promise { } async function sendReceiveMessages(): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const clients = []; const senders = []; diff --git a/sdk/servicebus/service-bus/test/stress/stress_messageAutolockRenewal.ts b/sdk/servicebus/service-bus/test/stress/stress_messageAutolockRenewal.ts index cf9f8e92f5e9..c6b725562d0c 100644 --- a/sdk/servicebus/service-bus/test/stress/stress_messageAutolockRenewal.ts +++ b/sdk/servicebus/service-bus/test/stress/stress_messageAutolockRenewal.ts @@ -35,7 +35,7 @@ async function main(): Promise { } async function sendMessage(): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { const sender = client.createSender(); @@ -54,7 +54,7 @@ async function sendMessage(): Promise { } async function receiveMessage(): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { diff --git a/sdk/servicebus/service-bus/test/stress/stress_messageLockRenewalBatchingThenStreaming.ts b/sdk/servicebus/service-bus/test/stress/stress_messageLockRenewalBatchingThenStreaming.ts index 19fc13f35160..a3c4dd6a8846 100644 --- a/sdk/servicebus/service-bus/test/stress/stress_messageLockRenewalBatchingThenStreaming.ts +++ b/sdk/servicebus/service-bus/test/stress/stress_messageLockRenewalBatchingThenStreaming.ts @@ -38,7 +38,7 @@ async function main(): Promise { } async function sendMessage(messageId: string): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { const sender = client.createSender(); @@ -57,7 +57,7 @@ async function sendMessage(messageId: string): Promise { } async function receiveMessages(): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { diff --git a/sdk/servicebus/service-bus/test/stress/stress_messageManualLockRenewal.ts b/sdk/servicebus/service-bus/test/stress/stress_messageManualLockRenewal.ts index 17ec3a740af7..98445d93007f 100644 --- a/sdk/servicebus/service-bus/test/stress/stress_messageManualLockRenewal.ts +++ b/sdk/servicebus/service-bus/test/stress/stress_messageManualLockRenewal.ts @@ -36,7 +36,7 @@ async function main(): Promise { } async function sendMessage(): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { const sender = client.createSender(); @@ -55,7 +55,7 @@ async function sendMessage(): Promise { } async function receiveMessage(): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { diff --git a/sdk/servicebus/service-bus/test/stress/stress_messageRandomDisposition.ts b/sdk/servicebus/service-bus/test/stress/stress_messageRandomDisposition.ts index 0b27840d8287..3ab6f9bbd0ba 100644 --- a/sdk/servicebus/service-bus/test/stress/stress_messageRandomDisposition.ts +++ b/sdk/servicebus/service-bus/test/stress/stress_messageRandomDisposition.ts @@ -47,7 +47,7 @@ async function main(): Promise { } async function sendMessages(): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { const sender = client.createSender(); @@ -70,7 +70,7 @@ async function sendMessages(): Promise { } async function receiveMessages(): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { diff --git a/sdk/servicebus/service-bus/test/stress/stress_messageRandomDispositionOnSession.ts b/sdk/servicebus/service-bus/test/stress/stress_messageRandomDispositionOnSession.ts index a9b5a3a0e4f2..f99dc0c5c6c1 100644 --- a/sdk/servicebus/service-bus/test/stress/stress_messageRandomDispositionOnSession.ts +++ b/sdk/servicebus/service-bus/test/stress/stress_messageRandomDispositionOnSession.ts @@ -48,7 +48,7 @@ async function main(): Promise { } async function sendMessages(): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { const sender = client.createSender(); @@ -72,7 +72,7 @@ async function sendMessages(): Promise { } async function receiveMessages(): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { diff --git a/sdk/servicebus/service-bus/test/stress/stress_sessionAutolockRenewal.ts b/sdk/servicebus/service-bus/test/stress/stress_sessionAutolockRenewal.ts index 83cb471f4827..20c90d6dface 100644 --- a/sdk/servicebus/service-bus/test/stress/stress_sessionAutolockRenewal.ts +++ b/sdk/servicebus/service-bus/test/stress/stress_sessionAutolockRenewal.ts @@ -35,7 +35,7 @@ async function main(): Promise { } async function sendMessage(sessionId: string): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { const sender = client.createSender(); @@ -55,7 +55,7 @@ async function sendMessage(sessionId: string): Promise { } async function receiveMessage(sessionId: string): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { diff --git a/sdk/servicebus/service-bus/test/stress/stress_sessionManualLockRenewal.ts b/sdk/servicebus/service-bus/test/stress/stress_sessionManualLockRenewal.ts index 3c3b6bbab7ca..80266a534a68 100644 --- a/sdk/servicebus/service-bus/test/stress/stress_sessionManualLockRenewal.ts +++ b/sdk/servicebus/service-bus/test/stress/stress_sessionManualLockRenewal.ts @@ -37,7 +37,7 @@ async function main(): Promise { } async function sendMessage(sessionId: string): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { const sender = client.createSender(); @@ -57,7 +57,7 @@ async function sendMessage(sessionId: string): Promise { } async function receiveMessage(sessionId: string): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { diff --git a/sdk/servicebus/service-bus/test/stress/stress_sessionState.ts b/sdk/servicebus/service-bus/test/stress/stress_sessionState.ts index 2162870adb14..f89821a9a643 100644 --- a/sdk/servicebus/service-bus/test/stress/stress_sessionState.ts +++ b/sdk/servicebus/service-bus/test/stress/stress_sessionState.ts @@ -25,7 +25,7 @@ async function main(): Promise { } async function setGetSessionState(sessionId: string): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { diff --git a/sdk/servicebus/service-bus/test/stress/stress_singleClient.ts b/sdk/servicebus/service-bus/test/stress/stress_singleClient.ts index cc787921bcfc..3633158c372d 100644 --- a/sdk/servicebus/service-bus/test/stress/stress_singleClient.ts +++ b/sdk/servicebus/service-bus/test/stress/stress_singleClient.ts @@ -35,7 +35,7 @@ async function main(): Promise { } async function sendReceiveMessages(): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); try { while (!isJobDone) { diff --git a/sdk/servicebus/service-bus/test/stress/stress_singleMessageComplete.ts b/sdk/servicebus/service-bus/test/stress/stress_singleMessageComplete.ts index 7d8782bcfeb5..0c887303018c 100644 --- a/sdk/servicebus/service-bus/test/stress/stress_singleMessageComplete.ts +++ b/sdk/servicebus/service-bus/test/stress/stress_singleMessageComplete.ts @@ -40,7 +40,7 @@ async function main(): Promise { } async function sendMessages(): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { const sender = client.createSender(); @@ -63,7 +63,7 @@ async function sendMessages(): Promise { } async function receiveMessages(): Promise { - const ns = ServiceBusClient.createFromConnectionString(connectionString); + const ns = new ServiceBusClient(connectionString); const client = ns.createQueueClient(queueName); try { diff --git a/sdk/servicebus/service-bus/test/topicFilters.spec.ts b/sdk/servicebus/service-bus/test/topicFilters.spec.ts index c3107e2f99c3..270040eb4b64 100644 --- a/sdk/servicebus/service-bus/test/topicFilters.spec.ts +++ b/sdk/servicebus/service-bus/test/topicFilters.spec.ts @@ -239,9 +239,9 @@ describe("addRule() #RunInBrowser", function(): void { "ErrorMessage is different than expected" ); should.equal( - error.name, + error.code, "MessagingEntityAlreadyExistsError", - "ErrorName is different than expected" + "Error code is different than expected" ); } should.equal(errorWasThrown, true, "Error thrown flag must be true"); @@ -270,9 +270,9 @@ describe("removeRule()", function(): void { "ErrorMessage is different than expected" ); should.equal( - error.name, + error.code, "MessagingEntityNotFoundError", - "ErrorName is different than expected" + "Error code is different than expected" ); errorWasThrown = true; } diff --git a/sdk/servicebus/service-bus/test/utils/aadUtils.browser.ts b/sdk/servicebus/service-bus/test/utils/aadUtils.browser.ts deleted file mode 100644 index 861973d77b9c..000000000000 --- a/sdk/servicebus/service-bus/test/utils/aadUtils.browser.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -export async function getTokenCredentialsFromAAD() {} diff --git a/sdk/servicebus/service-bus/test/utils/aadUtils.ts b/sdk/servicebus/service-bus/test/utils/aadUtils.ts deleted file mode 100644 index 2588c21d5c6a..000000000000 --- a/sdk/servicebus/service-bus/test/utils/aadUtils.ts +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -import { EnvVarNames, getEnvVars } from "./envVarUtils"; - -import { loginWithServicePrincipalSecret } from "@azure/ms-rest-nodeauth"; - -const aadServiceBusAudience = "https://servicebus.azure.net/"; - -export async function getTokenCredentialsFromAAD() { - const env = getEnvVars(); - const tokenCreds = await loginWithServicePrincipalSecret( - env[EnvVarNames.AAD_CLIENT_ID], - env[EnvVarNames.AAD_CLIENT_SECRET], - env[EnvVarNames.AAD_TENANT_ID], - { - tokenAudience: aadServiceBusAudience - } - ); - return tokenCreds; -} diff --git a/sdk/servicebus/service-bus/test/utils/envVarUtils.ts b/sdk/servicebus/service-bus/test/utils/envVarUtils.ts index b2997f4c1d77..4cd82ea5da83 100644 --- a/sdk/servicebus/service-bus/test/utils/envVarUtils.ts +++ b/sdk/servicebus/service-bus/test/utils/envVarUtils.ts @@ -9,9 +9,9 @@ export const isNode = */ export enum EnvVarNames { SERVICEBUS_CONNECTION_STRING = "SERVICEBUS_CONNECTION_STRING", - AAD_CLIENT_ID = "AAD_CLIENT_ID", - AAD_CLIENT_SECRET = "AAD_CLIENT_SECRET", - AAD_TENANT_ID = "AAD_TENANT_ID" + AZURE_CLIENT_ID = "AZURE_CLIENT_ID", + AZURE_CLIENT_SECRET = "AZURE_CLIENT_SECRET", + AZURE_TENANT_ID = "AZURE_TENANT_ID" } /** @@ -42,9 +42,9 @@ export function getEnvVars(): { [key in EnvVarNames]: any } { // Throw error if required environment variables are missing. [ EnvVarNames.SERVICEBUS_CONNECTION_STRING, - EnvVarNames.AAD_CLIENT_ID, - EnvVarNames.AAD_CLIENT_SECRET, - EnvVarNames.AAD_TENANT_ID + EnvVarNames.AZURE_CLIENT_ID, + EnvVarNames.AZURE_CLIENT_SECRET, + EnvVarNames.AZURE_TENANT_ID ].forEach(function(name: string) { if (!getEnvVarValue(name)) { throw new Error(`Define ${name} in your environment before running integration tests.`); @@ -55,9 +55,9 @@ export function getEnvVars(): { [key in EnvVarNames]: any } { [EnvVarNames.SERVICEBUS_CONNECTION_STRING]: getEnvVarValue( EnvVarNames.SERVICEBUS_CONNECTION_STRING ), - [EnvVarNames.AAD_CLIENT_ID]: getEnvVarValue(EnvVarNames.AAD_CLIENT_ID), - [EnvVarNames.AAD_CLIENT_SECRET]: getEnvVarValue(EnvVarNames.AAD_CLIENT_SECRET), - [EnvVarNames.AAD_TENANT_ID]: getEnvVarValue(EnvVarNames.AAD_TENANT_ID) + [EnvVarNames.AZURE_CLIENT_ID]: getEnvVarValue(EnvVarNames.AZURE_CLIENT_ID), + [EnvVarNames.AZURE_CLIENT_SECRET]: getEnvVarValue(EnvVarNames.AZURE_CLIENT_SECRET), + [EnvVarNames.AZURE_TENANT_ID]: getEnvVarValue(EnvVarNames.AZURE_TENANT_ID) }; return envVars; diff --git a/sdk/servicebus/service-bus/test/utils/testUtils.ts b/sdk/servicebus/service-bus/test/utils/testUtils.ts index 40d456a4221d..8335e8db455b 100644 --- a/sdk/servicebus/service-bus/test/utils/testUtils.ts +++ b/sdk/servicebus/service-bus/test/utils/testUtils.ts @@ -10,7 +10,8 @@ import { SubscriptionClient, delay, ReceiveMode, - ServiceBusMessage + ServiceBusMessage, + MessagingError } from "../../src"; import { EnvVarNames, getEnvVars } from "./envVarUtils"; import { recreateQueue, recreateSubscription, recreateTopic } from "./managementUtils"; @@ -470,7 +471,7 @@ export function getNamespace(serviceBusConnectionString: string): string { export function getServiceBusClient(): ServiceBusClient { const env = getEnvVars(); - return ServiceBusClient.createFromConnectionString(env[EnvVarNames.SERVICEBUS_CONNECTION_STRING]); + return new ServiceBusClient(env[EnvVarNames.SERVICEBUS_CONNECTION_STRING]); } /** @@ -503,3 +504,11 @@ export enum EntityNames { MANAGEMENT_NEW_ENTITY_1 = "management-new-entity-1", MANAGEMENT_NEW_ENTITY_2 = "management-new-entity-2" } + +/** + * Utility to check if given error is instance of `MessagingError` + * @param err + */ +export function isMessagingError(err: any): err is MessagingError { + return err.name === "MessagingError"; +} diff --git a/sdk/servicebus/service-bus/tests.yml b/sdk/servicebus/service-bus/tests.yml index ffe676f9caf9..25cd48df8794 100644 --- a/sdk/servicebus/service-bus/tests.yml +++ b/sdk/servicebus/service-bus/tests.yml @@ -24,7 +24,8 @@ jobs: OSVmImage: "windows-2019" TestType: "browser" EnvVars: - AAD_CLIENT_ID: $(aad-azure-sdk-test-client-id) - AAD_TENANT_ID: $(aad-azure-sdk-test-tenant-id) - AAD_CLIENT_SECRET: $(aad-azure-sdk-test-client-secret) - SERVICEBUS_CONNECTION_STRING: $(SERVICEBUS_CONNECTION_STRING) + AZURE_CLIENT_ID: $(aad-azure-sdk-test-client-id) + AZURE_TENANT_ID: $(aad-azure-sdk-test-tenant-id) + AZURE_CLIENT_SECRET: $(aad-azure-sdk-test-client-secret) + AZURE_SUBSCRIPTION_ID: $(test-subscription-id) + SERVICEBUS_CONNECTION_STRING: $(service-bus-test-connection-string) From d9ea9abe8aac271cc7a4e3defcadfd04662bb394 Mon Sep 17 00:00:00 2001 From: HarshaNalluru <10452642+HarshaNalluru@users.noreply.github.com> Date: Mon, 10 Feb 2020 18:32:14 -0800 Subject: [PATCH 13/13] Sender -> AwaitableSender --- .../service-bus/src/core/linkEntity.ts | 4 +- .../service-bus/src/core/messageSender.ts | 131 ++++-------------- 2 files changed, 26 insertions(+), 109 deletions(-) diff --git a/sdk/servicebus/service-bus/src/core/linkEntity.ts b/sdk/servicebus/service-bus/src/core/linkEntity.ts index 8a40f54b5992..0994129b167e 100644 --- a/sdk/servicebus/service-bus/src/core/linkEntity.ts +++ b/sdk/servicebus/service-bus/src/core/linkEntity.ts @@ -10,7 +10,7 @@ import { } from "@azure/core-amqp"; import { ClientEntityContext } from "../clientEntityContext"; import * as log from "../log"; -import { Sender, Receiver } from "rhea-promise"; +import { AwaitableSender, Receiver } from "rhea-promise"; import { getUniqueName } from "../util/utils"; /** @@ -225,7 +225,7 @@ export class LinkEntity { * @param {Sender | Receiver} [link] The Sender or Receiver link that needs to be closed and * removed. */ - protected async _closeLink(link?: Sender | Receiver): Promise { + protected async _closeLink(link?: AwaitableSender | Receiver): Promise { clearTimeout(this._tokenRenewalTimer as NodeJS.Timer); if (link) { try { diff --git a/sdk/servicebus/service-bus/src/core/messageSender.ts b/sdk/servicebus/service-bus/src/core/messageSender.ts index 1c18ee964681..66928a752a16 100644 --- a/sdk/servicebus/service-bus/src/core/messageSender.ts +++ b/sdk/servicebus/service-bus/src/core/messageSender.ts @@ -4,18 +4,16 @@ import * as log from "../log"; import { messageProperties, - Sender, + AwaitableSender, + AwaitableSenderOptions, EventContext, OnAmqpEvent, - SenderOptions, - SenderEvents, message as RheaMessageUtil, AmqpError, generate_uuid } from "rhea-promise"; import { defaultLock, - Func, retry, translate, AmqpMessage, @@ -36,13 +34,6 @@ import { LinkEntity } from "./linkEntity"; import { getUniqueName } from "../util/utils"; import { throwErrorIfConnectionClosed } from "../util/errors"; -/** - * @internal - */ -interface CreateSenderOptions { - newName?: boolean; -} - /** * @internal * Describes the MessageSender that will send messages to ServiceBus. @@ -83,7 +74,7 @@ export class MessageSender extends LinkEntity { * @property {Sender} [_sender] The AMQP sender link. * @private */ - private _sender?: Sender; + private _sender?: AwaitableSender; /** * Creates a new MessageSender instance. @@ -225,9 +216,9 @@ export class MessageSender extends LinkEntity { ); } - private _createSenderOptions(options: CreateSenderOptions): SenderOptions { - if (options.newName) this.name = getUniqueName(this._context.entityPath); - const srOptions: SenderOptions = { + private _createSenderOptions(timeoutInMs: number, newName?: boolean): AwaitableSenderOptions { + if (newName) this.name = getUniqueName(this._context.entityPath); + const srOptions: AwaitableSenderOptions = { name: this.name, target: { address: this.address @@ -235,7 +226,8 @@ export class MessageSender extends LinkEntity { onError: this._onAmqpError, onClose: this._onAmqpClose, onSessionError: this._onSessionError, - onSessionClose: this._onSessionClose + onSessionClose: this._onSessionClose, + sendTimeoutInSeconds: timeoutInMs / 1000 }; log.sender("Creating sender with options: %O", srOptions); return srOptions; @@ -255,7 +247,6 @@ export class MessageSender extends LinkEntity { private _trySend(encodedMessage: Buffer, sendBatch?: boolean): Promise { const sendEventPromise = () => new Promise(async (resolve, reject) => { - let waitTimer: any; log.sender( "[%s] Sender '%s', credit: %d available: %d", this._context.namespace.connectionId, @@ -281,83 +272,7 @@ export class MessageSender extends LinkEntity { ); } if (this._sender!.sendable()) { - let onRejected: Func; - let onReleased: Func; - let onModified: Func; - let onAccepted: Func; - const removeListeners = (): void => { - clearTimeout(waitTimer); - // When `removeListeners` is called on timeout, the sender might be closed and cleared - // So, check if it exists, before removing listeners from it. - if (this._sender) { - this._sender.removeListener(SenderEvents.rejected, onRejected); - this._sender.removeListener(SenderEvents.accepted, onAccepted); - this._sender.removeListener(SenderEvents.released, onReleased); - this._sender.removeListener(SenderEvents.modified, onModified); - } - }; - - onAccepted = (context: EventContext) => { - // Since we will be adding listener for accepted and rejected event every time - // we send a message, we need to remove listener for both the events. - // This will ensure duplicate listeners are not added for the same event. - removeListeners(); - log.sender( - "[%s] Sender '%s', got event accepted.", - this._context.namespace.connectionId, - this.name - ); - resolve(); - }; - onRejected = (context: EventContext) => { - removeListeners(); - log.error( - "[%s] Sender '%s', got event rejected.", - this._context.namespace.connectionId, - this.name - ); - const err = translate(context!.delivery!.remote_state!.error); - reject(err); - }; - onReleased = (context: EventContext) => { - removeListeners(); - log.error( - "[%s] Sender '%s', got event released.", - this._context.namespace.connectionId, - this.name - ); - let err: Error; - if (context!.delivery!.remote_state!.error) { - err = translate(context!.delivery!.remote_state!.error); - } else { - err = new Error( - `[${this._context.namespace.connectionId}]Sender '${this.name}', ` + - `received a release disposition.Hence we are rejecting the promise.` - ); - } - reject(err); - }; - onModified = (context: EventContext) => { - removeListeners(); - log.error( - "[%s] Sender '%s', got event modified.", - this._context.namespace.connectionId, - this.name - ); - let err: Error; - if (context!.delivery!.remote_state!.error) { - err = translate(context!.delivery!.remote_state!.error); - } else { - err = new Error( - `[${this._context.namespace.connectionId}]Sender "${this.name}", ` + - `received a modified disposition.Hence we are rejecting the promise.` - ); - } - reject(err); - }; - const actionAfterTimeout = () => { - removeListeners(); const desc: string = `[${this._context.namespace.connectionId}] Sender "${this.name}" ` + `with address "${this.address}", was not able to send the message right now, due ` + @@ -370,13 +285,9 @@ export class MessageSender extends LinkEntity { return reject(translate(e)); }; - this._sender!.on(SenderEvents.accepted, onAccepted); - this._sender!.on(SenderEvents.rejected, onRejected); - this._sender!.on(SenderEvents.modified, onModified); - this._sender!.on(SenderEvents.released, onReleased); - waitTimer = setTimeout(actionAfterTimeout, Constants.defaultOperationTimeoutInMs); + const waitTimer = setTimeout(actionAfterTimeout, Constants.defaultOperationTimeoutInMs); try { - const delivery = this._sender!.send( + const delivery = await this._sender!.send( encodedMessage, undefined, sendBatch ? 0x80013700 : 0 @@ -387,9 +298,17 @@ export class MessageSender extends LinkEntity { this.name, delivery.id ); + return resolve(); } catch (error) { - removeListeners(); + error = translate(error); + log.error( + "[%s] An error occurred while sending the message", + this._context.namespace.connectionId, + error + ); return reject(error); + } finally { + clearTimeout(waitTimer); } } else { // let us retry to send the message after some time. @@ -421,7 +340,7 @@ export class MessageSender extends LinkEntity { /** * Initializes the sender session on the connection. */ - private async _init(options?: SenderOptions): Promise { + private async _init(options?: AwaitableSenderOptions): Promise { try { // isOpen isConnecting Should establish // true false No @@ -444,9 +363,9 @@ export class MessageSender extends LinkEntity { this.name ); if (!options) { - options = this._createSenderOptions({}); + options = this._createSenderOptions(Constants.defaultOperationTimeoutInMs); } - this._sender = await this._context.namespace.connection.createSender(options); + this._sender = await this._context.namespace.connection.createAwaitableSender(options); this.isConnecting = false; log.error( "[%s] Sender '%s' with address '%s' has established itself.", @@ -544,13 +463,11 @@ export class MessageSender extends LinkEntity { } if (shouldReopen) { await defaultLock.acquire(this.senderLock, () => { - const options: SenderOptions = this._createSenderOptions({ - newName: true - }); + const senderOptions = this._createSenderOptions(Constants.defaultOperationTimeoutInMs); // shall retry forever at an interval of 15 seconds if the error is a retryable error // else bail out when the error is not retryable or the oepration succeeds. const config: RetryConfig = { - operation: () => this._init(options), + operation: () => this._init(senderOptions), connectionId: this._context.namespace.connectionId!, operationType: RetryOperationType.senderLink, retryOptions: {