diff --git a/eng/common/pipelines/templates/steps/create-pull-request.yml b/eng/common/pipelines/templates/steps/create-pull-request.yml index a60d26c8fe98..e3b3e538c036 100644 --- a/eng/common/pipelines/templates/steps/create-pull-request.yml +++ b/eng/common/pipelines/templates/steps/create-pull-request.yml @@ -17,6 +17,7 @@ parameters: GHTeamReviewersVariable: '' # Multiple labels seperated by comma, e.g. "bug, APIView" PRLabels: '' + SkipCheckingForChanges: false steps: @@ -35,15 +36,19 @@ steps: echo "##vso[task.setvariable variable=HasChanges]$false" echo "No changes so skipping code push" } + displayName: Check for changes + condition: and(succeeded(), eq(${{ parameters.SkipCheckingForChanges }}, false)) + workingDirectory: ${{ parameters.WorkingDirectory }} + ignoreLASTEXITCODE: true +- pwsh: | # Remove the repo owner from the front of the repo name if it exists there $repoName = "${{ parameters.RepoName }}" -replace "^${{ parameters.RepoOwner }}/", "" echo "##vso[task.setvariable variable=RepoNameWithoutOwner]$repoName" - echo "RepoName = $repName" - - displayName: Check for changes + echo "RepoName = $repoName" + displayName: Remove Repo Owner from Repo Name + condition: succeeded() workingDirectory: ${{ parameters.WorkingDirectory }} - ignoreLASTEXITCODE: true - task: PowerShell@2 displayName: Push changes @@ -57,6 +62,7 @@ steps: -CommitMsg "${{ parameters.CommitMsg }}" -GitUrl "https://$(azuresdk-github-pat)@github.com/${{ parameters.PROwner }}/$(RepoNameWithoutOwner).git" -PushArgs "${{ parameters.PushArgs }}" + -SkipCommit $${{parameters.SkipCheckingForChanges}} - task: PowerShell@2 displayName: Create pull request diff --git a/eng/common/scripts/Add-Issue-Comment.ps1 b/eng/common/scripts/Add-Issue-Comment.ps1 new file mode 100644 index 000000000000..b945d70c3fe9 --- /dev/null +++ b/eng/common/scripts/Add-Issue-Comment.ps1 @@ -0,0 +1,53 @@ +[CmdletBinding(SupportsShouldProcess = $true)] +param( + [Parameter(Mandatory = $true)] + [string]$RepoOwner, + + [Parameter(Mandatory = $true)] + [string]$RepoName, + + [Parameter(Mandatory = $true)] + [string]$IssueNumber, + + [Parameter(Mandatory = $false)] + [string]$CommentPrefix, + + [Parameter(Mandatory = $true)] + [string]$Comment, + + [Parameter(Mandatory = $false)] + [string]$CommentPostFix, + + [Parameter(Mandatory = $true)] + [string]$AuthToken +) + +. "${PSScriptRoot}\logging.ps1" + +$headers = @{ + Authorization = "bearer $AuthToken" +} + +$apiUrl = "https://api.github.com/repos/$RepoOwner/$RepoName/issues/$IssueNumber/comments" + +$commentPrefixValue = [System.Environment]::GetEnvironmentVariable($CommentPrefix) +$commentValue = [System.Environment]::GetEnvironmentVariable($Comment) +$commentPostFixValue = [System.Environment]::GetEnvironmentVariable($CommentPostFix) + +if (!$commentPrefixValue) { $commentPrefixValue = $CommentPrefix } +if (!$commentValue) { $commentValue = $Comment } +if (!$commentPostFixValue) { $commentPostFixValue = $CommentPostFix } + +$PRComment = "$commentPrefixValue $commentValue $commentPostFixValue" + +$data = @{ + body = $PRComment +} + +try { + $resp = Invoke-RestMethod -Method POST -Headers $headers -Uri $apiUrl -Body ($data | ConvertTo-Json) +} +catch { + LogError "Invoke-RestMethod [ $apiUrl ] failed with exception:`n$_" + exit 1 +} \ No newline at end of file diff --git a/eng/common/scripts/Queue-Pipeline.ps1 b/eng/common/scripts/Queue-Pipeline.ps1 new file mode 100644 index 000000000000..4e0122ca9256 --- /dev/null +++ b/eng/common/scripts/Queue-Pipeline.ps1 @@ -0,0 +1,56 @@ +[CmdletBinding(SupportsShouldProcess = $true)] +param( + [Parameter(Mandatory = $true)] + [string]$Organization, + + [Parameter(Mandatory = $true)] + [string]$Project, + + [Parameter(Mandatory = $true)] + [string]$SourceBranch, + + [Parameter(Mandatory = $true)] + [int]$DefinitionId, + + [Parameter(Mandatory = $false)] + [string]$VsoQueuedPipelines, + + [Parameter(Mandatory = $true)] + [string]$AuthToken +) + +. "${PSScriptRoot}\logging.ps1" + +$headers = @{ + Authorization = "Basic $AuthToken" +} + +$apiUrl = "https://dev.azure.com/$Organization/$Project/_apis/build/builds?api-version=6.0" + +$body = @{ + sourceBranch = $SourceBranch + definition = @{ id = $DefinitionId } +} + +Write-Verbose ($body | ConvertTo-Json) + +try { + $resp = Invoke-RestMethod -Method POST -Headers $headers $apiUrl -Body ($body | ConvertTo-Json) -ContentType application/json +} +catch { + LogError "Invoke-RestMethod [ $apiUrl ] failed with exception:`n$_" + exit 1 +} + +LogDebug "Pipeline [ $($resp.definition.name) ] queued at [ $($resp._links.web.href) ]" + +if ($VsoQueuedPipelines) { + $enVarValue = [System.Environment]::GetEnvironmentVariable($VsoQueuedPipelines) + $QueuedPipelineLinks = if ($enVarValue) { + "$enVarValue
[$($resp.definition.name)]($($resp._links.web.href))" + }else { + "[$($resp.definition.name)]($($resp._links.web.href))" + } + $QueuedPipelineLinks + Write-Host "##vso[task.setvariable variable=$VsoQueuedPipelines]$QueuedPipelineLinks" +} \ No newline at end of file diff --git a/eng/common/scripts/git-branch-push.ps1 b/eng/common/scripts/git-branch-push.ps1 index 9b3d78345589..333ed0a62c5e 100644 --- a/eng/common/scripts/git-branch-push.ps1 +++ b/eng/common/scripts/git-branch-push.ps1 @@ -25,7 +25,10 @@ param( [string] $GitUrl, [Parameter(Mandatory = $false)] - [string] $PushArgs = "" + [string] $PushArgs = "", + + [Parameter(Mandatory = $false)] + [boolean] $SkipCommit = $false ) # This is necessay because of the janky git command output writing to stderr. @@ -57,12 +60,17 @@ if ($LASTEXITCODE -ne 0) exit $LASTEXITCODE } -Write-Host "git -c user.name=`"azure-sdk`" -c user.email=`"azuresdk@microsoft.com`" commit -am `"$($CommitMsg)`"" -git -c user.name="azure-sdk" -c user.email="azuresdk@microsoft.com" commit -am "$($CommitMsg)" -if ($LASTEXITCODE -ne 0) -{ - Write-Error "Unable to add files and create commit LASTEXITCODE=$($LASTEXITCODE), see command output above." - exit $LASTEXITCODE +if (!$SkipCommit) { + Write-Host "git -c user.name=`"azure-sdk`" -c user.email=`"azuresdk@microsoft.com`" commit -am `"$($CommitMsg)`"" + git -c user.name="azure-sdk" -c user.email="azuresdk@microsoft.com" commit -am "$($CommitMsg)" + if ($LASTEXITCODE -ne 0) + { + Write-Error "Unable to add files and create commit LASTEXITCODE=$($LASTEXITCODE), see command output above." + exit $LASTEXITCODE + } +} +else { + Write-Host "Skipped applying commit" } # The number of retries can be increased if necessary. In theory, the number of retries diff --git a/eng/common/scripts/modules/ChangeLog-Operations.psm1 b/eng/common/scripts/modules/ChangeLog-Operations.psm1 index 5aed584d018b..bfcd8d193b00 100644 --- a/eng/common/scripts/modules/ChangeLog-Operations.psm1 +++ b/eng/common/scripts/modules/ChangeLog-Operations.psm1 @@ -1,5 +1,4 @@ # Common Changelog Operations - $RELEASE_TITLE_REGEX = "(?^\#+.*(?\b\d+\.\d+\.\d+([^0-9\s][^\s:]+)?)(\s(?\(Unreleased\)|\(\d{4}-\d{2}-\d{2}\)))?)" # Returns a Collection of changeLogEntry object containing changelog info for all version present in the gived CHANGELOG diff --git a/eng/common/scripts/modules/Package-Properties.psm1 b/eng/common/scripts/modules/Package-Properties.psm1 index b0572a71d449..61c45455f0d0 100644 --- a/eng/common/scripts/modules/Package-Properties.psm1 +++ b/eng/common/scripts/modules/Package-Properties.psm1 @@ -1,3 +1,4 @@ +# This Files has been retired # Helper functions for retireving useful information from azure-sdk-for-* repo # Example Use : Import-Module .\eng\common\scripts\modules class PackageProps diff --git a/sdk/communication/communication-administration/CHANGELOG.md b/sdk/communication/communication-administration/CHANGELOG.md index afadab3e8aef..18044cae1dcb 100644 --- a/sdk/communication/communication-administration/CHANGELOG.md +++ b/sdk/communication/communication-administration/CHANGELOG.md @@ -1,5 +1,7 @@ # Release History +## 1.0.0-beta.3 (Unreleased) + ## 1.0.0-beta.2 (2020-10-06) Added support for phone number administration. diff --git a/sdk/communication/communication-administration/package.json b/sdk/communication/communication-administration/package.json index 21ab83ff801c..9c2b23dbe795 100644 --- a/sdk/communication/communication-administration/package.json +++ b/sdk/communication/communication-administration/package.json @@ -1,6 +1,6 @@ { "name": "@azure/communication-administration", - "version": "1.0.0-beta.2", + "version": "1.0.0-beta.3", "description": "SDK for Azure Communication service which facilitates user token administration.", "sdk-type": "client", "main": "dist/index.js", @@ -60,7 +60,7 @@ "sideEffects": false, "prettier": "@azure/eslint-plugin-azure-sdk/prettier.json", "dependencies": { - "@azure/communication-common": "1.0.0-beta.2", + "@azure/communication-common": "1.0.0-beta.3", "@azure/core-auth": "^1.1.3", "@azure/core-http": "^1.1.6", "@azure/core-paging": "^1.1.1", diff --git a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClientContext.ts b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClientContext.ts index 2a8b028d151a..9152ad2a290a 100644 --- a/sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClientContext.ts +++ b/sdk/communication/communication-administration/src/communicationIdentity/generated/src/generatedCommunicationIdentityClientContext.ts @@ -11,7 +11,7 @@ import * as coreHttp from "@azure/core-http"; const packageName = "azure-communication-administration-identity"; -const packageVersion = "1.0.0-beta.2"; +const packageVersion = "1.0.0-beta.3"; export class GeneratedCommunicationIdentityClientContext extends coreHttp.ServiceClient { /** diff --git a/sdk/communication/communication-administration/swagger/CommunicationIdentity.md b/sdk/communication/communication-administration/swagger/CommunicationIdentity.md index 5ee804214692..296f54dc19f0 100644 --- a/sdk/communication/communication-administration/swagger/CommunicationIdentity.md +++ b/sdk/communication/communication-administration/swagger/CommunicationIdentity.md @@ -9,7 +9,7 @@ package-name: azure-communication-administration-identity title: CommunicationIdentityConfigurationClient override-client-name: GeneratedCommunicationIdentityClient description: Communication identity configuration client -package-version: 1.0.0-beta.2 +package-version: 1.0.0-beta.3 generate-metadata: false license-header: MICROSOFT_MIT_NO_VERSION output-folder: ../src/communicationIdentity/generated diff --git a/sdk/communication/communication-chat/CHANGELOG.md b/sdk/communication/communication-chat/CHANGELOG.md index a2b5d807c7c3..e71e68ede491 100644 --- a/sdk/communication/communication-chat/CHANGELOG.md +++ b/sdk/communication/communication-chat/CHANGELOG.md @@ -1,5 +1,7 @@ # Release History +## 1.0.0-beta.3 (Unreleased) + ## 1.0.0-beta.2 (2020-10-06) Updated `@azure/communication-chat` version diff --git a/sdk/communication/communication-chat/package.json b/sdk/communication/communication-chat/package.json index 12429dc8fbb4..a6e018913969 100644 --- a/sdk/communication/communication-chat/package.json +++ b/sdk/communication/communication-chat/package.json @@ -1,6 +1,6 @@ { "name": "@azure/communication-chat", - "version": "1.0.0-beta.2", + "version": "1.0.0-beta.3", "description": "Azure client library for Azure Communication Chat services", "sdk-type": "client", "main": "dist/index.js", @@ -8,7 +8,7 @@ "types": "types/communication-chat.d.ts", "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 --version=3.0.6267 --v3 --package-version=1.0.0-beta.2 && rushx format", + "build:autorest": "autorest ./swagger/README.md --typescript --version=3.0.6267 --v3 --package-version=1.0.0-beta.3 && rushx format", "build:browser": "tsc -p . && cross-env ONLY_BROWSER=true rollup -c 2>&1", "build:node": "tsc -p . && cross-env ONLY_NODE=true rollup -c 2>&1", "build:samples": "cd samples && tsc -p .", @@ -21,7 +21,7 @@ "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"", "integration-test:browser": "karma start --single-run", "integration-test:node": "nyc mocha -r esm --require source-map-support/register --reporter ../../../common/tools/mocha-multi-reporter.js --full-trace -t 300000 dist-esm/test/*.spec.js dist-esm/test/node/*.spec.js", - "integration-test": "npm run integration-test:node && npm run integration-test:browser", + "integration-test": "npm run integration-test:node && npm run integration-test:browser", "lint:fix": "eslint package.json tsconfig.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]", "lint": "eslint package.json tsconfig.json api-extractor.json src test --ext .ts -f html -o communication-chat-lintReport.html || exit 0", "pack": "npm pack 2>&1", @@ -65,7 +65,7 @@ "prettier": "@azure/eslint-plugin-azure-sdk/prettier.json", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/communication-common": "1.0.0-beta.2", + "@azure/communication-common": "1.0.0-beta.3", "@azure/communication-signaling": "1.0.0-beta.1", "@azure/core-auth": "^1.1.3", "@azure/core-http": "^1.1.6", @@ -77,7 +77,7 @@ "@azure/core-paging": "^1.1.1" }, "devDependencies": { - "@azure/communication-administration": "1.0.0-beta.2", + "@azure/communication-administration": "1.0.0-beta.3", "@azure/eslint-plugin-azure-sdk": "^3.0.0", "@azure/test-utils-recorder": "^1.0.0", "@microsoft/api-extractor": "7.7.11", diff --git a/sdk/communication/communication-chat/src/generated/src/chatApiClientContext.ts b/sdk/communication/communication-chat/src/generated/src/chatApiClientContext.ts index af45ad2e7c87..076066313f29 100644 --- a/sdk/communication/communication-chat/src/generated/src/chatApiClientContext.ts +++ b/sdk/communication/communication-chat/src/generated/src/chatApiClientContext.ts @@ -10,7 +10,7 @@ import * as coreHttp from "@azure/core-http"; import { ChatApiClientOptionalParams } from "./models"; const packageName = "azure-communication-chat"; -const packageVersion = "1.0.0-beta.2"; +const packageVersion = "1.0.0-beta.3"; export class ChatApiClientContext extends coreHttp.ServiceClient { endpoint: string; diff --git a/sdk/communication/communication-common/CHANGELOG.md b/sdk/communication/communication-common/CHANGELOG.md index 59e86744292e..3dc61bd65737 100644 --- a/sdk/communication/communication-common/CHANGELOG.md +++ b/sdk/communication/communication-common/CHANGELOG.md @@ -1,5 +1,7 @@ # Release History +## 1.0.0-beta.3 (Unreleased) + ## 1.0.0-beta.2 (2020-10-06) Updated `@azure/communication-common` version diff --git a/sdk/communication/communication-common/package.json b/sdk/communication/communication-common/package.json index cf0b88f1d906..b1ea6a38296a 100644 --- a/sdk/communication/communication-common/package.json +++ b/sdk/communication/communication-common/package.json @@ -1,6 +1,6 @@ { "name": "@azure/communication-common", - "version": "1.0.0-beta.2", + "version": "1.0.0-beta.3", "description": "Common package for Azure Communication services.", "sdk-type": "client", "main": "dist/index.js", diff --git a/sdk/communication/communication-sms/CHANGELOG.md b/sdk/communication/communication-sms/CHANGELOG.md index e0a0999f9d52..5b64aa987acb 100644 --- a/sdk/communication/communication-sms/CHANGELOG.md +++ b/sdk/communication/communication-sms/CHANGELOG.md @@ -1,5 +1,7 @@ # Release History +## 1.0.0-beta.3 (Unreleased) + ## 1.0.0-beta.2 (2020-10-06) Updated `@azure/communication-sms` version diff --git a/sdk/communication/communication-sms/package.json b/sdk/communication/communication-sms/package.json index 9f051d403874..3bf7af49b33e 100644 --- a/sdk/communication/communication-sms/package.json +++ b/sdk/communication/communication-sms/package.json @@ -1,6 +1,6 @@ { "name": "@azure/communication-sms", - "version": "1.0.0-beta.2", + "version": "1.0.0-beta.3", "description": "SDK for Azure Communication SMS service which facilitates the sending of SMS messages.", "sdk-type": "client", "main": "dist/index.js", @@ -12,7 +12,7 @@ "types": "types/communication-sms.d.ts", "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 --v3 --package-version=1.0.0-beta.2 && rushx format", + "build:autorest": "autorest ./swagger/README.md --typescript --v3 --package-version=1.0.0-beta.3 && rushx format", "build:browser": "tsc -p . && cross-env ONLY_BROWSER=true rollup -c 2>&1", "build:node": "tsc -p . && cross-env ONLY_NODE=true rollup -c 2>&1", "build:samples": "cd samples && tsc -p .", @@ -65,7 +65,7 @@ "prettier": "@azure/eslint-plugin-azure-sdk/prettier.json", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/communication-common": "1.0.0-beta.2", + "@azure/communication-common": "1.0.0-beta.3", "@azure/core-auth": "^1.1.3", "@azure/core-http": "^1.1.6", "@azure/core-tracing": "1.0.0-preview.9", diff --git a/sdk/communication/communication-sms/src/generated/src/smsApiClientContext.ts b/sdk/communication/communication-sms/src/generated/src/smsApiClientContext.ts index 903d008b20ab..bd6f9d77b6bb 100644 --- a/sdk/communication/communication-sms/src/generated/src/smsApiClientContext.ts +++ b/sdk/communication/communication-sms/src/generated/src/smsApiClientContext.ts @@ -11,7 +11,7 @@ import * as coreHttp from "@azure/core-http"; const packageName = "azure-communication-sms"; -const packageVersion = "1.0.0-beta.2"; +const packageVersion = "1.0.0-beta.3"; export class SmsApiClientContext extends coreHttp.ServiceClient { endpoint: string; diff --git a/sdk/cosmosdb/cosmos/CHANGELOG.md b/sdk/cosmosdb/cosmos/CHANGELOG.md index 6a31f4605946..008d521794fb 100644 --- a/sdk/cosmosdb/cosmos/CHANGELOG.md +++ b/sdk/cosmosdb/cosmos/CHANGELOG.md @@ -2,6 +2,7 @@ ## 3.9.3 (Unreleased) +- BUGFIX: Fixes bulk operations with top level partitionKey values that are undefined or null. ## 3.9.2 (2020-09-16) diff --git a/sdk/cosmosdb/cosmos/src/utils/batch.ts b/sdk/cosmosdb/cosmos/src/utils/batch.ts index 15274fa93725..0cf7aef05d75 100644 --- a/sdk/cosmosdb/cosmos/src/utils/batch.ts +++ b/sdk/cosmosdb/cosmos/src/utils/batch.ts @@ -129,7 +129,8 @@ export function hasResource( export function getPartitionKeyToHash(operation: Operation, partitionProperty: string) { const toHashKey = hasResource(operation) ? (operation.resourceBody as any)[partitionProperty] - : operation.partitionKey.replace(/[\[\]\"\']/g, ""); + : (operation.partitionKey && operation.partitionKey.replace(/[\[\]\"\']/g, "")) || + operation.partitionKey; // We check for empty object since replace will stringify the value // The second check avoids cases where the partitionKey value is actually the string '{}' if (toHashKey === "{}" && operation.partitionKey === "[{}]") { @@ -151,7 +152,7 @@ export function decorateOperation( operation.resourceBody.id = uuid(); } } - if (operation.partitionKey) { + if ("partitionKey" in operation) { const extracted = extractPartitionKey(operation, { paths: ["/partitionKey"] }); return { ...operation, partitionKey: JSON.stringify(extracted) } as Operation; } else if ( diff --git a/sdk/cosmosdb/cosmos/test/functional/item.spec.ts b/sdk/cosmosdb/cosmos/test/functional/item.spec.ts index 0d31df9373ed..255f3cea5352 100644 --- a/sdk/cosmosdb/cosmos/test/functional/item.spec.ts +++ b/sdk/cosmosdb/cosmos/test/functional/item.spec.ts @@ -441,6 +441,43 @@ describe("bulk item operations", function() { const response = await v2Container.items.bulk(operations); assert.equal(response[0].statusCode, 201); }); + it("handles operations with null, undefined, and 0 partition keys", async function() { + const item1Id = addEntropy("item1"); + const item2Id = addEntropy("item2"); + const item3Id = addEntropy("item2"); + await v2Container.items.create({ + id: item1Id, + key: null, + class: "2010" + }); + await v2Container.items.create({ + id: item2Id, + key: 0 + }); + await v2Container.items.create({ + id: item3Id, + key: undefined + }); + const operations: OperationInput[] = [ + { + operationType: BulkOperationType.Read, + id: item1Id, + partitionKey: null + }, + { + operationType: BulkOperationType.Read, + id: item2Id, + partitionKey: 0 + }, + { + operationType: BulkOperationType.Read, + id: item3Id, + partitionKey: undefined + } + ]; + const response = await v2Container.items.bulk(operations); + assert.equal(response[0].statusCode, 201); + }); }); describe("v2 single partition container", async function() { let container: Container; diff --git a/sdk/eventgrid/eventgrid/CHANGELOG.md b/sdk/eventgrid/eventgrid/CHANGELOG.md index e36bed2c62e0..001dfd5f58eb 100644 --- a/sdk/eventgrid/eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/eventgrid/CHANGELOG.md @@ -1,7 +1,8 @@ # Release History -## 3.0.0-beta.3 (Unreleased) +## 3.0.0-beta.3 (2020-10-06) +- Added distributed tracing support. `EventGridProducerClient` will now create spans when sending events to Event Grid. - Added support for system events sent by Azure Key Vault. ### Breaking Changes diff --git a/sdk/keyvault/keyvault-keys/CHANGELOG.md b/sdk/keyvault/keyvault-keys/CHANGELOG.md index be4aed8884a6..6cdcf3b8b0ef 100644 --- a/sdk/keyvault/keyvault-keys/CHANGELOG.md +++ b/sdk/keyvault/keyvault-keys/CHANGELOG.md @@ -1,6 +1,7 @@ # Release History -## 4.2.0-beta.2 (Unreleased) +## 4.2.0-beta.2 (2020-10-06) + - Added the `oct-HSM` type to `KeyType`. - Added encryption, decryption, wrapping and unwrapping service support for the algorithms "A128GCM", "A192GCM", "A256GCM", "A128KW", "A192KW", "A256KW", "A128CBC", "A192CBC", "A256CBC", "A128CBCPAD", "A192CBCPAD", "A256CBCPAD". - The encryption, decryption, wrapping and unwrapping operations now support the following optional parameters: diff --git a/sdk/metricsadvisor/ai-metrics-advisor/CHANGELOG.md b/sdk/metricsadvisor/ai-metrics-advisor/CHANGELOG.md index 0f0f90277eab..05749ac48c74 100644 --- a/sdk/metricsadvisor/ai-metrics-advisor/CHANGELOG.md +++ b/sdk/metricsadvisor/ai-metrics-advisor/CHANGELOG.md @@ -1,6 +1,6 @@ # Release History -## 1.0.0-beta.1 (Unreleased) +## 1.0.0-beta.1 (2020-10-07) - This release is a preview of our efforts to create a client library that is user friendly and idiomatic to the JavaScript ecosystem. The reasons for most of the changes in this update can be found in the diff --git a/sdk/metricsadvisor/ai-metrics-advisor/package.json b/sdk/metricsadvisor/ai-metrics-advisor/package.json index 43de92b219cb..899f202aa590 100644 --- a/sdk/metricsadvisor/ai-metrics-advisor/package.json +++ b/sdk/metricsadvisor/ai-metrics-advisor/package.json @@ -4,7 +4,6 @@ "author": "Microsoft Corporation", "description": "An isomorphic client library for the Azure Metrics Advisor service.", "version": "1.0.0-beta.1", - "private": true, "keywords": [ "node", "azure", diff --git a/sdk/schemaregistry/schema-registry-avro/src/schemaRegistryAvroSerializer.ts b/sdk/schemaregistry/schema-registry-avro/src/schemaRegistryAvroSerializer.ts index 03f358de1e7a..aef75f4ffe0b 100644 --- a/sdk/schemaregistry/schema-registry-avro/src/schemaRegistryAvroSerializer.ts +++ b/sdk/schemaregistry/schema-registry-avro/src/schemaRegistryAvroSerializer.ts @@ -169,7 +169,7 @@ export class SchemaRegistryAvroSerializer { const schemaResponse = await this.registry.getSchemaById(schemaId); if (!schemaResponse.serializationType.match(/^avro$/i)) { throw new Error( - `Schema with ID '${schemaResponse.id}' has has serialization type '${schemaResponse.serializationType}', not 'avro'.` + `Schema with ID '${schemaResponse.id}' has serialization type '${schemaResponse.serializationType}', not 'avro'.` ); } diff --git a/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_fails_to_get_schema_by_id_when_given_invalid_id.json b/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_fails_to_get_schema_by_id_when_given_invalid_id.json index 62182470fe4e..cf9ee3f0eebb 100644 --- a/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_fails_to_get_schema_by_id_when_given_invalid_id.json +++ b/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_fails_to_get_schema_by_id_when_given_invalid_id.json @@ -4,5 +4,5 @@ "uniqueName": {}, "newDate": {} }, - "hash": "7220741891b091659a7e96987c33a460" + "hash": "6f572a97d843ab607d39229f05cc94be" } \ No newline at end of file diff --git a/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_fails_to_get_schema_id_when_given_invalid_args.json b/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_fails_to_get_schema_id_when_given_invalid_args.json index 3ec4aa57a074..6ef54403529f 100644 --- a/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_fails_to_get_schema_id_when_given_invalid_args.json +++ b/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_fails_to_get_schema_id_when_given_invalid_args.json @@ -11,29 +11,29 @@ "cache-control": "no-store, no-cache", "content-length": "1321", "content-type": "application/json; charset=utf-8", - "date": "Wed, 19 Aug 2020 14:57:59 GMT", + "date": "Mon, 05 Oct 2020 21:31:53 GMT", "expires": "-1", "p3p": "CP=\"DSP CUR OTPi IND OTRi ONL FIN\"", "pragma": "no-cache", "referrer-policy": "strict-origin-when-cross-origin", "strict-transport-security": "max-age=31536000; includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-ests-server": "2.1.10963.12 - SCUS ProdSlices", - "x-ms-request-id": "a44e3961-5fcd-4a2b-af72-721fb1011c00" + "x-ms-ests-server": "2.1.11086.7 - WUS2 ProdSlices", + "x-ms-request-id": "9d5e0c6e-eefb-4836-8253-bcf009e2b601" } }, { "method": "POST", "url": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022", "query": { - "api-version": "2017-04" + "api-version": "2020-09-01-preview" }, - "requestBody": "\"{\\\"type\\\":\\\"record\\\",\\\"name\\\":\\\"User\\\",\\\"namespace\\\":\\\"com.azure.schemaregistry.samples\\\",\\\"fields\\\":[{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"favoriteNumber\\\",\\\"type\\\":\\\"int\\\"}]}\"", + "requestBody": "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"com.azure.schemaregistry.samples\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favoriteNumber\",\"type\":\"int\"}]}", "status": 400, - "response": "400Invalid schema type for POST request. 'not-valid' is not supported. TrackingId:a8ca8631-cca1-4c2a-8c45-7966b97608a5_G2, SystemTracker:endpoint:$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022, Timestamp:2020-08-19T14:58:00", + "response": "{\"Code\":400,\"Detail\":\"Invalid schema type for POST request. 'not-valid' is not supported. TrackingId:d440bcd1-0d67-43df-aefd-fe0197182949_G2, SystemTracker:endpoint:$schemagroups\\/azsdk_js_test_group\\/schemas\\/azsdk_js_test_000022, Timestamp:2020-10-05T21:31:54\"}", "responseHeaders": { - "content-type": "application/xml; charset=utf-8", - "date": "Wed, 19 Aug 2020 14:57:59 GMT", + "content-type": "application/json", + "date": "Mon, 05 Oct 2020 21:31:54 GMT", "server": "Microsoft-HTTPAPI/2.0", "strict-transport-security": "max-age=31536000", "transfer-encoding": "chunked" @@ -44,5 +44,5 @@ "uniqueName": {}, "newDate": {} }, - "hash": "6d47aa1dccb69e0e485abcb3b7517281" + "hash": "65ea37c6e1f5b6bb10cdc1fe4668aa6e" } \ No newline at end of file diff --git a/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_fails_to_get_schema_id_when_no_matching_schema_exists.json b/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_fails_to_get_schema_id_when_no_matching_schema_exists.json index fc4397edd3e8..e4b88278ab06 100644 --- a/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_fails_to_get_schema_id_when_no_matching_schema_exists.json +++ b/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_fails_to_get_schema_id_when_no_matching_schema_exists.json @@ -11,29 +11,29 @@ "cache-control": "no-store, no-cache", "content-length": "1321", "content-type": "application/json; charset=utf-8", - "date": "Wed, 19 Aug 2020 14:57:59 GMT", + "date": "Mon, 05 Oct 2020 21:31:54 GMT", "expires": "-1", "p3p": "CP=\"DSP CUR OTPi IND OTRi ONL FIN\"", "pragma": "no-cache", "referrer-policy": "strict-origin-when-cross-origin", "strict-transport-security": "max-age=31536000; includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-ests-server": "2.1.10963.12 - EUS ProdSlices", - "x-ms-request-id": "89a7d5b7-0b94-442b-965f-0dc2f4260900" + "x-ms-ests-server": "2.1.11086.7 - WUS2 ProdSlices", + "x-ms-request-id": "9d5e0c6e-eefb-4836-8253-bcf01be2b601" } }, { "method": "POST", "url": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/never-registered", "query": { - "api-version": "2017-04" + "api-version": "2020-09-01-preview" }, - "requestBody": "\"{\\\"type\\\":\\\"record\\\",\\\"name\\\":\\\"User\\\",\\\"namespace\\\":\\\"com.azure.schemaregistry.samples\\\",\\\"fields\\\":[{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"favoriteNumber\\\",\\\"type\\\":\\\"int\\\"}]}\"", + "requestBody": "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"com.azure.schemaregistry.samples\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favoriteNumber\",\"type\":\"int\"}]}", "status": 404, - "response": "404Schema azsdk_js_test_group/never-registered does not exist. TrackingId:6e255746-7a23-4d52-a4d7-1d2d320e0eb7_G2, SystemTracker:endpoint:$schemagroups/azsdk_js_test_group/schemas/never-registered, Timestamp:2020-08-19T14:58:01", + "response": "{\"Code\":404,\"Detail\":\"Schema azsdk_js_test_group\\/never-registered does not exist. TrackingId:e3a4ba29-1f00-4736-906f-840a8518c881_G2, SystemTracker:endpoint:$schemagroups\\/azsdk_js_test_group\\/schemas\\/never-registered, Timestamp:2020-10-05T21:31:55\"}", "responseHeaders": { - "content-type": "application/xml; charset=utf-8", - "date": "Wed, 19 Aug 2020 14:58:01 GMT", + "content-type": "application/json", + "date": "Mon, 05 Oct 2020 21:31:55 GMT", "server": "Microsoft-HTTPAPI/2.0", "strict-transport-security": "max-age=31536000", "transfer-encoding": "chunked" @@ -44,5 +44,5 @@ "uniqueName": {}, "newDate": {} }, - "hash": "9e983945505540675be9e6f7dd1639e7" + "hash": "7d401e42535b3b61eb2f6f62dc9471c8" } \ No newline at end of file diff --git a/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_fails_to_get_schema_when_no_schema_exists_with_given_id.json b/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_fails_to_get_schema_when_no_schema_exists_with_given_id.json index 3a3b5b9a2306..1c594a87dd16 100644 --- a/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_fails_to_get_schema_when_no_schema_exists_with_given_id.json +++ b/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_fails_to_get_schema_when_no_schema_exists_with_given_id.json @@ -11,29 +11,29 @@ "cache-control": "no-store, no-cache", "content-length": "1321", "content-type": "application/json; charset=utf-8", - "date": "Wed, 19 Aug 2020 14:58:01 GMT", + "date": "Mon, 05 Oct 2020 21:31:56 GMT", "expires": "-1", "p3p": "CP=\"DSP CUR OTPi IND OTRi ONL FIN\"", "pragma": "no-cache", "referrer-policy": "strict-origin-when-cross-origin", "strict-transport-security": "max-age=31536000; includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-ests-server": "2.1.10963.12 - EUS ProdSlices", - "x-ms-request-id": "25ad362c-72fc-47ac-9534-7060b7f51e00" + "x-ms-ests-server": "2.1.11086.7 - SCUS ProdSlices", + "x-ms-request-id": "38c27b57-286c-4b33-a980-8dd442b62101" } }, { "method": "GET", "url": "https://endpoint/$schemagroups/getSchemaById/ffffffffffffffffffffffffffffffff", "query": { - "api-version": "2017-04" + "api-version": "2020-09-01-preview" }, "requestBody": null, "status": 404, - "response": "404Schema id ffffffffffffffffffffffffffffffff does not exist. TrackingId:6acb9259-ea04-4ff8-b53a-0eeec936abdc_G2, SystemTracker:endpoint:$schemagroups/getSchemaById/ffffffffffffffffffffffffffffffff, Timestamp:2020-08-19T14:58:02", + "response": "{\"Code\":404,\"Detail\":\"Schema id ffffffffffffffffffffffffffffffff does not exist. TrackingId:daa08d0b-0c49-4d6b-8fa1-9d4e57f535f7_G2, SystemTracker:endpoint:$schemagroups\\/getSchemaById\\/ffffffffffffffffffffffffffffffff, Timestamp:2020-10-05T21:31:57\"}", "responseHeaders": { - "content-type": "application/xml; charset=utf-8", - "date": "Wed, 19 Aug 2020 14:58:02 GMT", + "content-type": "application/json", + "date": "Mon, 05 Oct 2020 21:31:56 GMT", "server": "Microsoft-HTTPAPI/2.0", "strict-transport-security": "max-age=31536000", "transfer-encoding": "chunked" @@ -44,5 +44,5 @@ "uniqueName": {}, "newDate": {} }, - "hash": "e3d393a14244a1dcd98b75f330116952" + "hash": "48553553ebd0830c8508d763e677a96c" } \ No newline at end of file diff --git a/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_gets_schema_by_id.json b/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_gets_schema_by_id.json index 9e0d385943e9..aac4035fc995 100644 --- a/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_gets_schema_by_id.json +++ b/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_gets_schema_by_id.json @@ -11,83 +11,61 @@ "cache-control": "no-store, no-cache", "content-length": "1321", "content-type": "application/json; charset=utf-8", - "date": "Wed, 19 Aug 2020 14:58:02 GMT", + "date": "Mon, 05 Oct 2020 21:31:56 GMT", "expires": "-1", "p3p": "CP=\"DSP CUR OTPi IND OTRi ONL FIN\"", "pragma": "no-cache", "referrer-policy": "strict-origin-when-cross-origin", "strict-transport-security": "max-age=31536000; includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-ests-server": "2.1.10963.12 - EUS ProdSlices", - "x-ms-request-id": "25ad362c-72fc-47ac-9534-7060d2f51e00" + "x-ms-ests-server": "2.1.11086.7 - WUS2 ProdSlices", + "x-ms-request-id": "ac9a0126-3939-44e9-95e3-d69e6e5fbd01" } }, { "method": "PUT", "url": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022", "query": { - "api-version": "2017-04" + "api-version": "2020-09-01-preview" }, - "requestBody": "\"{\\\"type\\\":\\\"record\\\",\\\"name\\\":\\\"User\\\",\\\"namespace\\\":\\\"com.azure.schemaregistry.samples\\\",\\\"fields\\\":[{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"favoriteNumber\\\",\\\"type\\\":\\\"int\\\"}]}\"", + "requestBody": "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"com.azure.schemaregistry.samples\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favoriteNumber\",\"type\":\"int\"}]}", "status": 200, - "response": "{\"id\":\"e2e5788061834d6f977442df0fcbcfb8\"}", + "response": "{\"id\":\"61d32a86b70e4fe0b026c1291c0aee7a\"}", "responseHeaders": { "content-type": "application/json", - "date": "Wed, 19 Aug 2020 14:58:03 GMT", - "location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/5?api-version=2017-04", + "date": "Mon, 05 Oct 2020 21:31:57 GMT", + "location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/45?api-version=2020-09-01-preview", + "schema-id": "61d32a86b70e4fe0b026c1291c0aee7a", + "schema-id-location": "https://endpoint/$schemagroups/getschemabyid/61d32a86b70e4fe0b026c1291c0aee7a?api-version=2020-09-01-preview", + "schema-version": "45", + "schema-versions-location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2020-09-01-preview", + "serialization-type": "Avro", "server": "Microsoft-HTTPAPI/2.0", "strict-transport-security": "max-age=31536000", - "transfer-encoding": "chunked", - "x-schema-id": "e2e5788061834d6f977442df0fcbcfb8", - "x-schema-id-location": "https://endpoint/$schemagroups/getschemabyid/e2e5788061834d6f977442df0fcbcfb8?api-version=2017-04", - "x-schema-type": "Avro", - "x-schema-version": "5", - "x-schema-versions-location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2017-04" - } - }, - { - "method": "POST", - "url": "https://login.microsoftonline.com/azure_tenant_id/oauth2/v2.0/token", - "query": {}, - "requestBody": "response_type=token&grant_type=client_credentials&client_id=azure_client_id&client_secret=azure_client_secret&scope=https%3A%2F%2Feventhubs.azure.net%2F.default", - "status": 200, - "response": "{\"token_type\":\"Bearer\",\"expires_in\":86399,\"ext_expires_in\":86399,\"access_token\":\"access_token\"}", - "responseHeaders": { - "cache-control": "no-store, no-cache", - "content-length": "1321", - "content-type": "application/json; charset=utf-8", - "date": "Wed, 19 Aug 2020 14:58:02 GMT", - "expires": "-1", - "p3p": "CP=\"DSP CUR OTPi IND OTRi ONL FIN\"", - "pragma": "no-cache", - "referrer-policy": "strict-origin-when-cross-origin", - "strict-transport-security": "max-age=31536000; includeSubDomains", - "x-content-type-options": "nosniff", - "x-ms-ests-server": "2.1.10963.12 - EUS ProdSlices", - "x-ms-request-id": "38eb9bff-4d7a-4139-b4e9-2f1ab9cc1d00" + "transfer-encoding": "chunked" } }, { "method": "GET", - "url": "https://endpoint/$schemagroups/getSchemaById/e2e5788061834d6f977442df0fcbcfb8", + "url": "https://endpoint/$schemagroups/getSchemaById/61d32a86b70e4fe0b026c1291c0aee7a", "query": { - "api-version": "2017-04" + "api-version": "2020-09-01-preview" }, "requestBody": null, "status": 200, - "response": "\"{\\\"type\\\":\\\"record\\\",\\\"name\\\":\\\"User\\\",\\\"namespace\\\":\\\"com.azure.schemaregistry.samples\\\",\\\"fields\\\":[{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"favoriteNumber\\\",\\\"type\\\":\\\"int\\\"}]}\"", + "response": "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"com.azure.schemaregistry.samples\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favoriteNumber\",\"type\":\"int\"}]}", "responseHeaders": { "content-type": "application/json", - "date": "Wed, 19 Aug 2020 14:58:03 GMT", - "location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/5?api-version=2017-04", + "date": "Mon, 05 Oct 2020 21:31:57 GMT", + "location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/45?api-version=2020-09-01-preview", + "schema-id": "61d32a86b70e4fe0b026c1291c0aee7a", + "schema-id-location": "https://endpoint/$schemagroups/getschemabyid/61d32a86b70e4fe0b026c1291c0aee7a?api-version=2020-09-01-preview", + "schema-version": "45", + "schema-versions-location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2020-09-01-preview", + "serialization-type": "Avro", "server": "Microsoft-HTTPAPI/2.0", "strict-transport-security": "max-age=31536000", - "transfer-encoding": "chunked", - "x-schema-id": "e2e5788061834d6f977442df0fcbcfb8", - "x-schema-id-location": "https://endpoint/$schemagroups/getschemabyid/e2e5788061834d6f977442df0fcbcfb8?api-version=2017-04", - "x-schema-type": "Avro", - "x-schema-version": "5", - "x-schema-versions-location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2017-04" + "transfer-encoding": "chunked" } } ], @@ -95,5 +73,5 @@ "uniqueName": {}, "newDate": {} }, - "hash": "08a40f030c832fb81f5f6dc66f61b2f1" + "hash": "fe1a1747c1a9d7c362ec5d3f46bbb92f" } \ No newline at end of file diff --git a/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_gets_schema_id.json b/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_gets_schema_id.json index e4ddc4a58f85..94e8d5895654 100644 --- a/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_gets_schema_id.json +++ b/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_gets_schema_id.json @@ -11,83 +11,61 @@ "cache-control": "no-store, no-cache", "content-length": "1321", "content-type": "application/json; charset=utf-8", - "date": "Wed, 19 Aug 2020 14:58:00 GMT", + "date": "Mon, 05 Oct 2020 21:31:54 GMT", "expires": "-1", "p3p": "CP=\"DSP CUR OTPi IND OTRi ONL FIN\"", "pragma": "no-cache", "referrer-policy": "strict-origin-when-cross-origin", "strict-transport-security": "max-age=31536000; includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-ests-server": "2.1.10963.12 - SCUS ProdSlices", - "x-ms-request-id": "a44e3961-5fcd-4a2b-af72-721fe4011c00" + "x-ms-ests-server": "2.1.11086.7 - EUS ProdSlices", + "x-ms-request-id": "d36c8a8c-e537-4665-8d4a-5624b17f1f01" } }, { "method": "PUT", "url": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022", "query": { - "api-version": "2017-04" + "api-version": "2020-09-01-preview" }, - "requestBody": "\"{\\\"type\\\":\\\"record\\\",\\\"name\\\":\\\"User\\\",\\\"namespace\\\":\\\"com.azure.schemaregistry.samples\\\",\\\"fields\\\":[{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"favoriteNumber\\\",\\\"type\\\":\\\"int\\\"}]}\"", + "requestBody": "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"com.azure.schemaregistry.samples\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favoriteNumber\",\"type\":\"int\"}]}", "status": 200, - "response": "{\"id\":\"e2e5788061834d6f977442df0fcbcfb8\"}", + "response": "{\"id\":\"61d32a86b70e4fe0b026c1291c0aee7a\"}", "responseHeaders": { "content-type": "application/json", - "date": "Wed, 19 Aug 2020 14:58:01 GMT", - "location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/5?api-version=2017-04", + "date": "Mon, 05 Oct 2020 21:31:55 GMT", + "location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/45?api-version=2020-09-01-preview", + "schema-id": "61d32a86b70e4fe0b026c1291c0aee7a", + "schema-id-location": "https://endpoint/$schemagroups/getschemabyid/61d32a86b70e4fe0b026c1291c0aee7a?api-version=2020-09-01-preview", + "schema-version": "45", + "schema-versions-location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2020-09-01-preview", + "serialization-type": "Avro", "server": "Microsoft-HTTPAPI/2.0", "strict-transport-security": "max-age=31536000", - "transfer-encoding": "chunked", - "x-schema-id": "e2e5788061834d6f977442df0fcbcfb8", - "x-schema-id-location": "https://endpoint/$schemagroups/getschemabyid/e2e5788061834d6f977442df0fcbcfb8?api-version=2017-04", - "x-schema-type": "Avro", - "x-schema-version": "5", - "x-schema-versions-location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2017-04" - } - }, - { - "method": "POST", - "url": "https://login.microsoftonline.com/azure_tenant_id/oauth2/v2.0/token", - "query": {}, - "requestBody": "response_type=token&grant_type=client_credentials&client_id=azure_client_id&client_secret=azure_client_secret&scope=https%3A%2F%2Feventhubs.azure.net%2F.default", - "status": 200, - "response": "{\"token_type\":\"Bearer\",\"expires_in\":86399,\"ext_expires_in\":86399,\"access_token\":\"access_token\"}", - "responseHeaders": { - "cache-control": "no-store, no-cache", - "content-length": "1321", - "content-type": "application/json; charset=utf-8", - "date": "Wed, 19 Aug 2020 14:58:00 GMT", - "expires": "-1", - "p3p": "CP=\"DSP CUR OTPi IND OTRi ONL FIN\"", - "pragma": "no-cache", - "referrer-policy": "strict-origin-when-cross-origin", - "strict-transport-security": "max-age=31536000; includeSubDomains", - "x-content-type-options": "nosniff", - "x-ms-ests-server": "2.1.10963.12 - WUS2 ProdSlices", - "x-ms-request-id": "c0655f2e-bcde-41e6-8dfd-28d90ef72400" + "transfer-encoding": "chunked" } }, { "method": "POST", "url": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022", "query": { - "api-version": "2017-04" + "api-version": "2020-09-01-preview" }, - "requestBody": "\"{\\\"type\\\":\\\"record\\\",\\\"name\\\":\\\"User\\\",\\\"namespace\\\":\\\"com.azure.schemaregistry.samples\\\",\\\"fields\\\":[{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"favoriteNumber\\\",\\\"type\\\":\\\"int\\\"}]}\"", + "requestBody": "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"com.azure.schemaregistry.samples\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favoriteNumber\",\"type\":\"int\"}]}", "status": 200, "response": "{\"id\":\"35c8c3d0438c48c09602b6b765c6d8dd\"}", "responseHeaders": { "content-type": "application/json", - "date": "Wed, 19 Aug 2020 14:58:02 GMT", - "location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/3?api-version=2017-04", + "date": "Mon, 05 Oct 2020 21:31:56 GMT", + "location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/3?api-version=2020-09-01-preview", + "schema-id": "35c8c3d0438c48c09602b6b765c6d8dd", + "schema-id-location": "https://endpoint/$schemagroups/getschemabyid/35c8c3d0438c48c09602b6b765c6d8dd?api-version=2020-09-01-preview", + "schema-version": "3", + "schema-versions-location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2020-09-01-preview", + "serialization-type": "Avro", "server": "Microsoft-HTTPAPI/2.0", "strict-transport-security": "max-age=31536000", - "transfer-encoding": "chunked", - "x-schema-id": "35c8c3d0438c48c09602b6b765c6d8dd", - "x-schema-id-location": "https://endpoint/$schemagroups/getschemabyid/35c8c3d0438c48c09602b6b765c6d8dd?api-version=2017-04", - "x-schema-type": "Avro", - "x-schema-version": "3", - "x-schema-versions-location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2017-04" + "transfer-encoding": "chunked" } } ], @@ -95,5 +73,5 @@ "uniqueName": {}, "newDate": {} }, - "hash": "d6f9624eef29abc8a89b9717aa653796" + "hash": "46bb417d9fa5f687470ebddf45e933ac" } \ No newline at end of file diff --git a/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_registers_schema.json b/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_registers_schema.json index 13492002b3ca..fb9fc2328a98 100644 --- a/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_registers_schema.json +++ b/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_registers_schema.json @@ -11,83 +11,61 @@ "cache-control": "no-store, no-cache", "content-length": "1321", "content-type": "application/json; charset=utf-8", - "date": "Wed, 19 Aug 2020 14:57:58 GMT", + "date": "Mon, 05 Oct 2020 21:31:52 GMT", "expires": "-1", "p3p": "CP=\"DSP CUR OTPi IND OTRi ONL FIN\"", "pragma": "no-cache", "referrer-policy": "strict-origin-when-cross-origin", "strict-transport-security": "max-age=31536000; includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-ests-server": "2.1.10963.12 - WUS2 ProdSlices", - "x-ms-request-id": "c0655f2e-bcde-41e6-8dfd-28d9a9f62400" + "x-ms-ests-server": "2.1.11086.7 - SCUS ProdSlices", + "x-ms-request-id": "150c77df-d7b2-402f-bb17-73fa02212101" } }, { "method": "PUT", "url": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022", "query": { - "api-version": "2017-04" + "api-version": "2020-09-01-preview" }, - "requestBody": "\"{\\\"type\\\":\\\"record\\\",\\\"name\\\":\\\"User\\\",\\\"namespace\\\":\\\"com.azure.schemaregistry.samples\\\",\\\"fields\\\":[{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"favoriteNumber\\\",\\\"type\\\":\\\"int\\\"}]}\"", + "requestBody": "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"com.azure.schemaregistry.samples\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favoriteNumber\",\"type\":\"int\"}]}", "status": 200, - "response": "{\"id\":\"35c8c3d0438c48c09602b6b765c6d8dd\"}", + "response": "{\"id\":\"228b2b0ea7f74b55a80f6651d6641b59\"}", "responseHeaders": { "content-type": "application/json", - "date": "Wed, 19 Aug 2020 14:57:59 GMT", - "location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/3?api-version=2017-04", + "date": "Mon, 05 Oct 2020 21:31:53 GMT", + "location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/43?api-version=2020-09-01-preview", + "schema-id": "228b2b0ea7f74b55a80f6651d6641b59", + "schema-id-location": "https://endpoint/$schemagroups/getschemabyid/228b2b0ea7f74b55a80f6651d6641b59?api-version=2020-09-01-preview", + "schema-version": "43", + "schema-versions-location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2020-09-01-preview", + "serialization-type": "Avro", "server": "Microsoft-HTTPAPI/2.0", "strict-transport-security": "max-age=31536000", - "transfer-encoding": "chunked", - "x-schema-id": "35c8c3d0438c48c09602b6b765c6d8dd", - "x-schema-id-location": "https://endpoint/$schemagroups/getschemabyid/35c8c3d0438c48c09602b6b765c6d8dd?api-version=2017-04", - "x-schema-type": "Avro", - "x-schema-version": "3", - "x-schema-versions-location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2017-04" - } - }, - { - "method": "POST", - "url": "https://login.microsoftonline.com/azure_tenant_id/oauth2/v2.0/token", - "query": {}, - "requestBody": "response_type=token&grant_type=client_credentials&client_id=azure_client_id&client_secret=azure_client_secret&scope=https%3A%2F%2Feventhubs.azure.net%2F.default", - "status": 200, - "response": "{\"token_type\":\"Bearer\",\"expires_in\":86399,\"ext_expires_in\":86399,\"access_token\":\"access_token\"}", - "responseHeaders": { - "cache-control": "no-store, no-cache", - "content-length": "1321", - "content-type": "application/json; charset=utf-8", - "date": "Wed, 19 Aug 2020 14:57:58 GMT", - "expires": "-1", - "p3p": "CP=\"DSP CUR OTPi IND OTRi ONL FIN\"", - "pragma": "no-cache", - "referrer-policy": "strict-origin-when-cross-origin", - "strict-transport-security": "max-age=31536000; includeSubDomains", - "x-content-type-options": "nosniff", - "x-ms-ests-server": "2.1.10963.12 - NCUS ProdSlices", - "x-ms-request-id": "c71e49e2-e297-4e03-a148-9ab730ed1c00" + "transfer-encoding": "chunked" } }, { "method": "PUT", "url": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022", "query": { - "api-version": "2017-04" + "api-version": "2020-09-01-preview" }, - "requestBody": "\"{\\\"type\\\":\\\"record\\\",\\\"fullName\\\":\\\"User\\\",\\\"namespace\\\":\\\"com.azure.schemaregistry.samples\\\",\\\"fields\\\":[{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"favoriteNumber\\\",\\\"type\\\":\\\"int\\\"}]}\"", + "requestBody": "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"com.azure.schemaregistry.samples\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"secondFavoriteNumber\",\"type\":\"int\"}]}", "status": 200, - "response": "{\"id\":\"92a2b39babd44463bcbeed50d4e8b6b1\"}", + "response": "{\"id\":\"b19dc4f576434e94be7607c4a74bf358\"}", "responseHeaders": { "content-type": "application/json", - "date": "Wed, 19 Aug 2020 14:57:59 GMT", - "location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/4?api-version=2017-04", + "date": "Mon, 05 Oct 2020 21:31:54 GMT", + "location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/44?api-version=2020-09-01-preview", + "schema-id": "b19dc4f576434e94be7607c4a74bf358", + "schema-id-location": "https://endpoint/$schemagroups/getschemabyid/b19dc4f576434e94be7607c4a74bf358?api-version=2020-09-01-preview", + "schema-version": "44", + "schema-versions-location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2020-09-01-preview", + "serialization-type": "Avro", "server": "Microsoft-HTTPAPI/2.0", "strict-transport-security": "max-age=31536000", - "transfer-encoding": "chunked", - "x-schema-id": "92a2b39babd44463bcbeed50d4e8b6b1", - "x-schema-id-location": "https://endpoint/$schemagroups/getschemabyid/92a2b39babd44463bcbeed50d4e8b6b1?api-version=2017-04", - "x-schema-type": "Avro", - "x-schema-version": "4", - "x-schema-versions-location": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2017-04" + "transfer-encoding": "chunked" } } ], @@ -95,5 +73,5 @@ "uniqueName": {}, "newDate": {} }, - "hash": "d70a4e54d26ef37c305961658b4abf4f" + "hash": "ed82d361a9cc87c17fc3152f41086443" } \ No newline at end of file diff --git a/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_rejects_schema_registration_with_invalid_args.json b/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_rejects_schema_registration_with_invalid_args.json index 137b8a395b25..a8c722fdd942 100644 --- a/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_rejects_schema_registration_with_invalid_args.json +++ b/sdk/schemaregistry/schema-registry/recordings/browsers/schemaregistryclient/recording_rejects_schema_registration_with_invalid_args.json @@ -11,29 +11,29 @@ "cache-control": "no-store, no-cache", "content-length": "1321", "content-type": "application/json; charset=utf-8", - "date": "Wed, 19 Aug 2020 14:57:57 GMT", + "date": "Mon, 05 Oct 2020 21:31:51 GMT", "expires": "-1", "p3p": "CP=\"DSP CUR OTPi IND OTRi ONL FIN\"", "pragma": "no-cache", "referrer-policy": "strict-origin-when-cross-origin", "strict-transport-security": "max-age=31536000; includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-ests-server": "2.1.10963.12 - WUS2 ProdSlices", - "x-ms-request-id": "c8c8543c-80fb-470e-be7e-e02376172200" + "x-ms-ests-server": "2.1.11086.7 - SCUS ProdSlices", + "x-ms-request-id": "4a456eb9-4840-4f7d-8873-79b602524b00" } }, { "method": "PUT", "url": "https://endpoint/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022", "query": { - "api-version": "2017-04" + "api-version": "2020-09-01-preview" }, - "requestBody": "\"{\\\"type\\\":\\\"record\\\",\\\"name\\\":\\\"User\\\",\\\"namespace\\\":\\\"com.azure.schemaregistry.samples\\\",\\\"fields\\\":[{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"favoriteNumber\\\",\\\"type\\\":\\\"int\\\"}]}\"", + "requestBody": "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"com.azure.schemaregistry.samples\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favoriteNumber\",\"type\":\"int\"}]}", "status": 400, - "response": "400Invalid schema type for POST request. 'not-valid' is not supported. TrackingId:558774c7-8118-4c6f-b1aa-6166c61d8d52_G2, SystemTracker:endpoint:$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022, Timestamp:2020-08-19T14:57:59", + "response": "{\"Code\":400,\"Detail\":\"Invalid schema type for PUT request. 'not-valid' is not supported. TrackingId:7b88bffd-4d27-4186-9358-868f6ae54dfe_G2, SystemTracker:endpoint:$schemagroups\\/azsdk_js_test_group\\/schemas\\/azsdk_js_test_000022, Timestamp:2020-10-05T21:31:53\"}", "responseHeaders": { - "content-type": "application/xml; charset=utf-8", - "date": "Wed, 19 Aug 2020 14:57:58 GMT", + "content-type": "application/json", + "date": "Mon, 05 Oct 2020 21:31:53 GMT", "server": "Microsoft-HTTPAPI/2.0", "strict-transport-security": "max-age=31536000", "transfer-encoding": "chunked" @@ -44,5 +44,5 @@ "uniqueName": {}, "newDate": {} }, - "hash": "6d98f6e4cf5c2d79ff486c979c6f04a6" + "hash": "2552cbc68a24ac555f653e6ca175af96" } \ No newline at end of file diff --git a/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_fails_to_get_schema_by_id_when_given_invalid_id.js b/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_fails_to_get_schema_by_id_when_given_invalid_id.js index 2eb57874d461..a75df8fa63a4 100644 --- a/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_fails_to_get_schema_by_id_when_given_invalid_id.js +++ b/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_fails_to_get_schema_by_id_when_given_invalid_id.js @@ -1,5 +1,5 @@ let nock = require('nock'); -module.exports.hash = "eb54ecf2058c7d4917b656b697b37131"; +module.exports.hash = "7e5d35a42c93ab32fc6ec0332173c2f6"; module.exports.testInfo = {"uniqueName":{},"newDate":{}} diff --git a/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_fails_to_get_schema_id_when_given_invalid_args.js b/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_fails_to_get_schema_id_when_given_invalid_args.js index bb74f3b3609f..1af811ccc3a0 100644 --- a/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_fails_to_get_schema_id_when_given_invalid_args.js +++ b/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_fails_to_get_schema_id_when_given_invalid_args.js @@ -1,6 +1,6 @@ let nock = require('nock'); -module.exports.hash = "01692f8260b5641cb639d46ce3104b9c"; +module.exports.hash = "a825068b76f7666e5480b179a9fb4768"; module.exports.testInfo = {"uniqueName":{},"newDate":{}} @@ -22,33 +22,33 @@ nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) 'P3P', 'CP="DSP CUR OTPi IND OTRi ONL FIN"', 'x-ms-request-id', - '54063e45-5c15-4af5-ab3e-25833b042100', + 'cf9620ff-02bf-42fe-b555-43bc2b7c8d00', 'x-ms-ests-server', - '2.1.10963.12 - SCUS ProdSlices', + '2.1.11086.7 - EUS ProdSlices', 'Set-Cookie', - 'fpc=As4byXOGWFhFjvunwhCwK0ZJ4DFtAQAAAO40z9YOAAAA; expires=Fri, 18-Sep-2020 14:57:51 GMT; path=/; secure; HttpOnly; SameSite=None', + 'fpc=ApALMtN-Ww1Kg8GH9ZQXLb9J4DFtAQAAALuHDdcOAAAA; expires=Wed, 04-Nov-2020 21:31:40 GMT; path=/; secure; HttpOnly; SameSite=None', 'Set-Cookie', 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', 'Set-Cookie', 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', 'Date', - 'Wed, 19 Aug 2020 14:57:51 GMT', + 'Mon, 05 Oct 2020 21:31:40 GMT', 'Content-Length', '1321' ]); nock('https://endpoint', {"encodedQueryParams":true}) - .post('/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022', "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"com.azure.schemaregistry.samples\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favoriteNumber\",\"type\":\"int\"}]}") + .post('/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022', {"type":"record","name":"User","namespace":"com.azure.schemaregistry.samples","fields":[{"name":"name","type":"string"},{"name":"favoriteNumber","type":"int"}]}) .query(true) - .reply(400, "400Invalid schema type for POST request. 'not-valid' is not supported. TrackingId:d46025d8-79f5-460c-a4c5-93b967b4fdd5_G0, SystemTracker:endpoint:$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022, Timestamp:2020-08-19T14:57:52", [ + .reply(400, {"Code":400,"Detail":"Invalid schema type for POST request. 'not-valid' is not supported. TrackingId:056052ff-ee36-4ace-a5e4-fb1e96302b11_G2, SystemTracker:endpoint:$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022, Timestamp:2020-10-05T21:31:41"}, [ 'Transfer-Encoding', 'chunked', 'Content-Type', - 'application/xml; charset=utf-8', + 'application/json', 'Server', 'Microsoft-HTTPAPI/2.0', 'Strict-Transport-Security', 'max-age=31536000', 'Date', - 'Wed, 19 Aug 2020 14:57:52 GMT' + 'Mon, 05 Oct 2020 21:31:41 GMT' ]); diff --git a/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_fails_to_get_schema_id_when_no_matching_schema_exists.js b/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_fails_to_get_schema_id_when_no_matching_schema_exists.js index fadb6aaa6065..0f09d5a35d0e 100644 --- a/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_fails_to_get_schema_id_when_no_matching_schema_exists.js +++ b/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_fails_to_get_schema_id_when_no_matching_schema_exists.js @@ -1,6 +1,6 @@ let nock = require('nock'); -module.exports.hash = "97bb3ef7d11ff026e400c3bb44bc641b"; +module.exports.hash = "622a3fd7cdca169239801a8ae7843dfd"; module.exports.testInfo = {"uniqueName":{},"newDate":{}} @@ -11,8 +11,6 @@ nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) 'no-store, no-cache', 'Pragma', 'no-cache', - 'Content-Length', - '1321', 'Content-Type', 'application/json; charset=utf-8', 'Expires', @@ -24,31 +22,33 @@ nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) 'P3P', 'CP="DSP CUR OTPi IND OTRi ONL FIN"', 'x-ms-request-id', - 'baddaa24-a171-4d4f-a9cf-f756d0692000', + '5181cea2-c7b2-49b4-b673-19acf5497100', 'x-ms-ests-server', - '2.1.10963.12 - EUS ProdSlices', + '2.1.11086.7 - SCUS ProdSlices', 'Set-Cookie', - 'fpc=AlIg_Q3r3IxLr1ycfAlPxVBJ4DFtAQAAAPA0z9YOAAAA; expires=Fri, 18-Sep-2020 14:57:52 GMT; path=/; secure; HttpOnly; SameSite=None', + 'fpc=AszGFwoG8hZNm38rm6OF0klJ4DFtAQAAALyHDdcOAAAA; expires=Wed, 04-Nov-2020 21:31:41 GMT; path=/; secure; HttpOnly; SameSite=None', 'Set-Cookie', 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', 'Set-Cookie', 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', 'Date', - 'Wed, 19 Aug 2020 14:57:51 GMT' + 'Mon, 05 Oct 2020 21:31:41 GMT', + 'Content-Length', + '1321' ]); nock('https://endpoint', {"encodedQueryParams":true}) - .post('/$schemagroups/azsdk_js_test_group/schemas/never-registered', "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"com.azure.schemaregistry.samples\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favoriteNumber\",\"type\":\"int\"}]}") + .post('/$schemagroups/azsdk_js_test_group/schemas/never-registered', {"type":"record","name":"User","namespace":"com.azure.schemaregistry.samples","fields":[{"name":"name","type":"string"},{"name":"favoriteNumber","type":"int"}]}) .query(true) - .reply(404, "404Schema azsdk_js_test_group/never-registered does not exist. TrackingId:082342de-dc68-4907-9835-dbaccbbbb232_G2, SystemTracker:endpoint:$schemagroups/azsdk_js_test_group/schemas/never-registered, Timestamp:2020-08-19T14:57:53", [ + .reply(404, {"Code":404,"Detail":"Schema azsdk_js_test_group/never-registered does not exist. TrackingId:a14afd8a-8c44-47e5-b546-a1f4cb5c26ac_G4, SystemTracker:endpoint:$schemagroups/azsdk_js_test_group/schemas/never-registered, Timestamp:2020-10-05T21:31:42"}, [ 'Transfer-Encoding', 'chunked', 'Content-Type', - 'application/xml; charset=utf-8', + 'application/json', 'Server', 'Microsoft-HTTPAPI/2.0', 'Strict-Transport-Security', 'max-age=31536000', 'Date', - 'Wed, 19 Aug 2020 14:57:53 GMT' + 'Mon, 05 Oct 2020 21:31:42 GMT' ]); diff --git a/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_fails_to_get_schema_when_no_schema_exists_with_given_id.js b/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_fails_to_get_schema_when_no_schema_exists_with_given_id.js index f290fe270b0b..cb31677d0be2 100644 --- a/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_fails_to_get_schema_when_no_schema_exists_with_given_id.js +++ b/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_fails_to_get_schema_when_no_schema_exists_with_given_id.js @@ -1,6 +1,6 @@ let nock = require('nock'); -module.exports.hash = "c48d48c73653528508e5def8772d97fd"; +module.exports.hash = "8a7a25f38a53c528d64492b8a40d024c"; module.exports.testInfo = {"uniqueName":{},"newDate":{}} @@ -11,8 +11,6 @@ nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) 'no-store, no-cache', 'Pragma', 'no-cache', - 'Content-Length', - '1321', 'Content-Type', 'application/json; charset=utf-8', 'Expires', @@ -24,31 +22,33 @@ nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) 'P3P', 'CP="DSP CUR OTPi IND OTRi ONL FIN"', 'x-ms-request-id', - '12dcda7c-4ec0-448a-ae62-10860f191f00', + 'af534171-5c3c-4bcb-9a85-ee5dca8a4701', 'x-ms-ests-server', - '2.1.10963.12 - NCUS ProdSlices', + '2.1.11086.7 - SCUS ProdSlices', 'Set-Cookie', - 'fpc=AljzUBQibbZDpdvcYAtfgRpJ4DFtAQAAAPE0z9YOAAAA; expires=Fri, 18-Sep-2020 14:57:53 GMT; path=/; secure; HttpOnly; SameSite=None', + 'fpc=ArAKYg2zrPpLjrqM5pf-AGlJ4DFtAQAAAL-HDdcOAAAA; expires=Wed, 04-Nov-2020 21:31:44 GMT; path=/; secure; HttpOnly; SameSite=None', 'Set-Cookie', 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', 'Set-Cookie', 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', 'Date', - 'Wed, 19 Aug 2020 14:57:53 GMT' + 'Mon, 05 Oct 2020 21:31:43 GMT', + 'Content-Length', + '1321' ]); nock('https://endpoint', {"encodedQueryParams":true}) .get('/$schemagroups/getSchemaById/ffffffffffffffffffffffffffffffff') .query(true) - .reply(404, "404Schema id ffffffffffffffffffffffffffffffff does not exist. TrackingId:bf402ba9-f61e-4782-8413-bedb1ae87af8_G4, SystemTracker:endpoint:$schemagroups/getSchemaById/ffffffffffffffffffffffffffffffff, Timestamp:2020-08-19T14:57:54", [ + .reply(404, {"Code":404,"Detail":"Schema id ffffffffffffffffffffffffffffffff does not exist. TrackingId:4c61053c-d700-4fa8-ad15-90ab640077f3_G2, SystemTracker:endpoint:$schemagroups/getSchemaById/ffffffffffffffffffffffffffffffff, Timestamp:2020-10-05T21:31:45"}, [ 'Transfer-Encoding', 'chunked', 'Content-Type', - 'application/xml; charset=utf-8', + 'application/json', 'Server', 'Microsoft-HTTPAPI/2.0', 'Strict-Transport-Security', 'max-age=31536000', 'Date', - 'Wed, 19 Aug 2020 14:57:54 GMT' + 'Mon, 05 Oct 2020 21:31:45 GMT' ]); diff --git a/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_gets_schema_by_id.js b/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_gets_schema_by_id.js index f78a9c9579ba..4de3b7a51923 100644 --- a/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_gets_schema_by_id.js +++ b/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_gets_schema_by_id.js @@ -1,5 +1,94 @@ let nock = require('nock'); -module.exports.hash = "0b238db6249c70c8bd21fadb680ac235"; +module.exports.hash = "791f4e42cb62fa1923842fe52c20c725"; module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/azure_tenant_id/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=azure_client_id&client_secret=azure_client_secret&scope=https%3A%2F%2Feventhubs.azure.net%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"access_token"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Length', + '1321', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '95c9acd1-9bd6-4477-8b3c-ff15e14b7600', + 'x-ms-ests-server', + '2.1.11086.7 - EUS ProdSlices', + 'Set-Cookie', + 'fpc=AivV5P9RxTFKuL-mUNh-Bf9J4DFtAQAAAMCHDdcOAAAA; expires=Wed, 04-Nov-2020 21:31:45 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Mon, 05 Oct 2020 21:31:45 GMT' +]); + +nock('https://endpoint', {"encodedQueryParams":true}) + .put('/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022', {"type":"record","name":"User","namespace":"com.azure.schemaregistry.samples","fields":[{"name":"name","type":"string"},{"name":"favoriteNumber","type":"int"}]}) + .query(true) + .reply(200, {"id":"228b2b0ea7f74b55a80f6651d6641b59"}, [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/json', + 'Location', + 'https://endpoint:443/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/43?api-version=2020-09-01-preview', + 'Server', + 'Microsoft-HTTPAPI/2.0', + 'Schema-Id', + '228b2b0ea7f74b55a80f6651d6641b59', + 'Schema-Id-Location', + 'https://endpoint:443/$schemagroups/getschemabyid/228b2b0ea7f74b55a80f6651d6641b59?api-version=2020-09-01-preview', + 'Serialization-Type', + 'Avro', + 'Schema-Version', + '43', + 'Schema-Versions-Location', + 'https://endpoint:443/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2020-09-01-preview', + 'Strict-Transport-Security', + 'max-age=31536000', + 'Date', + 'Mon, 05 Oct 2020 21:31:45 GMT' +]); + +nock('https://endpoint', {"encodedQueryParams":true}) + .get('/$schemagroups/getSchemaById/228b2b0ea7f74b55a80f6651d6641b59') + .query(true) + .reply(200, {"type":"record","name":"User","namespace":"com.azure.schemaregistry.samples","fields":[{"name":"name","type":"string"},{"name":"favoriteNumber","type":"int"}]}, [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/json', + 'Location', + 'https://endpoint:443/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/43?api-version=2020-09-01-preview', + 'Server', + 'Microsoft-HTTPAPI/2.0', + 'Schema-Id', + '228b2b0ea7f74b55a80f6651d6641b59', + 'Schema-Id-Location', + 'https://endpoint:443/$schemagroups/getschemabyid/228b2b0ea7f74b55a80f6651d6641b59?api-version=2020-09-01-preview', + 'Serialization-Type', + 'Avro', + 'Schema-Version', + '43', + 'Schema-Versions-Location', + 'https://endpoint:443/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2020-09-01-preview', + 'Strict-Transport-Security', + 'max-age=31536000', + 'Date', + 'Mon, 05 Oct 2020 21:31:45 GMT' +]); diff --git a/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_gets_schema_id.js b/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_gets_schema_id.js index 9dfebb5d463d..7f15a9824f6c 100644 --- a/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_gets_schema_id.js +++ b/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_gets_schema_id.js @@ -1,5 +1,94 @@ let nock = require('nock'); -module.exports.hash = "737b53ffa4e9d8162139fa46698faea8"; +module.exports.hash = "9dab19fa6a49e9a7ea507f0dce75f893"; module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/azure_tenant_id/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=azure_client_id&client_secret=azure_client_secret&scope=https%3A%2F%2Feventhubs.azure.net%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"access_token"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Length', + '1321', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + '95f98f4d-8e98-44fd-ace6-6e4f58f7df01', + 'x-ms-ests-server', + '2.1.11086.7 - WUS2 ProdSlices', + 'Set-Cookie', + 'fpc=AjH-GjA6hktBlu0c09W2vYtJ4DFtAQAAAL6HDdcOAAAA; expires=Wed, 04-Nov-2020 21:31:42 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Mon, 05 Oct 2020 21:31:42 GMT' +]); + +nock('https://endpoint', {"encodedQueryParams":true}) + .put('/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022', {"type":"record","name":"User","namespace":"com.azure.schemaregistry.samples","fields":[{"name":"name","type":"string"},{"name":"favoriteNumber","type":"int"}]}) + .query(true) + .reply(200, {"id":"228b2b0ea7f74b55a80f6651d6641b59"}, [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/json', + 'Location', + 'https://endpoint:443/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/43?api-version=2020-09-01-preview', + 'Server', + 'Microsoft-HTTPAPI/2.0', + 'Schema-Id', + '228b2b0ea7f74b55a80f6651d6641b59', + 'Schema-Id-Location', + 'https://endpoint:443/$schemagroups/getschemabyid/228b2b0ea7f74b55a80f6651d6641b59?api-version=2020-09-01-preview', + 'Serialization-Type', + 'Avro', + 'Schema-Version', + '43', + 'Schema-Versions-Location', + 'https://endpoint:443/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2020-09-01-preview', + 'Strict-Transport-Security', + 'max-age=31536000', + 'Date', + 'Mon, 05 Oct 2020 21:31:43 GMT' +]); + +nock('https://endpoint', {"encodedQueryParams":true}) + .post('/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022', {"type":"record","name":"User","namespace":"com.azure.schemaregistry.samples","fields":[{"name":"name","type":"string"},{"name":"favoriteNumber","type":"int"}]}) + .query(true) + .reply(200, {"id":"35c8c3d0438c48c09602b6b765c6d8dd"}, [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/json', + 'Location', + 'https://endpoint:443/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/3?api-version=2020-09-01-preview', + 'Server', + 'Microsoft-HTTPAPI/2.0', + 'Schema-Id', + '35c8c3d0438c48c09602b6b765c6d8dd', + 'Schema-Id-Location', + 'https://endpoint:443/$schemagroups/getschemabyid/35c8c3d0438c48c09602b6b765c6d8dd?api-version=2020-09-01-preview', + 'Serialization-Type', + 'Avro', + 'Schema-Version', + '3', + 'Schema-Versions-Location', + 'https://endpoint:443/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2020-09-01-preview', + 'Strict-Transport-Security', + 'max-age=31536000', + 'Date', + 'Mon, 05 Oct 2020 21:31:43 GMT' +]); diff --git a/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_registers_schema.js b/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_registers_schema.js index ee3141241a5b..e168745ee289 100644 --- a/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_registers_schema.js +++ b/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_registers_schema.js @@ -1,5 +1,94 @@ let nock = require('nock'); -module.exports.hash = "07a39ece43bc33a97ba6ec7b0e4ced84"; +module.exports.hash = "7a3ba87cdf7a98b968983064f67f0184"; module.exports.testInfo = {"uniqueName":{},"newDate":{}} + +nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) + .post('/azure_tenant_id/oauth2/v2.0/token', "response_type=token&grant_type=client_credentials&client_id=azure_client_id&client_secret=azure_client_secret&scope=https%3A%2F%2Feventhubs.azure.net%2F.default") + .reply(200, {"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"access_token"}, [ + 'Cache-Control', + 'no-store, no-cache', + 'Pragma', + 'no-cache', + 'Content-Type', + 'application/json; charset=utf-8', + 'Expires', + '-1', + 'Strict-Transport-Security', + 'max-age=31536000; includeSubDomains', + 'X-Content-Type-Options', + 'nosniff', + 'P3P', + 'CP="DSP CUR OTPi IND OTRi ONL FIN"', + 'x-ms-request-id', + 'f49473b9-aa98-4eff-b5d2-9c1afe0c2401', + 'x-ms-ests-server', + '2.1.11086.7 - NCUS ProdSlices', + 'Set-Cookie', + 'fpc=AjXVec4rndNBop5Yt58N_2pJ4DFtAQAAALqHDdcOAAAA; expires=Wed, 04-Nov-2020 21:31:39 GMT; path=/; secure; HttpOnly; SameSite=None', + 'Set-Cookie', + 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', + 'Set-Cookie', + 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', + 'Date', + 'Mon, 05 Oct 2020 21:31:38 GMT', + 'Content-Length', + '1321' +]); + +nock('https://endpoint', {"encodedQueryParams":true}) + .put('/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022', {"type":"record","name":"User","namespace":"com.azure.schemaregistry.samples","fields":[{"name":"name","type":"string"},{"name":"favoriteNumber","type":"int"}]}) + .query(true) + .reply(200, {"id":"ac88cdfed763412f805999ae0e04ca72"}, [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/json', + 'Location', + 'https://endpoint:443/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/41?api-version=2020-09-01-preview', + 'Server', + 'Microsoft-HTTPAPI/2.0', + 'Schema-Id', + 'ac88cdfed763412f805999ae0e04ca72', + 'Schema-Id-Location', + 'https://endpoint:443/$schemagroups/getschemabyid/ac88cdfed763412f805999ae0e04ca72?api-version=2020-09-01-preview', + 'Serialization-Type', + 'Avro', + 'Schema-Version', + '41', + 'Schema-Versions-Location', + 'https://endpoint:443/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2020-09-01-preview', + 'Strict-Transport-Security', + 'max-age=31536000', + 'Date', + 'Mon, 05 Oct 2020 21:31:40 GMT' +]); + +nock('https://endpoint', {"encodedQueryParams":true}) + .put('/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022', {"type":"record","name":"User","namespace":"com.azure.schemaregistry.samples","fields":[{"name":"name","type":"string"},{"name":"secondFavoriteNumber","type":"int"}]}) + .query(true) + .reply(200, {"id":"c117273dd2e3403aa5176317936fe205"}, [ + 'Transfer-Encoding', + 'chunked', + 'Content-Type', + 'application/json', + 'Location', + 'https://endpoint:443/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions/42?api-version=2020-09-01-preview', + 'Server', + 'Microsoft-HTTPAPI/2.0', + 'Schema-Id', + 'c117273dd2e3403aa5176317936fe205', + 'Schema-Id-Location', + 'https://endpoint:443/$schemagroups/getschemabyid/c117273dd2e3403aa5176317936fe205?api-version=2020-09-01-preview', + 'Serialization-Type', + 'Avro', + 'Schema-Version', + '42', + 'Schema-Versions-Location', + 'https://endpoint:443/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022/versions?api-version=2020-09-01-preview', + 'Strict-Transport-Security', + 'max-age=31536000', + 'Date', + 'Mon, 05 Oct 2020 21:31:40 GMT' +]); diff --git a/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_rejects_schema_registration_with_invalid_args.js b/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_rejects_schema_registration_with_invalid_args.js index 2e9ff5151904..181f9d9f0a73 100644 --- a/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_rejects_schema_registration_with_invalid_args.js +++ b/sdk/schemaregistry/schema-registry/recordings/node/schemaregistryclient/recording_rejects_schema_registration_with_invalid_args.js @@ -1,6 +1,6 @@ let nock = require('nock'); -module.exports.hash = "febe9d20712277d8563fe7b198a96fb2"; +module.exports.hash = "ac40b383b445f28c364f65a46fa4079c"; module.exports.testInfo = {"uniqueName":{},"newDate":{}} @@ -11,6 +11,8 @@ nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) 'no-store, no-cache', 'Pragma', 'no-cache', + 'Content-Length', + '1321', 'Content-Type', 'application/json; charset=utf-8', 'Expires', @@ -22,33 +24,31 @@ nock('https://login.microsoftonline.com:443', {"encodedQueryParams":true}) 'P3P', 'CP="DSP CUR OTPi IND OTRi ONL FIN"', 'x-ms-request-id', - '369da187-f3b0-486b-84b9-d03c02882500', + 'b391363f-9941-40ef-8cc4-558e83811f01', 'x-ms-ests-server', - '2.1.10963.12 - WUS2 ProdSlices', + '2.1.11086.7 - NCUS ProdSlices', 'Set-Cookie', - 'fpc=ArOyg5x-Fu5Ls6uDcnLMq0tJ4DFtAQAAAO40z9YOAAAA; expires=Fri, 18-Sep-2020 14:57:50 GMT; path=/; secure; HttpOnly; SameSite=None', + 'fpc=Asnx_FjEpm5ClYIyr1GdvTFJ4DFtAQAAALiHDdcOAAAA; expires=Wed, 04-Nov-2020 21:31:37 GMT; path=/; secure; HttpOnly; SameSite=None', 'Set-Cookie', 'x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly', 'Set-Cookie', 'stsservicecookie=estsfd; path=/; secure; samesite=none; httponly', 'Date', - 'Wed, 19 Aug 2020 14:57:50 GMT', - 'Content-Length', - '1321' + 'Mon, 05 Oct 2020 21:31:37 GMT' ]); nock('https://endpoint', {"encodedQueryParams":true}) - .put('/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022', "{\"type\":\"record\",\"name\":\"User\",\"namespace\":\"com.azure.schemaregistry.samples\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"favoriteNumber\",\"type\":\"int\"}]}") + .put('/$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022', {"type":"record","name":"User","namespace":"com.azure.schemaregistry.samples","fields":[{"name":"name","type":"string"},{"name":"favoriteNumber","type":"int"}]}) .query(true) - .reply(400, "400Invalid schema type for POST request. 'not-valid' is not supported. TrackingId:01992703-c047-43ec-ba3f-1374d1ba197f_G4, SystemTracker:endpoint:$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022, Timestamp:2020-08-19T14:57:51", [ + .reply(400, {"Code":400,"Detail":"Invalid schema type for PUT request. 'not-valid' is not supported. TrackingId:0b46c6c6-1703-496b-a401-d04fe16404d5_G4, SystemTracker:endpoint:$schemagroups/azsdk_js_test_group/schemas/azsdk_js_test_000022, Timestamp:2020-10-05T21:31:39"}, [ 'Transfer-Encoding', 'chunked', 'Content-Type', - 'application/xml; charset=utf-8', + 'application/json', 'Server', 'Microsoft-HTTPAPI/2.0', 'Strict-Transport-Security', 'max-age=31536000', 'Date', - 'Wed, 19 Aug 2020 14:57:51 GMT' + 'Mon, 05 Oct 2020 21:31:39 GMT' ]); diff --git a/sdk/schemaregistry/schema-registry/src/conversions.ts b/sdk/schemaregistry/schema-registry/src/conversions.ts index 60fbb2162c77..35c60a46741b 100644 --- a/sdk/schemaregistry/schema-registry/src/conversions.ts +++ b/sdk/schemaregistry/schema-registry/src/conversions.ts @@ -30,7 +30,10 @@ type GeneratedResponse = GeneratedSchemaResponse | GeneratedSchemaIdResponse; * @internal */ export function convertSchemaResponse(response: GeneratedSchemaResponse): Schema { - return convertResponse(response, { content: response.body }); + // https://github.com/Azure/azure-sdk-for-js/issues/11649 + // Although response.body is typed as string, it is a parsed JSON object, + // so we use _response.bodyAsText instead as a workaround. + return convertResponse(response, { content: response._response.bodyAsText }); } /** @@ -49,10 +52,10 @@ function convertResponse(response: GeneratedResponse, additionalProperties: T // `!`s here because server is required to return these on success, but that // is not modeled by the generated client. location: response.location!, - locationById: response.xSchemaIdLocation!, - id: response.xSchemaId!, - version: response.xSchemaVersion!, - serializationType: response.xSchemaType!, + locationById: response.schemaIdLocation!, + id: response.schemaId!, + version: response.schemaVersion!, + serializationType: response.serializationType!, ...additionalProperties }; diff --git a/sdk/schemaregistry/schema-registry/src/generated/generatedSchemaRegistryClient.ts b/sdk/schemaregistry/schema-registry/src/generated/generatedSchemaRegistryClient.ts index 6d644bbed693..40b24b350fd4 100644 --- a/sdk/schemaregistry/schema-registry/src/generated/generatedSchemaRegistryClient.ts +++ b/sdk/schemaregistry/schema-registry/src/generated/generatedSchemaRegistryClient.ts @@ -6,13 +6,11 @@ * Changes may cause incorrect behavior and will be lost if the code is regenerated. */ -import * as operations from "./operations"; -import * as Models from "./models"; -import * as Mappers from "./models/mappers"; +import { Schema } from "./operations"; import { GeneratedSchemaRegistryClientContext } from "./generatedSchemaRegistryClientContext"; import { GeneratedSchemaRegistryClientOptionalParams } from "./models"; -class GeneratedSchemaRegistryClient extends GeneratedSchemaRegistryClientContext { +export class GeneratedSchemaRegistryClient extends GeneratedSchemaRegistryClientContext { /** * Initializes a new instance of the GeneratedSchemaRegistryClient class. * @param endpoint The Schema Registry service endpoint, for example @@ -24,18 +22,8 @@ class GeneratedSchemaRegistryClient extends GeneratedSchemaRegistryClientContext options?: GeneratedSchemaRegistryClientOptionalParams ) { super(endpoint, options); - this.schema = new operations.Schema(this); + this.schema = new Schema(this); } - schema: operations.Schema; + schema: Schema; } - -// Operation Specifications - -export { - GeneratedSchemaRegistryClient, - GeneratedSchemaRegistryClientContext, - Models as GeneratedSchemaRegistryModels, - Mappers as GeneratedSchemaRegistryMappers -}; -export * from "./operations"; diff --git a/sdk/schemaregistry/schema-registry/src/generated/generatedSchemaRegistryClientContext.ts b/sdk/schemaregistry/schema-registry/src/generated/generatedSchemaRegistryClientContext.ts index 847088ada49f..2bce0ee75d58 100644 --- a/sdk/schemaregistry/schema-registry/src/generated/generatedSchemaRegistryClientContext.ts +++ b/sdk/schemaregistry/schema-registry/src/generated/generatedSchemaRegistryClientContext.ts @@ -50,6 +50,6 @@ export class GeneratedSchemaRegistryClientContext extends coreHttp.ServiceClient this.endpoint = endpoint; // Assigning values to Constant parameters - this.apiVersion = options.apiVersion || "2018-01-01-preview"; + this.apiVersion = options.apiVersion || "2020-09-01-preview"; } } diff --git a/sdk/schemaregistry/schema-registry/src/generated/index.ts b/sdk/schemaregistry/schema-registry/src/generated/index.ts new file mode 100644 index 000000000000..f2753af619ad --- /dev/null +++ b/sdk/schemaregistry/schema-registry/src/generated/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is regenerated. + */ + +export * from "./models"; +export { GeneratedSchemaRegistryClient } from "./generatedSchemaRegistryClient"; +export { GeneratedSchemaRegistryClientContext } from "./generatedSchemaRegistryClientContext"; diff --git a/sdk/schemaregistry/schema-registry/src/generated/models/index.ts b/sdk/schemaregistry/schema-registry/src/generated/models/index.ts index 9131de63911a..76c9ef7ad524 100644 --- a/sdk/schemaregistry/schema-registry/src/generated/models/index.ts +++ b/sdk/schemaregistry/schema-registry/src/generated/models/index.ts @@ -29,19 +29,19 @@ export interface SchemaGetByIdHeaders { /** * Serialization type for the schema being stored. */ - xSchemaType?: string; + serializationType?: string; /** * References specific schema in registry namespace. */ - xSchemaId?: string; + schemaId?: string; /** * URL location of schema, identified by schema ID. */ - xSchemaIdLocation?: string; + schemaIdLocation?: string; /** * Version of the returned schema. */ - xSchemaVersion?: number; + schemaVersion?: number; } /** @@ -55,19 +55,19 @@ export interface SchemaQueryIdByContentHeaders { /** * Serialization type for the schema being stored. */ - xSchemaType?: string; + serializationType?: string; /** * References specific schema in registry namespace. */ - xSchemaId?: string; + schemaId?: string; /** * URL location of schema, identified by schema ID. */ - xSchemaIdLocation?: string; + schemaIdLocation?: string; /** * Version of the returned schema. */ - xSchemaVersion?: number; + schemaVersion?: number; } /** @@ -81,25 +81,25 @@ export interface SchemaRegisterHeaders { /** * Serialization type for the schema being registered. */ - xSchemaType?: string; + serializationType?: string; /** * References specific schema in registry namespace. */ - xSchemaId?: string; + schemaId?: string; /** * URL location of schema, identified by schema ID. */ - xSchemaIdLocation?: string; + schemaIdLocation?: string; /** * Version of the returned schema. */ - xSchemaVersion?: number; + schemaVersion?: number; } /** * Defines values for SerializationType. */ -export type SerializationType = "avro"; +export type SerializationType = "avro" | string; /** * Contains response data for the getById operation. diff --git a/sdk/schemaregistry/schema-registry/src/generated/models/mappers.ts b/sdk/schemaregistry/schema-registry/src/generated/models/mappers.ts index b04f86c49da0..a5f9d87c09b1 100644 --- a/sdk/schemaregistry/schema-registry/src/generated/models/mappers.ts +++ b/sdk/schemaregistry/schema-registry/src/generated/models/mappers.ts @@ -34,26 +34,26 @@ export const SchemaGetByIdHeaders: coreHttp.CompositeMapper = { name: "String" } }, - xSchemaType: { - serializedName: "x-schema-type", + serializationType: { + serializedName: "serialization-type", type: { name: "String" } }, - xSchemaId: { - serializedName: "x-schema-id", + schemaId: { + serializedName: "schema-id", type: { name: "String" } }, - xSchemaIdLocation: { - serializedName: "x-schema-id-location", + schemaIdLocation: { + serializedName: "schema-id-location", type: { name: "String" } }, - xSchemaVersion: { - serializedName: "x-schema-version", + schemaVersion: { + serializedName: "schema-version", type: { name: "Number" } @@ -73,26 +73,26 @@ export const SchemaQueryIdByContentHeaders: coreHttp.CompositeMapper = { name: "String" } }, - xSchemaType: { - serializedName: "x-schema-type", + serializationType: { + serializedName: "serialization-type", type: { name: "String" } }, - xSchemaId: { - serializedName: "x-schema-id", + schemaId: { + serializedName: "schema-id", type: { name: "String" } }, - xSchemaIdLocation: { - serializedName: "x-schema-id-location", + schemaIdLocation: { + serializedName: "schema-id-location", type: { name: "String" } }, - xSchemaVersion: { - serializedName: "x-schema-version", + schemaVersion: { + serializedName: "schema-version", type: { name: "Number" } @@ -112,26 +112,26 @@ export const SchemaRegisterHeaders: coreHttp.CompositeMapper = { name: "String" } }, - xSchemaType: { - serializedName: "x-schema-type", + serializationType: { + serializedName: "serialization-type", type: { name: "String" } }, - xSchemaId: { - serializedName: "x-schema-id", + schemaId: { + serializedName: "schema-id", type: { name: "String" } }, - xSchemaIdLocation: { - serializedName: "x-schema-id-location", + schemaIdLocation: { + serializedName: "schema-id-location", type: { name: "String" } }, - xSchemaVersion: { - serializedName: "x-schema-version", + schemaVersion: { + serializedName: "schema-version", type: { name: "Number" } diff --git a/sdk/schemaregistry/schema-registry/src/generated/models/parameters.ts b/sdk/schemaregistry/schema-registry/src/generated/models/parameters.ts index 9a4d4274022a..93345b330c64 100644 --- a/sdk/schemaregistry/schema-registry/src/generated/models/parameters.ts +++ b/sdk/schemaregistry/schema-registry/src/generated/models/parameters.ts @@ -7,11 +7,23 @@ */ import { + OperationParameter, OperationURLParameter, - OperationQueryParameter, - OperationParameter + OperationQueryParameter } from "@azure/core-http"; +export const accept: OperationParameter = { + parameterPath: "accept", + mapper: { + defaultValue: "text/plain; charset=utf-8", + isConstant: true, + serializedName: "Accept", + type: { + name: "String" + } + } +}; + export const endpoint: OperationURLParameter = { parameterPath: "endpoint", mapper: { @@ -38,9 +50,7 @@ export const schemaId: OperationURLParameter = { export const apiVersion: OperationQueryParameter = { parameterPath: "apiVersion", mapper: { - // TODO: Manually patched for now due to https://github.com/Azure/azure-rest-api-specs/pull/10220#discussion_r469588293 - // defaultValue: "2018-01-01-preview", - defaultValue: "2017-04", + defaultValue: "2020-09-01-preview", isConstant: true, serializedName: "api-version", type: { @@ -52,7 +62,7 @@ export const apiVersion: OperationQueryParameter = { export const contentType: OperationParameter = { parameterPath: ["options", "contentType"], mapper: { - defaultValue: "application/json", + defaultValue: "text/plain; charset=utf-8", isConstant: true, serializedName: "Content-Type", type: { @@ -72,6 +82,18 @@ export const schemaContent: OperationParameter = { } }; +export const accept1: OperationParameter = { + parameterPath: "accept", + mapper: { + defaultValue: "application/json", + isConstant: true, + serializedName: "Accept", + type: { + name: "String" + } + } +}; + export const groupName: OperationURLParameter = { parameterPath: "groupName", mapper: { @@ -94,10 +116,10 @@ export const schemaName: OperationURLParameter = { } }; -export const xSchemaType: OperationParameter = { - parameterPath: "xSchemaType", +export const serializationType: OperationParameter = { + parameterPath: "serializationType", mapper: { - serializedName: "X-Schema-Type", + serializedName: "Serialization-Type", required: true, type: { name: "String" diff --git a/sdk/schemaregistry/schema-registry/src/generated/operations/schema.ts b/sdk/schemaregistry/schema-registry/src/generated/operations/schema.ts index db0d51fe4aa7..9df38c2488d0 100644 --- a/sdk/schemaregistry/schema-registry/src/generated/operations/schema.ts +++ b/sdk/schemaregistry/schema-registry/src/generated/operations/schema.ts @@ -56,14 +56,14 @@ export class Schema { * @param groupName Schema group under which schema is registered. Group's serialization type should * match the serialization type specified in the request. * @param schemaName Name of the registered schema. - * @param xSchemaType Serialization type for the schema being registered. - * @param schemaContent String representation of the registered schema. + * @param serializationType Serialization type for the schema being registered. + * @param schemaContent String representation (UTF-8) of the registered schema. * @param options The options parameters. */ queryIdByContent( groupName: string, schemaName: string, - xSchemaType: SerializationType, + serializationType: SerializationType, schemaContent: string, options?: coreHttp.OperationOptions ): Promise { @@ -74,7 +74,7 @@ export class Schema { { groupName, schemaName, - xSchemaType, + serializationType, schemaContent, options: operationOptions }, @@ -90,14 +90,14 @@ export class Schema { * @param groupName Schema group under which schema should be registered. Group's serialization type * should match the serialization type specified in the request. * @param schemaName Name of schema being registered. - * @param xSchemaType Serialization type for the schema being registered. - * @param schemaContent String representation of the schema being registered. + * @param serializationType Serialization type for the schema being registered. + * @param schemaContent String representation (UTF-8) of the schema being registered. * @param options The options parameters. */ register( groupName: string, schemaName: string, - xSchemaType: SerializationType, + serializationType: SerializationType, schemaContent: string, options?: coreHttp.OperationOptions ): Promise { @@ -108,7 +108,7 @@ export class Schema { { groupName, schemaName, - xSchemaType, + serializationType, schemaContent, options: operationOptions }, @@ -134,6 +134,7 @@ const getByIdOperationSpec: coreHttp.OperationSpec = { }, queryParameters: [Parameters.apiVersion], urlParameters: [Parameters.endpoint, Parameters.schemaId], + headerParameters: [Parameters.accept], serializer }; const queryIdByContentOperationSpec: coreHttp.OperationSpec = { @@ -155,8 +156,12 @@ const queryIdByContentOperationSpec: coreHttp.OperationSpec = { Parameters.groupName, Parameters.schemaName ], - headerParameters: [Parameters.contentType, Parameters.xSchemaType], - mediaType: "json", + headerParameters: [ + Parameters.contentType, + Parameters.accept1, + Parameters.serializationType + ], + mediaType: "text", serializer }; const registerOperationSpec: coreHttp.OperationSpec = { @@ -178,7 +183,11 @@ const registerOperationSpec: coreHttp.OperationSpec = { Parameters.groupName, Parameters.schemaName ], - headerParameters: [Parameters.contentType, Parameters.xSchemaType], - mediaType: "json", + headerParameters: [ + Parameters.contentType, + Parameters.accept1, + Parameters.serializationType + ], + mediaType: "text", serializer }; diff --git a/sdk/schemaregistry/schema-registry/src/schemaRegistryClient.ts b/sdk/schemaregistry/schema-registry/src/schemaRegistryClient.ts index 22c2ffa83aad..cb4733cb93b9 100644 --- a/sdk/schemaregistry/schema-registry/src/schemaRegistryClient.ts +++ b/sdk/schemaregistry/schema-registry/src/schemaRegistryClient.ts @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { SerializationType } from "./generated/models"; import { GeneratedSchemaRegistryClient } from "./generated/generatedSchemaRegistryClient"; import { TokenCredential } from "@azure/core-http"; import { createPipeline } from "./pipeline"; @@ -63,10 +62,7 @@ export class SchemaRegistryClient implements SchemaRegistry { const response = await this.client.schema.register( schema.group, schema.name, - // cast due to https://github.com/Azure/autorest.typescript/issues/715 - // serialization type is an extensible enum, and therefore any string - // should be allowed. - schema.serializationType as SerializationType, + schema.serializationType, schema.content, options ); @@ -84,10 +80,7 @@ export class SchemaRegistryClient implements SchemaRegistry { const response = await this.client.schema.queryIdByContent( schema.group, schema.name, - // cast due to https://github.com/Azure/autorest.typescript/issues/715 - // serialization type is an extensible enum, and therefore any string - // should be allowed. - schema.serializationType as SerializationType, + schema.serializationType, schema.content, options ); diff --git a/sdk/schemaregistry/schema-registry/swagger/README.md b/sdk/schemaregistry/schema-registry/swagger/README.md index 347996eb5a61..807012da573a 100644 --- a/sdk/schemaregistry/schema-registry/swagger/README.md +++ b/sdk/schemaregistry/schema-registry/swagger/README.md @@ -18,7 +18,16 @@ add-credentials: false license-header: MICROSOFT_MIT_NO_VERSION output-folder: ../ source-code-folder-path: ./src/generated -input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/a90b9146e543d3eec11381bd52d3b6ff271b1b78/specification/schemaregistry/data-plane/Microsoft.EventHub/preview/2018-01-01-preview/schemaregistry.json +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/1e23d91e875e4464e57667639e06408cef99868d/specification/schemaregistry/data-plane/Microsoft.EventHub/preview/2020-09-01-preview/schemaregistry.json use-extension: - "@autorest/typescript": "6.0.0-dev.20200715.2" + "@autorest/typescript": "6.0.0-dev.20200918.1" + "@autorest/modelerfour": "4.15.421" +``` + +```yaml +directive: + from: swagger-document + where: $.paths..["Serialization-Type"] + transform: $.enum = undefined; $["x-ms-enum"] = undefined; return $; + reason: https://github.com/Azure/autorest.typescript/issues/736 ``` diff --git a/sdk/schemaregistry/schema-registry/test/schemaRegistry.spec.ts b/sdk/schemaregistry/schema-registry/test/schemaRegistry.spec.ts index 19ed8e5ede58..dc6dc1b52cdb 100644 --- a/sdk/schemaregistry/schema-registry/test/schemaRegistry.spec.ts +++ b/sdk/schemaregistry/schema-registry/test/schemaRegistry.spec.ts @@ -91,8 +91,6 @@ describe("SchemaRegistryClient", function() { }); it("rejects schema registration with invalid args", async () => { - recorder.skip("node", "https://github.com/Azure/azure-sdk-for-js/issues/10659"); - await assert.isRejected(client.registerSchema({ ...schema, name: null! }), /null/); await assert.isRejected(client.registerSchema({ ...schema, group: null! }), /null/); await assert.isRejected(client.registerSchema({ ...schema, content: null! }), /null/); @@ -104,8 +102,6 @@ describe("SchemaRegistryClient", function() { }); it("registers schema", async () => { - recorder.skip("node", "https://github.com/Azure/azure-sdk-for-js/issues/10659"); - const registered = await client.registerSchema(schema); assertStatus(registered, 200); assertIsValidSchemaId(registered); @@ -113,15 +109,13 @@ describe("SchemaRegistryClient", function() { // changing schema content bumps version, generates new id/locations const changed = await client.registerSchema({ ...schema, - content: schema.content.replace("name", "fullName") + content: schema.content.replace("favoriteNumber", "secondFavoriteNumber") }); assertStatus(changed, 200); assertIsValidSchemaId(changed); }); it("fails to get schema ID when given invalid args", async () => { - recorder.skip("node", "https://github.com/Azure/azure-sdk-for-js/issues/10659"); - await assert.isRejected(client.getSchemaId({ ...schema, name: null! }), /null/); await assert.isRejected(client.getSchemaId({ ...schema, group: null! }), /null/); await assert.isRejected(client.getSchemaId({ ...schema, content: null! }), /null/); @@ -133,7 +127,6 @@ describe("SchemaRegistryClient", function() { }); it("fails to get schema ID when no matching schema exists", async () => { - recorder.skip("node", "https://github.com/Azure/azure-sdk-for-js/issues/10659"); await assert.isRejected( client.getSchemaId({ ...schema, name: "never-registered" }), /never-registered/ @@ -141,8 +134,6 @@ describe("SchemaRegistryClient", function() { }); it("gets schema ID", async () => { - recorder.skip("node", "https://github.com/Azure/azure-sdk-for-js/issues/10659"); - const registered = await client.registerSchema(schema); assertStatus(registered, 200); assertIsValidSchemaId(registered); @@ -159,8 +150,6 @@ describe("SchemaRegistryClient", function() { }); it("fails to get schema when no schema exists with given ID", async () => { - recorder.skip("node", "https://github.com/Azure/azure-sdk-for-js/issues/10659"); - await assert.isRejected( client.getSchemaById("ffffffffffffffffffffffffffffffff"), /ffffffffffffffffffffffffffffffff/ @@ -168,8 +157,6 @@ describe("SchemaRegistryClient", function() { }); it("gets schema by ID", async () => { - recorder.skip("node", "https://github.com/Azure/azure-sdk-for-js/issues/10659"); - const registered = await client.registerSchema(schema); assertStatus(registered, 200); assertIsValidSchemaId(registered); @@ -177,7 +164,6 @@ describe("SchemaRegistryClient", function() { const found = await client.getSchemaById(registered.id); assertStatus(found, 200); assertIsValidSchemaId(found); - assert.equal(found.content, schema.content); }); }); diff --git a/sdk/servicebus/service-bus/CHANGELOG.md b/sdk/servicebus/service-bus/CHANGELOG.md index e27875e8a0b9..60499501d1fc 100644 --- a/sdk/servicebus/service-bus/CHANGELOG.md +++ b/sdk/servicebus/service-bus/CHANGELOG.md @@ -1,16 +1,20 @@ # Release History -## 7.0.0-preview.7 (Unreleased) +## 7.0.0-preview.7 (2020-10-07) ### New features: -- Options to create/update a queue, topic and subscription now support `availabilityStatus` property. `availabilityStatus` indicates the status of entity availability. Possible values are: Available, Limited, Renaming, Restoring and Unknown. - [PR 11152](https://github.com/Azure/azure-sdk-for-js/pull/11152) +- Message locks can be auto-renewed in all receive methods (receiver.receiveMessages, receiver.subcribe + and receiver.getMessageIterator). This can be configured in options when calling `ServiceBusClient.createReceiver()`. + [PR 11658](https://github.com/Azure/azure-sdk-for-js/pull/11658) - `ServiceBusClient` now supports authentication with AAD credentials in the browser(can use `InteractiveBrowserCredential` from `@azure/identity`). [PR 11250](https://github.com/Azure/azure-sdk-for-js/pull/11250) +- Options to create/update a queue, topic and subscription now support `availabilityStatus` property. `availabilityStatus` indicates the status of entity availability. Possible values are: Available, Limited, Renaming, Restoring and Unknown. + [PR 11152](https://github.com/Azure/azure-sdk-for-js/pull/11152) - "properties" in the correlation rule filter now supports `Date`. [PR 11117](https://github.com/Azure/azure-sdk-for-js/pull/11117) + ### Breaking changes - `ServiceBusClient.createSessionReceiver` has been split into two methods: diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index a6f81b117f98..651db13a0042 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -126,6 +126,7 @@ export interface CreateQueueOptions extends OperationOptions { // @public export interface CreateReceiverOptions { + maxAutoLockRenewalDurationInMs?: number; receiveMode?: ReceiveModeT; subQueue?: SubQueue; } @@ -190,7 +191,6 @@ export interface GetMessageIteratorOptions extends OperationOptionsBase { // @public export interface MessageHandlerOptions extends MessageHandlerOptionsBase { - maxAutoRenewLockDurationInMs?: number; } // @public diff --git a/sdk/servicebus/service-bus/src/core/autoLockRenewer.ts b/sdk/servicebus/service-bus/src/core/autoLockRenewer.ts index 989a4c4d4ec6..89ed7e30f985 100644 --- a/sdk/servicebus/service-bus/src/core/autoLockRenewer.ts +++ b/sdk/servicebus/service-bus/src/core/autoLockRenewer.ts @@ -3,11 +3,11 @@ import { ConnectionContext } from "../connectionContext"; import { logger } from "../log"; -import { InternalReceiveMode, ServiceBusMessageImpl } from "../serviceBusMessage"; +import { ServiceBusMessageImpl } from "../serviceBusMessage"; import { logError } from "../util/errors"; import { calculateRenewAfterDuration } from "../util/utils"; import { LinkEntity } from "./linkEntity"; -import { OnError, ReceiveOptions } from "./messageReceiver"; +import { OnError } from "./messageReceiver"; /** * @internal @@ -19,27 +19,28 @@ export type RenewableMessageProperties = Readonly< // updated when we renew the lock Pick; +type MinimalLink = Pick, "name" | "logPrefix" | "entityPath">; + /** * Tracks locks for messages, renewing until a configurable duration. * * @internal * @ignore */ -export class AutoLockRenewer { +export class LockRenewer { /** - * @property {Map} _messageRenewLockTimers Maintains a map of messages for which - * the lock is automatically renewed. + * @property _messageRenewLockTimers A map of link names to individual maps for each + * link that map a message ID to its auto-renewal timer. */ - private _messageRenewLockTimers: Map = new Map< + private _messageRenewLockTimers: Map> = new Map< string, - NodeJS.Timer | undefined + Map >(); // just here for make unit testing a bit easier. private _calculateRenewAfterDuration: typeof calculateRenewAfterDuration; constructor( - private _linkEntity: Pick, "name" | "logPrefix" | "entityPath">, private _context: Pick, private _maxAutoRenewDurationInMs: number ) { @@ -53,40 +54,43 @@ export class AutoLockRenewer { * @param context The connection context for your link entity (probably 'this._context') * @param options The ReceiveOptions passed through to your message receiver. * @returns if the lock mode is peek lock (or if is unspecified, thus defaulting to peekLock) - * and the options.maxAutoRenewLockDurationInMs is > 0..Otherwise, returns undefined. + * and the options.maxAutoLockRenewalDurationInMs is > 0..Otherwise, returns undefined. */ static create( - linkEntity: Pick, "name" | "logPrefix" | "entityPath">, context: Pick, - options?: Pick + maxAutoRenewLockDurationInMs: number, + receiveMode: "peekLock" | "receiveAndDelete" ) { - if (options?.receiveMode === InternalReceiveMode.receiveAndDelete) { + if (receiveMode !== "peekLock") { return undefined; } - const maxAutoRenewDurationInMs = - options?.maxAutoRenewLockDurationInMs != null - ? options.maxAutoRenewLockDurationInMs - : 300 * 1000; - - if (maxAutoRenewDurationInMs <= 0) { + if (maxAutoRenewLockDurationInMs <= 0) { return undefined; } - return new AutoLockRenewer(linkEntity, context, maxAutoRenewDurationInMs); + return new LockRenewer(context, maxAutoRenewLockDurationInMs); } /** - * Cancels all pending lock renewals and removes all entries from our internal cache. + * Cancels all pending lock renewals for messages on given link and removes all entries from our internal cache. */ - stopAll() { + stopAll(linkEntity: MinimalLink) { logger.verbose( - `${this._linkEntity.logPrefix} Clearing message renew lock timers for all the active messages.` + `${linkEntity.logPrefix} Clearing message renew lock timers for all the active messages.` ); - for (const messageId of this._messageRenewLockTimers.keys()) { - this._stopAndRemoveById(messageId); + const messagesForLink = this._messageRenewLockTimers.get(linkEntity.name); + + if (messagesForLink == null) { + return; } + + for (const messageId of messagesForLink.keys()) { + this._stopAndRemoveById(linkEntity, messagesForLink, messageId); + } + + this._messageRenewLockTimers.delete(linkEntity.name); } /** @@ -94,9 +98,16 @@ export class AutoLockRenewer { * * @param bMessage The message whose lock renewal we will stop. */ - stop(bMessage: RenewableMessageProperties) { + stop(linkEntity: MinimalLink, bMessage: RenewableMessageProperties) { const messageId = bMessage.messageId as string; - this._stopAndRemoveById(messageId); + + const messagesForLink = this._messageRenewLockTimers.get(linkEntity.name); + + if (messagesForLink == null) { + return; + } + + this._stopAndRemoveById(linkEntity, messagesForLink, messageId); } /** @@ -104,9 +115,9 @@ export class AutoLockRenewer { * * @param bMessage The message whose lock renewal we will start. */ - start(bMessage: RenewableMessageProperties, onError: OnError) { + start(linkEntity: MinimalLink, bMessage: RenewableMessageProperties, onError: OnError) { try { - const logPrefix = this._linkEntity.logPrefix; + const logPrefix = linkEntity.logPrefix; if (bMessage.lockToken == null) { throw new Error( @@ -115,15 +126,17 @@ export class AutoLockRenewer { } const lockToken = bMessage.lockToken; + const linkMessageMap = this._getOrCreateMapForLink(linkEntity); // - We need to renew locks before they expire by looking at bMessage.lockedUntilUtc. // - This autorenewal needs to happen **NO MORE** than maxAutoRenewDurationInMs // - We should be able to clear the renewal timer when the user's message handler // is done (whether it succeeds or fails). - // Setting the messageId with undefined value in the _messageRenewockTimers Map because we + // Setting the messageId with undefined value in the linkMessageMap because we // track state by checking the presence of messageId in the map. It is removed from the map // when an attempt is made to settle the message (either by the user or by the sdk) OR // when the execution of user's message handler completes. - this._messageRenewLockTimers.set(bMessage.messageId as string, undefined); + linkMessageMap.set(bMessage.messageId as string, undefined); + logger.verbose( `${logPrefix} message with id '${ bMessage.messageId @@ -135,6 +148,7 @@ export class AutoLockRenewer { bMessage.messageId }' is: ${new Date(totalAutoLockRenewDuration).toString()}` ); + const autoRenewLockTask = (): void => { const renewalNeededToMaintainLock = // if the lock expires _after_ our max auto-renew duration there's no reason to @@ -145,7 +159,7 @@ export class AutoLockRenewer { const haventExceededMaxLockRenewalTime = Date.now() < totalAutoLockRenewDuration; if (renewalNeededToMaintainLock && haventExceededMaxLockRenewalTime) { - if (this._messageRenewLockTimers.has(bMessage.messageId as string)) { + if (linkMessageMap.has(bMessage.messageId as string)) { // TODO: We can run into problems with clock skew between the client and the server. // It would be better to calculate the duration based on the "lockDuration" property // of the queue. However, we do not have the management plane of the client ready for @@ -153,38 +167,42 @@ export class AutoLockRenewer { const amount = this._calculateRenewAfterDuration(bMessage.lockedUntilUtc!); logger.verbose( - `${logPrefix} Sleeping for %d milliseconds while renewing the lock for message with id '${bMessage.messageId}' is: ${amount}` + `${logPrefix} Sleeping for ${amount} milliseconds while renewing the lock for message with id '${bMessage.messageId}'` ); // Setting the value of the messageId to the actual timer. This will be cleared when // an attempt is made to settle the message (either by the user or by the sdk) OR // when the execution of user's message handler completes. - this._messageRenewLockTimers.set( - bMessage.messageId as string, - setTimeout(async () => { - try { - logger.verbose( - `${logPrefix} Attempting to renew the lock for message with id '${bMessage.messageId}'.` - ); - - bMessage.lockedUntilUtc = await this._context - .getManagementClient(this._linkEntity.entityPath) - .renewLock(lockToken, { - associatedLinkName: this._linkEntity.name - }); - logger.verbose( - `${logPrefix} Successfully renewed the lock for message with id '${bMessage.messageId}'. Starting next auto-lock-renew cycle for message.` - ); - - autoRenewLockTask(); - } catch (err) { - logError( - err, - `${logPrefix} An error occurred while auto renewing the message lock '${bMessage.lockToken}' for message with id '${bMessage.messageId}'` - ); - onError(err); - } - }, amount) - ); + const autoRenewTimer = setTimeout(async () => { + try { + logger.verbose( + `${logPrefix} Attempting to renew the lock for message with id '${bMessage.messageId}'.` + ); + + bMessage.lockedUntilUtc = await this._context + .getManagementClient(linkEntity.entityPath) + .renewLock(lockToken, { + associatedLinkName: linkEntity.name + }); + logger.verbose( + `${logPrefix} Successfully renewed the lock for message with id '${bMessage.messageId}'. Starting next auto-lock-renew cycle for message.` + ); + + autoRenewLockTask(); + } catch (err) { + logError( + err, + `${logPrefix} An error occurred while auto renewing the message lock '${bMessage.lockToken}' for message with id '${bMessage.messageId}'` + ); + onError(err); + } + }, amount); + + // Prevent the active Timer from keeping the Node.js event loop active. + if (typeof autoRenewTimer.unref === "function") { + autoRenewTimer.unref(); + } + + linkMessageMap.set(bMessage.messageId as string, autoRenewTimer); } else { logger.verbose( `${logPrefix} Looks like the message lock renew timer has already been cleared for message with id '${bMessage.messageId}'.` @@ -199,7 +217,7 @@ export class AutoLockRenewer { }'. Hence we will stop the autoLockRenewTask.` ); - this.stop(bMessage); + this.stop(linkEntity, bMessage); } }; @@ -210,19 +228,34 @@ export class AutoLockRenewer { } } - private _stopAndRemoveById(messageId: string | undefined): void { + private _getOrCreateMapForLink(linkEntity: MinimalLink): Map { + if (!this._messageRenewLockTimers.has(linkEntity.name)) { + this._messageRenewLockTimers.set( + linkEntity.name, + new Map() + ); + } + + return this._messageRenewLockTimers.get(linkEntity.name)!; + } + + private _stopAndRemoveById( + linkEntity: MinimalLink, + linkMessageMap: Map, + messageId: string | undefined + ): void { if (messageId == null) { throw new Error("Failed to stop auto lock renewal - no message ID"); } // TODO: messageId doesn't actually need to be unique. Perhaps we should use lockToken // instead? - if (this._messageRenewLockTimers.has(messageId)) { - clearTimeout(this._messageRenewLockTimers.get(messageId) as NodeJS.Timer); + if (linkMessageMap.has(messageId)) { + clearTimeout(linkMessageMap.get(messageId) as NodeJS.Timer); logger.verbose( - `${this._linkEntity.logPrefix} Cleared the message renew lock timer for message with id '${messageId}'.` + `${linkEntity.logPrefix} Cleared the message renew lock timer for message with id '${messageId}'.` ); - this._messageRenewLockTimers.delete(messageId); + linkMessageMap.delete(messageId); } } } diff --git a/sdk/servicebus/service-bus/src/core/batchingReceiver.ts b/sdk/servicebus/service-bus/src/core/batchingReceiver.ts index fcd52ee842af..4d0c17db8b69 100644 --- a/sdk/servicebus/service-bus/src/core/batchingReceiver.ts +++ b/sdk/servicebus/service-bus/src/core/batchingReceiver.ts @@ -35,7 +35,7 @@ export class BatchingReceiver extends MessageReceiver { * @param {ClientEntityContext} context The client entity context. * @param {ReceiveOptions} [options] Options for how you'd like to connect. */ - constructor(context: ConnectionContext, entityPath: string, options?: ReceiveOptions) { + constructor(context: ConnectionContext, entityPath: string, options: ReceiveOptions) { super(context, entityPath, "br", options); this._batchingReceiverLite = new BatchingReceiverLite( @@ -118,12 +118,23 @@ export class BatchingReceiver extends MessageReceiver { this.name ); - return await this._batchingReceiverLite.receiveMessages({ + const messages = await this._batchingReceiverLite.receiveMessages({ maxMessageCount, maxWaitTimeInMs, maxTimeAfterFirstMessageInMs, userAbortSignal }); + + if (this._lockRenewer) { + for (const message of messages) { + this._lockRenewer.start(this, message, (_error) => { + // the auto lock renewer already logs this in a detailed way. So this hook is mainly here + // to potentially forward the error to the user (which we're not doing yet) + }); + } + } + + return messages; } catch (error) { logError( error, @@ -139,7 +150,7 @@ export class BatchingReceiver extends MessageReceiver { static create( context: ConnectionContext, entityPath: string, - options?: ReceiveOptions + options: ReceiveOptions ): BatchingReceiver { throwErrorIfConnectionClosed(context); const bReceiver = new BatchingReceiver(context, entityPath, options); diff --git a/sdk/servicebus/service-bus/src/core/messageReceiver.ts b/sdk/servicebus/service-bus/src/core/messageReceiver.ts index 3bd2b9904021..7c10f642c34f 100644 --- a/sdk/servicebus/service-bus/src/core/messageReceiver.ts +++ b/sdk/servicebus/service-bus/src/core/messageReceiver.ts @@ -19,7 +19,7 @@ import { DispositionStatusOptions } from "./managementClient"; import { AbortSignalLike } from "@azure/core-http"; import { onMessageSettled, DeferredPromiseAndTimer } from "./shared"; import { logError } from "../util/errors"; -import { AutoLockRenewer } from "./autoLockRenewer"; +import { LockRenewer } from "./autoLockRenewer"; /** * @internal @@ -45,13 +45,19 @@ export interface OnAmqpEventAsPromise extends OnAmqpEvent { export interface ReceiveOptions extends MessageHandlerOptions { /** * @property {number} [receiveMode] The mode in which messages should be received. - * Default: ReceiveMode.peekLock */ - receiveMode?: InternalReceiveMode; + receiveMode: InternalReceiveMode; /** * Retry policy options that determine the mode, number of retries, retry interval etc. */ retryOptions?: RetryOptions; + + /** + * A LockAutoRenewer that will automatically renew locks based on user specified interval. + * This will be set if the user has chosen peekLock mode _and_ they've set a positive + * maxAutoRenewLockDurationInMs value when they created their receiver. + */ + lockRenewer: LockRenewer | undefined; } /** @@ -120,31 +126,31 @@ export abstract class MessageReceiver extends LinkEntity { * inside _onAmqpError. */ protected _onError?: OnError; + /** - * An AutoLockRenewer. This is undefined unless the user has activated autolock renewal - * via ReceiveOptions. + * A lock renewer that handles message lock auto-renewal. This is undefined unless the user + * has activated autolock renewal via ReceiveOptions. A single auto lock renewer is shared + * for all links for a `ServiceBusReceiver` instance. */ - protected _autolockRenewer: AutoLockRenewer | undefined; + protected _lockRenewer: LockRenewer | undefined; constructor( context: ConnectionContext, entityPath: string, receiverType: ReceiverType, - options?: Omit + options: Omit ) { super(entityPath, entityPath, context, receiverType, { address: entityPath, audience: `${context.config.endpoint}${entityPath}` }); - if (!options) options = {}; this.receiverType = receiverType; this.receiveMode = options.receiveMode || InternalReceiveMode.peekLock; // If explicitly set to false then autoComplete is false else true (default). this.autoComplete = options.autoComplete === false ? options.autoComplete : true; - - this._autolockRenewer = AutoLockRenewer.create(this, this._context, options); + this._lockRenewer = options.lockRenewer; } /** @@ -231,7 +237,7 @@ export abstract class MessageReceiver extends LinkEntity { * @return {Promise} Promise. */ async close(): Promise { - this._autolockRenewer?.stopAll(); + this._lockRenewer?.stopAll(this); await super.close(); } @@ -251,7 +257,7 @@ export abstract class MessageReceiver extends LinkEntity { if (operation.match(/^(complete|abandon|defer|deadletter)$/) == null) { return reject(new Error(`operation: '${operation}' is not a valid operation.`)); } - this._autolockRenewer?.stop(message); + this._lockRenewer?.stop(this, message); const delivery = message.delivery; const timer = setTimeout(() => { this._deliveryDispositionMap.delete(delivery.id); diff --git a/sdk/servicebus/service-bus/src/core/streamingReceiver.ts b/sdk/servicebus/service-bus/src/core/streamingReceiver.ts index 9146a8fc4632..5f0d35c214f9 100644 --- a/sdk/servicebus/service-bus/src/core/streamingReceiver.ts +++ b/sdk/servicebus/service-bus/src/core/streamingReceiver.ts @@ -29,6 +29,23 @@ import { AmqpError, EventContext, isAmqpError, OnAmqpEvent } from "rhea-promise" import { InternalReceiveMode, ServiceBusMessageImpl } from "../serviceBusMessage"; import { AbortSignalLike } from "@azure/abort-controller"; +/** + * @internal + * @ignore + */ +export interface CreateStreamingReceiverOptions + extends ReceiveOptions, + Pick { + /** + * Used for mocking/stubbing in tests. + */ + _createStreamingReceiverStubForTests?: ( + context: ConnectionContext, + options?: ReceiveOptions + ) => StreamingReceiver; + cachedStreamingReceiver?: StreamingReceiver; +} + /** * @internal * @ignore @@ -106,7 +123,7 @@ export class StreamingReceiver extends MessageReceiver { * @param {ClientEntityContext} context The client entity context. * @param {ReceiveOptions} [options] Options for how you'd like to connect. */ - constructor(context: ConnectionContext, entityPath: string, options?: ReceiveOptions) { + constructor(context: ConnectionContext, entityPath: string, options: ReceiveOptions) { super(context, entityPath, "sr", options); if (typeof options?.maxConcurrentCalls === "number" && options?.maxConcurrentCalls > 0) { @@ -127,7 +144,7 @@ export class StreamingReceiver extends MessageReceiver { receiverError ); - this._autolockRenewer?.stopAll(); + this._lockRenewer?.stopAll(this); if (receiver && !receiver.isItselfClosed()) { await this.onDetached(receiverError); @@ -154,7 +171,7 @@ export class StreamingReceiver extends MessageReceiver { sessionError ); - this._autolockRenewer?.stopAll(); + this._lockRenewer?.stopAll(this); if (receiver && !receiver.isSessionItselfClosed()) { await this.onDetached(sessionError); @@ -258,7 +275,7 @@ export class StreamingReceiver extends MessageReceiver { this.receiveMode ); - this._autolockRenewer?.start(bMessage, (err) => { + this._lockRenewer?.start(this, bMessage, (err) => { if (this._onError) { this._onError(err); } @@ -266,7 +283,6 @@ export class StreamingReceiver extends MessageReceiver { try { await this._onMessage(bMessage); - this._autolockRenewer?.stop(bMessage); } catch (err) { // This ensures we call users' error handler when users' message handler throws. if (!isAmqpError(err)) { @@ -284,7 +300,7 @@ export class StreamingReceiver extends MessageReceiver { // Do not want renewLock to happen unnecessarily, while abandoning the message. Hence, // doing this here. Otherwise, this should be done in finally. - this._autolockRenewer?.stop(bMessage); + this._lockRenewer?.stop(this, bMessage); const error = translate(err) as MessagingError; // Nothing much to do if user's message handler throws. Let us try abandoning the message. if ( @@ -548,17 +564,9 @@ export class StreamingReceiver extends MessageReceiver { static async create( context: ConnectionContext, entityPath: string, - options?: ReceiveOptions & - Pick & { - _createStreamingReceiverStubForTests?: ( - context: ConnectionContext, - options?: ReceiveOptions - ) => StreamingReceiver; - cachedStreamingReceiver?: StreamingReceiver; - } + options: CreateStreamingReceiverOptions ): Promise { throwErrorIfConnectionClosed(context); - if (!options) options = {}; if (options.autoComplete == null) options.autoComplete = true; let sReceiver: StreamingReceiver; diff --git a/sdk/servicebus/service-bus/src/models.ts b/sdk/servicebus/service-bus/src/models.ts index fc88eafb442f..a1e5a6c1583d 100644 --- a/sdk/servicebus/service-bus/src/models.ts +++ b/sdk/servicebus/service-bus/src/models.ts @@ -80,6 +80,16 @@ export interface CreateReceiverOptions { * see https://docs.microsoft.com/azure/service-bus-messaging/service-bus-dead-letter-queues */ subQueue?: SubQueue; + + /** + * The maximum duration in milliseconds until which the lock on the message will be renewed + * by the sdk automatically. This auto renewal stops once the message is settled or once the user + * provided onMessage handler completes ite execution. + * + * - **Default**: `300 * 1000` milliseconds (5 minutes). + * - **To disable autolock renewal**, set this to `0`. + */ + maxAutoLockRenewalDurationInMs?: number; } /** @@ -152,17 +162,7 @@ export interface MessageHandlerOptionsBase extends OperationOptionsBase { * Describes the options passed to `registerMessageHandler` method when receiving messages from a * Queue/Subscription which does not have sessions enabled. */ -export interface MessageHandlerOptions extends MessageHandlerOptionsBase { - /** - * @property The maximum duration in milliseconds until which the lock on the message will be renewed - * by the sdk automatically. This auto renewal stops once the message is settled or once the user - * provided onMessage handler completes ite execution. - * - * - **Default**: `300 * 1000` milliseconds (5 minutes). - * - **To disable autolock renewal**, set this to `0`. - */ - maxAutoRenewLockDurationInMs?: number; -} +export interface MessageHandlerOptions extends MessageHandlerOptionsBase {} /** * Describes the options passed to the `acceptSession` and `acceptNextSession` methods diff --git a/sdk/servicebus/service-bus/src/receivers/receiver.ts b/sdk/servicebus/service-bus/src/receivers/receiver.ts index 85f9d23057b8..7b6ae2d13880 100644 --- a/sdk/servicebus/service-bus/src/receivers/receiver.ts +++ b/sdk/servicebus/service-bus/src/receivers/receiver.ts @@ -21,7 +21,7 @@ import { throwTypeErrorIfParameterNotLong } from "../util/errors"; import { OnError, OnMessage, ReceiveOptions } from "../core/messageReceiver"; -import { StreamingReceiver } from "../core/streamingReceiver"; +import { CreateStreamingReceiverOptions, StreamingReceiver } from "../core/streamingReceiver"; import { BatchingReceiver } from "../core/batchingReceiver"; import { assertValidMessageHandlers, getMessageIterator, wrapProcessErrorHandler } from "./shared"; import { convertToInternalReceiveMode } from "../constructorHelpers"; @@ -29,6 +29,7 @@ import Long from "long"; import { ServiceBusReceivedMessageWithLock, ServiceBusMessageImpl } from "../serviceBusMessage"; import { Constants, RetryConfig, RetryOperationType, RetryOptions, retry } from "@azure/core-amqp"; import "@azure/core-asynciterator-polyfill"; +import { LockRenewer } from "../core/autoLockRenewer"; /** * A receiver that does not handle sessions. @@ -155,6 +156,7 @@ export class ServiceBusReceiverImpl< * Instance of the StreamingReceiver class to use to receive messages in push mode. */ private _streamingReceiver?: StreamingReceiver; + private _lockRenewer: LockRenewer | undefined; /** * @throws Error if the underlying connection is closed. @@ -163,10 +165,16 @@ export class ServiceBusReceiverImpl< private _context: ConnectionContext, public entityPath: string, public receiveMode: "peekLock" | "receiveAndDelete", + maxAutoRenewLockDurationInMs: number, retryOptions: RetryOptions = {} ) { throwErrorIfConnectionClosed(_context); this._retryOptions = retryOptions; + this._lockRenewer = LockRenewer.create( + this._context, + maxAutoRenewLockDurationInMs, + receiveMode + ); } private _throwIfAlreadyReceiving(): void { @@ -235,7 +243,8 @@ export class ServiceBusReceiverImpl< ...options, receiveMode: convertToInternalReceiveMode(this.receiveMode), retryOptions: this._retryOptions, - cachedStreamingReceiver: this._streamingReceiver + cachedStreamingReceiver: this._streamingReceiver, + lockRenewer: this._lockRenewer }) .then(async (sReceiver) => { if (!sReceiver) { @@ -264,15 +273,7 @@ export class ServiceBusReceiverImpl< private _createStreamingReceiver( context: ConnectionContext, entityPath: string, - options?: ReceiveOptions & - Pick & { - createStreamingReceiver?: ( - context: ConnectionContext, - entityPath: string, - options?: ReceiveOptions - ) => StreamingReceiver; - cachedStreamingReceiver?: StreamingReceiver; - } + options: CreateStreamingReceiverOptions ): Promise { return StreamingReceiver.create(context, entityPath, options); } @@ -292,7 +293,8 @@ export class ServiceBusReceiverImpl< if (!this._batchingReceiver || !this._context.messageReceivers[this._batchingReceiver.name]) { const options: ReceiveOptions = { maxConcurrentCalls: 0, - receiveMode: convertToInternalReceiveMode(this.receiveMode) + receiveMode: convertToInternalReceiveMode(this.receiveMode), + lockRenewer: this._lockRenewer }; this._batchingReceiver = this._createBatchingReceiver( this._context, @@ -498,7 +500,7 @@ export class ServiceBusReceiverImpl< private _createBatchingReceiver( context: ConnectionContext, entityPath: string, - options?: ReceiveOptions + options: ReceiveOptions ): BatchingReceiver { return BatchingReceiver.create(context, entityPath, options); } diff --git a/sdk/servicebus/service-bus/src/serviceBusClient.ts b/sdk/servicebus/service-bus/src/serviceBusClient.ts index c06cb2408a3d..1c158dd6dd67 100644 --- a/sdk/servicebus/service-bus/src/serviceBusClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusClient.ts @@ -236,11 +236,17 @@ export class ServiceBusClient { } } + const maxLockAutoRenewDurationInMs = + options?.maxAutoLockRenewalDurationInMs != null + ? options.maxAutoLockRenewalDurationInMs + : 5 * 60 * 1000; + if (receiveMode === "peekLock") { return new ServiceBusReceiverImpl( this._connectionContext, entityPathWithSubQueue, receiveMode, + maxLockAutoRenewDurationInMs, this._clientOptions.retryOptions ); } else { @@ -248,6 +254,7 @@ export class ServiceBusClient { this._connectionContext, entityPathWithSubQueue, receiveMode, + maxLockAutoRenewDurationInMs, this._clientOptions.retryOptions ); } @@ -353,9 +360,7 @@ export class ServiceBusClient { | AcceptSessionOptions<"peekLock"> | AcceptSessionOptions<"receiveAndDelete"> | string, - options4?: - | AcceptSessionOptions<"peekLock"> - | AcceptSessionOptions<"receiveAndDelete"> + options4?: AcceptSessionOptions<"peekLock"> | AcceptSessionOptions<"receiveAndDelete"> ): Promise< | ServiceBusSessionReceiver | ServiceBusSessionReceiver @@ -514,9 +519,7 @@ export class ServiceBusClient { | AcceptSessionOptions<"peekLock"> | AcceptSessionOptions<"receiveAndDelete"> | string, - options3?: - | AcceptSessionOptions<"peekLock"> - | AcceptSessionOptions<"receiveAndDelete"> + options3?: AcceptSessionOptions<"peekLock"> | AcceptSessionOptions<"receiveAndDelete"> ): Promise< | ServiceBusSessionReceiver | ServiceBusSessionReceiver diff --git a/sdk/servicebus/service-bus/test/batchReceiver.spec.ts b/sdk/servicebus/service-bus/test/batchReceiver.spec.ts index 638293d3daed..157ebafaddcb 100644 --- a/sdk/servicebus/service-bus/test/batchReceiver.spec.ts +++ b/sdk/servicebus/service-bus/test/batchReceiver.spec.ts @@ -40,7 +40,12 @@ let deadLetterReceiver: ServiceBusReceiver; async function beforeEachTest(entityType: TestClientType): Promise { entityNames = await serviceBusClient.test.createTestEntities(entityType); - receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); + receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames, { + // prior to a recent change the behavior was always to _not_ auto-renew locks. + // for compat with these tests I'm just disabling this. There are tests in renewLocks.spec.ts that + // ensure lock renewal does work with batching. + maxAutoLockRenewalDurationInMs: 0 + }); sender = serviceBusClient.test.addToCleanup( serviceBusClient.createSender(entityNames.queue ?? entityNames.topic!) diff --git a/sdk/servicebus/service-bus/test/internal/abortSignal.spec.ts b/sdk/servicebus/service-bus/test/internal/abortSignal.spec.ts index 2c426e438569..e7dc0702a3c5 100644 --- a/sdk/servicebus/service-bus/test/internal/abortSignal.spec.ts +++ b/sdk/servicebus/service-bus/test/internal/abortSignal.spec.ts @@ -24,8 +24,14 @@ import { isLinkLocked } from "../utils/misc"; import { ServiceBusSessionReceiverImpl } from "../../src/receivers/sessionReceiver"; import { ServiceBusReceiverImpl } from "../../src/receivers/receiver"; import { MessageSession } from "../../src/session/messageSession"; +import { InternalReceiveMode } from "../../src/serviceBusMessage"; describe("AbortSignal", () => { + const defaultOptions = { + lockRenewer: undefined, + receiveMode: InternalReceiveMode.peekLock + }; + const testMessageThatDoesntMatter = { body: "doesn't matter" }; @@ -253,7 +259,8 @@ describe("AbortSignal", () => { it("...before first async call", async () => { const messageReceiver = new StreamingReceiver( createConnectionContextForTests(), - "fakeEntityPath" + "fakeEntityPath", + defaultOptions ); closeables.push(messageReceiver); @@ -273,7 +280,8 @@ describe("AbortSignal", () => { it("...after negotiateClaim", async () => { const messageReceiver = new StreamingReceiver( createConnectionContextForTests(), - "fakeEntityPath" + "fakeEntityPath", + defaultOptions ); closeables.push(messageReceiver); @@ -304,7 +312,7 @@ describe("AbortSignal", () => { isAborted = true; } }); - const messageReceiver = new StreamingReceiver(fakeContext, "fakeEntityPath"); + const messageReceiver = new StreamingReceiver(fakeContext, "fakeEntityPath", defaultOptions); closeables.push(messageReceiver); messageReceiver["_negotiateClaim"] = async () => {}; @@ -366,7 +374,8 @@ describe("AbortSignal", () => { const receiver = new ServiceBusReceiverImpl( createConnectionContextForTests(), "entityPath", - "peekLock" + "peekLock", + 1 ); try { diff --git a/sdk/servicebus/service-bus/test/internal/autoLockRenewer.spec.ts b/sdk/servicebus/service-bus/test/internal/autoLockRenewer.spec.ts index f63b0bcf3d46..b9413160264a 100644 --- a/sdk/servicebus/service-bus/test/internal/autoLockRenewer.spec.ts +++ b/sdk/servicebus/service-bus/test/internal/autoLockRenewer.spec.ts @@ -7,15 +7,14 @@ import chaiAsPromised from "chai-as-promised"; chai.use(chaiAsPromised); const assert = chai.assert; import * as sinon from "sinon"; -import { AutoLockRenewer } from "../../src/core/autoLockRenewer"; +import { LockRenewer } from "../../src/core/autoLockRenewer"; import { ManagementClient, SendManagementRequestOptions } from "../../src/core/managementClient"; -import { InternalReceiveMode } from "../../src/serviceBusMessage"; import { getPromiseResolverForTest } from "./unittestUtils"; describe("autoLockRenewer unit tests", () => { let clock: ReturnType; - let autoLockRenewer: AutoLockRenewer; + let autoLockRenewer: LockRenewer; let renewLockSpy: sinon.SinonSpy< Parameters, @@ -30,6 +29,12 @@ describe("autoLockRenewer unit tests", () => { msToNextRenewal: 5 }; + const testLinkEntity = { + name: "linkName", + logPrefix: "this is my log prefix", + entityPath: "entity path" + }; + let stopTimerPromise: Promise; beforeEach(() => { @@ -48,22 +53,15 @@ describe("autoLockRenewer unit tests", () => { renewLockSpy = sinon.spy(managementClient, "renewLock"); onErrorFake = sinon.fake(async (_err: Error | MessagingError) => {}); - autoLockRenewer = AutoLockRenewer.create( - { - name: "linkName", - logPrefix: "this is my log prefix", - entityPath: "entity path" - }, + autoLockRenewer = LockRenewer.create( { getManagementClient: (entityPath) => { assert.equal(entityPath, "entity path"); return managementClient; } }, - { - maxAutoRenewLockDurationInMs: limits.maxAdditionalTimeToRenewLock, - receiveMode: InternalReceiveMode.peekLock - } + limits.maxAdditionalTimeToRenewLock, + "peekLock" )!; // always just start the next auto-renew timer after 5 milliseconds to keep things simple. @@ -74,13 +72,29 @@ describe("autoLockRenewer unit tests", () => { const origStop = autoLockRenewer["stop"].bind(autoLockRenewer); - autoLockRenewer["stop"] = (message) => { - origStop(message); + autoLockRenewer["stop"] = (linkEntity, message) => { + origStop(linkEntity, message); stopTimerResolve(); }; }); afterEach(() => { + // each test should properly end "clean" as far as removing any + // message timers. + let lockRenewalTimersTotal = 0; + for (const value of autoLockRenewer["_messageRenewLockTimers"].values()) { + lockRenewalTimersTotal += value.size; + } + + assert.equal( + lockRenewalTimersTotal, + 0, + "Should be no active lock timers after test have completed." + ); + + // the per-link map is not cleaned up automatically - you must + // stopAll() to remove it. + autoLockRenewer.stopAll(testLinkEntity); assert.equal( autoLockRenewer["_messageRenewLockTimers"].size, 0, @@ -92,6 +106,7 @@ describe("autoLockRenewer unit tests", () => { it("standard renewal", async () => { autoLockRenewer.start( + testLinkEntity, { lockToken: "lock token", lockedUntilUtc: new Date(), @@ -103,7 +118,7 @@ describe("autoLockRenewer unit tests", () => { clock.tick(limits.msToNextRenewal - 1); // right before the renew timer would run assert.exists( - autoLockRenewer["_messageRenewLockTimers"].get("message id"), + autoLockRenewer["_messageRenewLockTimers"].get(testLinkEntity.name)?.get("message id"), "auto-renew timer should be set up" ); @@ -123,8 +138,21 @@ describe("autoLockRenewer unit tests", () => { assert.isFalse(onErrorFake.called, "no errors"); }); + it("delete multiple times", () => { + // no lock renewal for this message + autoLockRenewer.stop(testLinkEntity, { + messageId: "hello" + }); + + // no locks have been setup + autoLockRenewer.stopAll(testLinkEntity); + + assert.isEmpty(autoLockRenewer["_messageRenewLockTimers"]); + }); + it("renewal timer not scheduled: message is already locked for longer than our renewal would extend it", () => { autoLockRenewer.start( + testLinkEntity, { lockToken: "lock token", // this date exceeds the max time we would renew for so we don't need to do anything. @@ -144,6 +172,7 @@ describe("autoLockRenewer unit tests", () => { it("renewal timer is not (re)scheduled: the current date has passed our max lock renewal time", async () => { autoLockRenewer.start( + testLinkEntity, { lockToken: "lock token", lockedUntilUtc: new Date(), @@ -175,6 +204,7 @@ describe("autoLockRenewer unit tests", () => { it("invalid message can't renew", () => { autoLockRenewer.start( + testLinkEntity, { messageId: "my message id" }, @@ -198,17 +228,10 @@ describe("autoLockRenewer unit tests", () => { }; it("doesn't support receiveAndDelete mode", () => { - const autoLockRenewer = AutoLockRenewer.create( - { - name: "linkName", - logPrefix: "this is my log prefix", - entityPath: "entity path" - }, + const autoLockRenewer = LockRenewer.create( unusedMgmtClient, - { - maxAutoRenewLockDurationInMs: 1, // this is okay - receiveMode: InternalReceiveMode.receiveAndDelete // this is not okay - there aren't any locks to renew in receiveAndDelete mode. - } + 1, // this is okay, + "receiveAndDelete" // this is not okay - there aren't any locks to renew in receiveAndDelete mode. ); assert.notExists( @@ -219,17 +242,10 @@ describe("autoLockRenewer unit tests", () => { [0, -1].forEach((invalidMaxAutoRenewLockDurationInMs) => { it(`Invalid maxAutoRenewLockDurationInMs duration: ${invalidMaxAutoRenewLockDurationInMs}`, () => { - const autoLockRenewer = AutoLockRenewer.create( - { - name: "linkName", - logPrefix: "this is my log prefix", - entityPath: "entity path" - }, + const autoLockRenewer = LockRenewer.create( unusedMgmtClient, - { - receiveMode: InternalReceiveMode.peekLock, // this is okay - maxAutoRenewLockDurationInMs: invalidMaxAutoRenewLockDurationInMs - } + invalidMaxAutoRenewLockDurationInMs, + "peekLock" // this is okay ); assert.notExists( @@ -238,26 +254,5 @@ describe("autoLockRenewer unit tests", () => { ); }); }); - - it(`maxAutoRenewLockDurationInMs of undefined becomes the default (5 minutes)`, () => { - const autoLockRenewer = AutoLockRenewer.create( - { - name: "linkName", - logPrefix: "this is my log prefix", - entityPath: "entity path" - }, - unusedMgmtClient, - { - receiveMode: InternalReceiveMode.peekLock - } - ); - - assert.exists(autoLockRenewer); - assert.equal( - autoLockRenewer!["_maxAutoRenewDurationInMs"], - 1000 * 5 * 60, - "By default our max auto renew lock duration is 5 minutes" - ); - }); }); }); diff --git a/sdk/servicebus/service-bus/test/internal/batchingReceiver.spec.ts b/sdk/servicebus/service-bus/test/internal/batchingReceiver.spec.ts index acb8360a8dde..79e4dc669bf0 100644 --- a/sdk/servicebus/service-bus/test/internal/batchingReceiver.spec.ts +++ b/sdk/servicebus/service-bus/test/internal/batchingReceiver.spec.ts @@ -52,7 +52,8 @@ describe("BatchingReceiver unit tests", () => { const receiver = new ServiceBusReceiverImpl( createConnectionContextForTests(), "fakeEntityPath", - "peekLock" + "peekLock", + 1 ); let wasCalled = false; @@ -84,7 +85,8 @@ describe("BatchingReceiver unit tests", () => { abortController.abort(); const receiver = new BatchingReceiver(createConnectionContextForTests(), "fakeEntityPath", { - receiveMode: InternalReceiveMode.peekLock + receiveMode: InternalReceiveMode.peekLock, + lockRenewer: undefined }); try { @@ -100,7 +102,8 @@ describe("BatchingReceiver unit tests", () => { const abortController = new AbortController(); const receiver = new BatchingReceiver(createConnectionContextForTests(), "fakeEntityPath", { - receiveMode: InternalReceiveMode.peekLock + receiveMode: InternalReceiveMode.peekLock, + lockRenewer: undefined }); closeables.push(receiver); @@ -185,7 +188,8 @@ describe("BatchingReceiver unit tests", () => { createConnectionContextForTests(), "dummyEntityPath", { - receiveMode: lockMode + receiveMode: lockMode, + lockRenewer: undefined } ); closeables.push(receiver); @@ -218,7 +222,8 @@ describe("BatchingReceiver unit tests", () => { createConnectionContextForTests(), "dummyEntityPath", { - receiveMode: lockMode + receiveMode: lockMode, + lockRenewer: undefined } ); closeables.push(receiver); @@ -249,7 +254,8 @@ describe("BatchingReceiver unit tests", () => { createConnectionContextForTests(), "dummyEntityPath", { - receiveMode: lockMode + receiveMode: lockMode, + lockRenewer: undefined } ); closeables.push(receiver); @@ -300,7 +306,8 @@ describe("BatchingReceiver unit tests", () => { createConnectionContextForTests(), "dummyEntityPath", { - receiveMode: lockMode + receiveMode: lockMode, + lockRenewer: undefined } ); closeables.push(receiver); @@ -356,7 +363,8 @@ describe("BatchingReceiver unit tests", () => { createConnectionContextForTests(), "dummyEntityPath", { - receiveMode: lockMode + receiveMode: lockMode, + lockRenewer: undefined } ); closeables.push(receiver); diff --git a/sdk/servicebus/service-bus/test/internal/receiver.spec.ts b/sdk/servicebus/service-bus/test/internal/receiver.spec.ts index 2b71ca65fb0b..b23d134f929e 100644 --- a/sdk/servicebus/service-bus/test/internal/receiver.spec.ts +++ b/sdk/servicebus/service-bus/test/internal/receiver.spec.ts @@ -20,13 +20,18 @@ import { createAbortSignalForTest } from "../utils/abortSignalTestUtils"; import { AbortSignalLike } from "@azure/abort-controller"; import { ServiceBusSessionReceiverImpl } from "../../src/receivers/sessionReceiver"; import { MessageSession } from "../../src/session/messageSession"; +import { InternalReceiveMode } from "../../src/serviceBusMessage"; describe("Receiver unit tests", () => { describe("init() and close() interactions", () => { it("close() called just after init() but before the next step", async () => { const batchingReceiver = new BatchingReceiver( createConnectionContextForTests(), - "fakeEntityPath" + "fakeEntityPath", + { + lockRenewer: undefined, + receiveMode: InternalReceiveMode.peekLock + } ); let initWasCalled = false; @@ -47,7 +52,11 @@ describe("Receiver unit tests", () => { it("message receiver init() bails out early if object is closed()", async () => { const messageReceiver2 = new StreamingReceiver( createConnectionContextForTests(), - "fakeEntityPath" + "fakeEntityPath", + { + lockRenewer: undefined, + receiveMode: InternalReceiveMode.peekLock + } ); await messageReceiver2.close(); @@ -91,7 +100,8 @@ describe("Receiver unit tests", () => { } }), "fakeEntityPath", - "peekLock" + "peekLock", + 0 ); const subscription = await subscribeAndWaitForInitialize(receiverImpl); @@ -119,7 +129,8 @@ describe("Receiver unit tests", () => { const receiverImpl = new ServiceBusReceiverImpl( createConnectionContextForTests(), "fakeEntityPath", - "peekLock" + "peekLock", + 1 ); const subscription = await subscribeAndWaitForInitialize(receiverImpl); @@ -156,7 +167,8 @@ describe("Receiver unit tests", () => { } }), "fakeEntityPath", - "peekLock" + "peekLock", + 1 ); const subscription = await subscribeAndWaitForInitialize(receiverImpl); @@ -186,7 +198,8 @@ describe("Receiver unit tests", () => { const receiverImpl = new ServiceBusReceiverImpl( createConnectionContextForTests(), "fakeEntityPath", - "peekLock" + "peekLock", + 1 ); const abortSignal = { @@ -250,7 +263,8 @@ describe("Receiver unit tests", () => { const impl = new ServiceBusReceiverImpl( createConnectionContextForTests(), "entity path", - "peekLock" + "peekLock", + 1 ); const abortSignal = createAbortSignalForTest(true); diff --git a/sdk/servicebus/service-bus/test/internal/streamingReceiver.spec.ts b/sdk/servicebus/service-bus/test/internal/streamingReceiver.spec.ts index c8532c8812a6..4991d7445006 100644 --- a/sdk/servicebus/service-bus/test/internal/streamingReceiver.spec.ts +++ b/sdk/servicebus/service-bus/test/internal/streamingReceiver.spec.ts @@ -11,10 +11,16 @@ import { OperationOptions } from "../../src"; import { StreamingReceiver } from "../../src/core/streamingReceiver"; import { AbortController, AbortSignalLike } from "@azure/abort-controller"; import sinon from "sinon"; +import { InternalReceiveMode } from "../../src/serviceBusMessage"; chai.use(chaiAsPromised); const assert = chai.assert; describe("StreamingReceiver unit tests", () => { + const defaultOptions = { + lockRenewer: undefined, + receiveMode: InternalReceiveMode.peekLock + }; + let closeables: { close(): Promise }[]; beforeEach(() => { @@ -31,7 +37,8 @@ describe("StreamingReceiver unit tests", () => { it("off by default", async () => { const streamingReceiver = new StreamingReceiver( createConnectionContextForTests(), - "fakeEntityPath" + "fakeEntityPath", + defaultOptions ); closeables.push(streamingReceiver); assert.isFalse(streamingReceiver.isReceivingMessages); @@ -47,7 +54,8 @@ describe("StreamingReceiver unit tests", () => { createConnectionContextForTests(), "fakeEntityPath", { - maxConcurrentCalls: 101 + maxConcurrentCalls: 101, + ...defaultOptions } ); closeables.push(streamingReceiver); @@ -107,7 +115,8 @@ describe("StreamingReceiver unit tests", () => { it("isReceivingMessages set to false by close()'ing", async () => { const streamingReceiver = new StreamingReceiver( createConnectionContextForTests(), - "fakeEntityPath" + "fakeEntityPath", + defaultOptions ); closeables.push(streamingReceiver); @@ -127,7 +136,8 @@ describe("StreamingReceiver unit tests", () => { it("isReceivingMessages set to false by calling stopReceivingMessages()", async () => { const streamingReceiver = new StreamingReceiver( createConnectionContextForTests(), - "fakeEntityPath" + "fakeEntityPath", + defaultOptions ); closeables.push(streamingReceiver); @@ -147,7 +157,8 @@ describe("StreamingReceiver unit tests", () => { it("isReceivingMessages set to false by calling onDetach and init fails", async () => { const streamingReceiver = new StreamingReceiver( createConnectionContextForTests(), - "fakeEntityPath" + "fakeEntityPath", + defaultOptions ); closeables.push(streamingReceiver); @@ -171,7 +182,8 @@ describe("StreamingReceiver unit tests", () => { it("isReceivingMessages is set to true if onDetach succeeds in reconnecting", async () => { const streamingReceiver = new StreamingReceiver( createConnectionContextForTests(), - "fakeEntityPath" + "fakeEntityPath", + defaultOptions ); closeables.push(streamingReceiver); @@ -198,7 +210,10 @@ describe("StreamingReceiver unit tests", () => { it("create() with an existing receiver and that receiver is open()", async () => { const context = createConnectionContextForTests(); - const existingStreamingReceiver = new StreamingReceiver(context, "fakeEntityPath"); + const existingStreamingReceiver = new StreamingReceiver(context, "fakeEntityPath", { + lockRenewer: undefined, + receiveMode: InternalReceiveMode.peekLock + }); closeables.push(existingStreamingReceiver); await existingStreamingReceiver.init(false); @@ -208,7 +223,9 @@ describe("StreamingReceiver unit tests", () => { const spy = sinon.spy(existingStreamingReceiver, "init"); const newStreamingReceiver = await StreamingReceiver.create(context, "fakeEntityPath", { - cachedStreamingReceiver: existingStreamingReceiver + cachedStreamingReceiver: existingStreamingReceiver, + lockRenewer: undefined, + receiveMode: InternalReceiveMode.peekLock }); assert.isTrue(spy.called, "We do still call init() on the receiver"); @@ -229,7 +246,10 @@ describe("StreamingReceiver unit tests", () => { it("create() with an existing receiver and that receiver is NOT open()", async () => { const context = createConnectionContextForTests(); - const existingStreamingReceiver = new StreamingReceiver(context, "fakeEntityPath"); + const existingStreamingReceiver = new StreamingReceiver(context, "fakeEntityPath", { + lockRenewer: undefined, + receiveMode: InternalReceiveMode.peekLock + }); closeables.push(existingStreamingReceiver); await existingStreamingReceiver.init(false); @@ -247,7 +267,9 @@ describe("StreamingReceiver unit tests", () => { ); const newStreamingReceiver = await StreamingReceiver.create(context, "fakeEntityPath", { - cachedStreamingReceiver: existingStreamingReceiver + cachedStreamingReceiver: existingStreamingReceiver, + receiveMode: InternalReceiveMode.peekLock, + lockRenewer: undefined }); assert.isTrue(spy.called, "We do still call init() on the receiver"); @@ -270,7 +292,8 @@ describe("StreamingReceiver unit tests", () => { const receiverImpl = new ServiceBusReceiverImpl( createConnectionContextForTests(), "fakeEntityPath", - "peekLock" + "peekLock", + 1 ); closeables.push(receiverImpl); @@ -333,7 +356,9 @@ describe("StreamingReceiver unit tests", () => { } } as any) as StreamingReceiver; }, - abortSignal: abortController.signal + abortSignal: abortController.signal, + lockRenewer: undefined, + receiveMode: InternalReceiveMode.receiveAndDelete }); assert.isTrue(wasCalled); diff --git a/sdk/servicebus/service-bus/test/renewLock.spec.ts b/sdk/servicebus/service-bus/test/renewLock.spec.ts index dacc1f791149..cbcd79ae517b 100644 --- a/sdk/servicebus/service-bus/test/renewLock.spec.ts +++ b/sdk/servicebus/service-bus/test/renewLock.spec.ts @@ -10,7 +10,8 @@ import { TestMessage } from "./utils/testUtils"; import { ServiceBusClientForTests, createServiceBusClientForTests, - getRandomTestClientTypeWithNoSessions + getRandomTestClientTypeWithNoSessions, + AutoGeneratedEntity } from "./utils/testutils2"; import { ServiceBusReceiver } from "../src/receivers/receiver"; import { ServiceBusSender } from "../src/sender"; @@ -19,9 +20,9 @@ import { ServiceBusReceivedMessageWithLock } from "../src/serviceBusMessage"; describe("Message Lock Renewal", () => { let serviceBusClient: ServiceBusClientForTests; let sender: ServiceBusSender; - let receiver: ServiceBusReceiver; const testClientType = getRandomTestClientTypeWithNoSessions(); + let autoGeneratedEntity: AutoGeneratedEntity; before(() => { serviceBusClient = createServiceBusClientForTests(); @@ -32,11 +33,10 @@ describe("Message Lock Renewal", () => { }); beforeEach(async () => { - const entityNames = await serviceBusClient.test.createTestEntities(testClientType); - receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); + autoGeneratedEntity = await serviceBusClient.test.createTestEntities(testClientType); sender = serviceBusClient.test.addToCleanup( - serviceBusClient.createSender(entityNames.queue ?? entityNames.topic!) + serviceBusClient.createSender(autoGeneratedEntity.queue ?? autoGeneratedEntity.topic!) ); }); @@ -47,69 +47,79 @@ describe("Message Lock Renewal", () => { it( testClientType + ": Batch Receiver: renewLock() resets lock duration each time.", async function(): Promise { - await testBatchReceiverManualLockRenewalHappyCase(sender, receiver); + await testBatchReceiverManualLockRenewalHappyCase(sender); } ); it( testClientType + ": Batch Receiver: complete() after lock expiry with throws error", async function(): Promise { - await testBatchReceiverManualLockRenewalErrorOnLockExpiry(sender, receiver); + await testBatchReceiverManualLockRenewalErrorOnLockExpiry(sender); } ); it( testClientType + ": Streaming Receiver: renewLock() resets lock duration each time.", async function(): Promise { - await testStreamingReceiverManualLockRenewalHappyCase(sender, receiver); + await testStreamingReceiverManualLockRenewalHappyCase(sender); } ); - it( - testClientType + - ": Streaming Receiver: complete() after lock expiry with auto-renewal disabled throws error", - async function(): Promise { - await testAutoLockRenewalConfigBehavior(sender, receiver, { - maxAutoRenewDurationInMs: 0, - delayBeforeAttemptingToCompleteMessageInSeconds: 31, - willCompleteFail: true + const receiveMethodType: ("subscribe" | "receive" | "iterator")[] = [ + "iterator", + "subscribe", + "receive" + ]; + + describe(`Using configurable renew durations`, () => { + receiveMethodType.forEach((receiveMethodType) => { + it(`${testClientType}: [${receiveMethodType}] Streaming Receiver: complete() after lock expiry with auto-renewal disabled throws error`, async function(): Promise< + void + > { + await testAutoLockRenewalConfigBehavior(sender, receiveMethodType, { + maxAutoRenewDurationInMs: 0, + delayBeforeAttemptingToCompleteMessageInSeconds: 31, + willCompleteFail: true + }); }); - } - ); + }); - it( - testClientType + ": Streaming Receiver: lock will not expire until configured time", - async function(): Promise { - await testAutoLockRenewalConfigBehavior(sender, receiver, { - maxAutoRenewDurationInMs: 38 * 1000, - delayBeforeAttemptingToCompleteMessageInSeconds: 35, - willCompleteFail: false + receiveMethodType.forEach((receiveMethodType) => { + it(`${testClientType}: [${receiveMethodType}] : Streaming Receiver: lock will not expire until configured time`, async function(): Promise< + void + > { + await testAutoLockRenewalConfigBehavior(sender, receiveMethodType, { + maxAutoRenewDurationInMs: 38 * 1000, + delayBeforeAttemptingToCompleteMessageInSeconds: 35, + willCompleteFail: false + }); }); - } - ); + }); - it( - testClientType + ": Streaming Receiver: lock expires sometime after configured time", - async function(): Promise { - await testAutoLockRenewalConfigBehavior(sender, receiver, { - maxAutoRenewDurationInMs: 35 * 1000, - delayBeforeAttemptingToCompleteMessageInSeconds: 55, - willCompleteFail: true - }); - } - ).timeout(95000 + 30000); + receiveMethodType.forEach((receiveMethodType) => { + it(`${testClientType}: [${receiveMethodType}] : Streaming Receiver: lock expires sometime after configured time`, async function(): Promise< + void + > { + await testAutoLockRenewalConfigBehavior(sender, receiveMethodType, { + maxAutoRenewDurationInMs: 35 * 1000, + delayBeforeAttemptingToCompleteMessageInSeconds: 55, + willCompleteFail: true + }); + }).timeout(95000 + 30000); + }); - it( - testClientType + - ": Streaming Receiver: No lock renewal when config value is less than lock duration", - async function(): Promise { - await testAutoLockRenewalConfigBehavior(sender, receiver, { - maxAutoRenewDurationInMs: 15 * 1000, - delayBeforeAttemptingToCompleteMessageInSeconds: 31, - willCompleteFail: true + receiveMethodType.forEach((receiveMethodType) => { + it(`${testClientType}: [${receiveMethodType}] Streaming Receiver: No lock renewal when config value is less than lock duration`, async function(): Promise< + void + > { + await testAutoLockRenewalConfigBehavior(sender, receiveMethodType, { + maxAutoRenewDurationInMs: 15 * 1000, + delayBeforeAttemptingToCompleteMessageInSeconds: 31, + willCompleteFail: true + }); }); - } - ); + }); + }); const lockDurationInMilliseconds = 30000; @@ -123,9 +133,12 @@ describe("Message Lock Renewal", () => { * Test renewLock() after receiving a message using Batch Receiver */ async function testBatchReceiverManualLockRenewalHappyCase( - sender: ServiceBusSender, - receiver: ServiceBusReceiver + sender: ServiceBusSender ): Promise { + const receiver = await serviceBusClient.test.createPeekLockReceiver(autoGeneratedEntity, { + maxAutoLockRenewalDurationInMs: 0 + }); + const testMessage = TestMessage.getSample(); await sender.sendMessages(testMessage); @@ -171,9 +184,12 @@ describe("Message Lock Renewal", () => { * Test settling of message from Batch Receiver fails after message lock expires */ async function testBatchReceiverManualLockRenewalErrorOnLockExpiry( - sender: ServiceBusSender, - receiver: ServiceBusReceiver + sender: ServiceBusSender ): Promise { + const receiver = await serviceBusClient.test.createPeekLockReceiver(autoGeneratedEntity, { + maxAutoLockRenewalDurationInMs: 0 + }); + const testMessage = TestMessage.getSample(); await sender.sendMessages(testMessage); @@ -184,7 +200,8 @@ describe("Message Lock Renewal", () => { should.equal(msgs[0].body, testMessage.body, "MessageBody is different than expected"); should.equal(msgs[0].messageId, testMessage.messageId, "MessageId is different than expected"); - // Sleeping 30 seconds... + // sleeping for long enough to let the message expire (we assume + // the remote entity is using the default duration of 30 seconds for their locks) await delay(lockDurationInMilliseconds + 1000); let errorWasThrown: boolean = false; @@ -204,9 +221,12 @@ describe("Message Lock Renewal", () => { * Test renewLock() after receiving a message using Streaming Receiver with autoLockRenewal disabled */ async function testStreamingReceiverManualLockRenewalHappyCase( - sender: ServiceBusSender, - receiver: ServiceBusReceiver + sender: ServiceBusSender ): Promise { + const receiver = await serviceBusClient.test.createPeekLockReceiver(autoGeneratedEntity, { + maxAutoLockRenewalDurationInMs: 0 + }); + let numOfMessagesReceived = 0; const testMessage = TestMessage.getSample(); await sender.sendMessages(testMessage); @@ -261,8 +281,7 @@ describe("Message Lock Renewal", () => { receiver.subscribe( { processMessage, processError }, { - autoComplete: false, - maxAutoRenewLockDurationInMs: 0 + autoComplete: false } ); await delay(10000); @@ -283,70 +302,89 @@ describe("Message Lock Renewal", () => { async function testAutoLockRenewalConfigBehavior( sender: ServiceBusSender, - receiver: ServiceBusReceiver, + type: "subscribe" | "receive" | "iterator", options: AutoLockRenewalTestOptions ): Promise { - let numOfMessagesReceived = 0; - const testMessage = TestMessage.getSample(); - await sender.sendMessages(testMessage); + const expectedMessage = TestMessage.getSample(`${type} ${Date.now().toString()}`); + await sender.sendMessages(expectedMessage); - async function processMessage( - brokeredMessage: ServiceBusReceivedMessageWithLock - ): Promise { - if (numOfMessagesReceived < 1) { - numOfMessagesReceived++; + const receiver = await serviceBusClient.test.createPeekLockReceiver(autoGeneratedEntity, { + maxAutoLockRenewalDurationInMs: options.maxAutoRenewDurationInMs + }); - should.equal( - brokeredMessage.body, - testMessage.body, - "MessageBody is different than expected" - ); - should.equal( - brokeredMessage.messageId, - testMessage.messageId, - "MessageId is different than expected" - ); + try { + const actualMessage = await receiveSingleMessageUsingSpecificReceiveMethod(receiver, type); - // Sleeping... - await delay(options.delayBeforeAttemptingToCompleteMessageInSeconds * 1000); + should.equal( + actualMessage.body, + expectedMessage.body, + "MessageBody is different than expected" + ); + should.equal( + actualMessage.messageId, + expectedMessage.messageId, + "MessageId is different than expected" + ); - let errorWasThrown: boolean = false; - await brokeredMessage.complete().catch((err) => { - should.equal(err.code, "MessageLockLostError", "Error code is different than expected"); - errorWasThrown = true; - }); + // Sleeping... + await delay(options.delayBeforeAttemptingToCompleteMessageInSeconds * 1000); - should.equal(errorWasThrown, options.willCompleteFail, "Error Thrown flag value mismatch"); - } - } + try { + await actualMessage.complete(); - receiver.subscribe( - { processMessage, processError }, - { - autoComplete: false, - maxAutoRenewLockDurationInMs: options.maxAutoRenewDurationInMs + if (options.willCompleteFail) { + should.fail("complete() should throw an error"); + } + } catch (err) { + if (options.willCompleteFail) { + should.equal(err.code, "MessageLockLostError", "Error code is different than expected"); + } else { + throw err; + } + } + } finally { + try { + const purgingReceiver = await serviceBusClient.test.createReceiveAndDeleteReceiver( + autoGeneratedEntity + ); + await purgingReceiver.receiveMessages(10, { maxWaitTimeInMs: 1000 }); + } catch (err) { + // ignore these errors } - ); - await delay(options.delayBeforeAttemptingToCompleteMessageInSeconds * 1000 + 10000); - - if (uncaughtErrorFromHandlers) { - chai.assert.fail(uncaughtErrorFromHandlers.message); } + } - should.equal(numOfMessagesReceived, 1, "Mismatch in number of messages received"); - - if (options.willCompleteFail) { - // Clean up any left over messages - await receiver.close(); - - receiver = await serviceBusClient.test.createPeekLockReceiver( - await serviceBusClient.test.createTestEntities(testClientType) - ); - - const unprocessedMsgsBatch = await receiver.receiveMessages(1); - if (unprocessedMsgsBatch.length) { - await unprocessedMsgsBatch[0].complete(); + async function receiveSingleMessageUsingSpecificReceiveMethod( + receiver: ServiceBusReceiver, + type: "subscribe" | "receive" | "iterator" + ): Promise { + switch (type) { + case "subscribe": { + return await new Promise((resolve, reject) => { + receiver.subscribe( + { + processMessage: async (msg) => resolve(msg), + processError: async (err) => reject(err) + }, + { + autoComplete: false + } + ); + }); + } + case "receive": { + const messages = await receiver.receiveMessages(1); + should.equal(1, messages.length); + return messages[0]; + } + case "iterator": { + for await (const message of receiver.getMessageIterator()) { + return message; + } + throw new Error("Failed to get message using iterator"); } + default: + throw new Error(`No receive method corresponds to type ${type}`); } } diff --git a/sdk/servicebus/service-bus/test/retries.spec.ts b/sdk/servicebus/service-bus/test/retries.spec.ts index 6df6f6823b51..e0fed6170b3d 100644 --- a/sdk/servicebus/service-bus/test/retries.spec.ts +++ b/sdk/servicebus/service-bus/test/retries.spec.ts @@ -18,6 +18,7 @@ import { ServiceBusSessionReceiver } from "../src/receivers/sessionReceiver"; import { ServiceBusReceiver, ServiceBusReceiverImpl } from "../src/receivers/receiver"; +import { InternalReceiveMode } from "../src/serviceBusMessage"; describe("Retries - ManagementClient", () => { let sender: ServiceBusSender; @@ -353,7 +354,11 @@ describe("Retries - Receive methods", () => { // Mocking batchingReceiver.receive to throw the error and fail const batchingReceiver = BatchingReceiver.create( (receiver as any)._context, - "dummyEntityPath" + "dummyEntityPath", + { + lockRenewer: undefined, + receiveMode: InternalReceiveMode.peekLock + } ); batchingReceiver.isOpen = () => true; batchingReceiver.receive = fakeFunction; diff --git a/sdk/servicebus/service-bus/test/streamingReceiver.spec.ts b/sdk/servicebus/service-bus/test/streamingReceiver.spec.ts index b03f360f466e..e2a6da6d1713 100644 --- a/sdk/servicebus/service-bus/test/streamingReceiver.spec.ts +++ b/sdk/servicebus/service-bus/test/streamingReceiver.spec.ts @@ -171,7 +171,8 @@ describe("Streaming Receiver Tests", () => { (receiver as any)._context, receiver.entityPath, { - receiveMode: InternalReceiveMode.peekLock + receiveMode: InternalReceiveMode.peekLock, + lockRenewer: undefined } ); diff --git a/sdk/servicebus/service-bus/test/utils/testUtils.ts b/sdk/servicebus/service-bus/test/utils/testUtils.ts index 50303c661d9c..b7f3e3092d08 100644 --- a/sdk/servicebus/service-bus/test/utils/testUtils.ts +++ b/sdk/servicebus/service-bus/test/utils/testUtils.ts @@ -9,18 +9,21 @@ dotenv.config(); export class TestMessage { static sessionId: string = "my-session"; - static getSample(): ServiceBusMessage { - const randomNumber = Math.random(); + static getSample(randomTag?: string): ServiceBusMessage { + if (randomTag == null) { + randomTag = Math.random().toString(); + } + return { - body: `message body ${randomNumber}`, - messageId: `message id ${randomNumber}`, + body: `message body ${randomTag}`, + messageId: `message id ${randomTag}`, partitionKey: `dummy partition key`, - contentType: `content type ${randomNumber}`, - correlationId: `correlation id ${randomNumber}`, + contentType: `content type ${randomTag}`, + correlationId: `correlation id ${randomTag}`, timeToLive: 60 * 60 * 24, - label: `label ${randomNumber}`, - to: `to ${randomNumber}`, - replyTo: `reply to ${randomNumber}`, + label: `label ${randomTag}`, + to: `to ${randomTag}`, + replyTo: `reply to ${randomTag}`, scheduledEnqueueTimeUtc: new Date(), properties: { propOne: 1, diff --git a/sdk/servicebus/service-bus/test/utils/testutils2.ts b/sdk/servicebus/service-bus/test/utils/testutils2.ts index d1e2276d184d..4ab7146fefab 100644 --- a/sdk/servicebus/service-bus/test/utils/testutils2.ts +++ b/sdk/servicebus/service-bus/test/utils/testutils2.ts @@ -8,7 +8,8 @@ import { ServiceBusReceiver, ServiceBusSessionReceiver, ServiceBusClientOptions, - AcceptSessionOptions + AcceptSessionOptions, + CreateReceiverOptions } from "../../src"; import { TestClientType, TestMessage } from "./testUtils"; @@ -31,17 +32,24 @@ dotenv.config(); const env = getEnvVars(); const should = chai.should(); -const defaultLockDuration = "PT30S"; // 30 seconds in ISO 8601 FORMAT - equivalent to "P0Y0M0DT0H0M30S" - -function getEntityNames( - testClientType: TestClientType -): { +/** + * Identifier of an auto-generated entity. + * + * note: For the entity name itself either 'queue' or 'topic' (or 'topic and 'subscription') + * will be filled out, depending on the type of test entity you created. + * + */ +export interface AutoGeneratedEntity { queue?: string; topic?: string; subscription?: string; usesSessions: boolean; isPartitioned: boolean; -} { +} + +const defaultLockDuration = "PT30S"; // 30 seconds in ISO 8601 FORMAT - equivalent to "P0Y0M0DT0H0M30S" + +function getEntityNames(testClientType: TestClientType): AutoGeneratedEntity { const name = testClientType; let prefix = ""; let isPartitioned = false; @@ -322,24 +330,25 @@ export class ServiceBusTestHelpers { * The receiver created by this method will be cleaned up by `afterEach()` */ async createPeekLockReceiver( - entityNames: Omit, "isPartitioned"> + entityNames: Omit, "isPartitioned">, + options?: CreateReceiverOptions<"peekLock"> ): Promise> { - try { + if (entityNames.usesSessions) { // if you're creating a receiver this way then you'll just use the default // session ID for your receiver. // if you want to get more specific use the `getPeekLockSessionReceiver` method // instead. - return await this.acceptSessionWithPeekLock(entityNames, TestMessage.sessionId); - } catch (err) { - if (!(err instanceof TypeError)) { - throw err; - } + return await this.acceptSessionWithPeekLock(entityNames, TestMessage.sessionId, options); } return this.addToCleanup( entityNames.queue - ? this._serviceBusClient.createReceiver(entityNames.queue) - : this._serviceBusClient.createReceiver(entityNames.topic!, entityNames.subscription!) + ? this._serviceBusClient.createReceiver(entityNames.queue, options) + : this._serviceBusClient.createReceiver( + entityNames.topic!, + entityNames.subscription!, + options + ) ); } diff --git a/sdk/tables/data-tables/CHANGELOG.md b/sdk/tables/data-tables/CHANGELOG.md index dfb20e73eeca..b79331a48209 100644 --- a/sdk/tables/data-tables/CHANGELOG.md +++ b/sdk/tables/data-tables/CHANGELOG.md @@ -1,5 +1,8 @@ # Release History +## 1.0.0-beta.3 (Unreleased) + + ## 1.0.0-beta.2 (2020-10-06) - Add support for Entity Group Transactions (Batch) [#11551](https://github.com/Azure/azure-sdk-for-js/pull/11551). diff --git a/sdk/tables/data-tables/package.json b/sdk/tables/data-tables/package.json index 42243084dc27..e52b28327b7b 100644 --- a/sdk/tables/data-tables/package.json +++ b/sdk/tables/data-tables/package.json @@ -1,6 +1,6 @@ { "name": "@azure/data-tables", - "version": "1.0.0-beta.2", + "version": "1.0.0-beta.3", "description": "An isomorphic client library for the Azure Tables service.", "sdk-type": "client", "main": "dist/index.js", diff --git a/sdk/tables/data-tables/src/generated/generatedClientContext.ts b/sdk/tables/data-tables/src/generated/generatedClientContext.ts index e90a9fabc5c4..c788ecbbd730 100644 --- a/sdk/tables/data-tables/src/generated/generatedClientContext.ts +++ b/sdk/tables/data-tables/src/generated/generatedClientContext.ts @@ -10,7 +10,7 @@ import * as coreHttp from "@azure/core-http"; import { GeneratedClientOptionalParams } from "./models"; const packageName = "@azure/data-tables"; -const packageVersion = "1.0.0-beta.2"; +const packageVersion = "1.0.0-beta.3"; export class GeneratedClientContext extends coreHttp.ServiceClient { url: string; diff --git a/sdk/tables/data-tables/src/utils/constants.ts b/sdk/tables/data-tables/src/utils/constants.ts index 44a9935759fc..e9ba4597212e 100644 --- a/sdk/tables/data-tables/src/utils/constants.ts +++ b/sdk/tables/data-tables/src/utils/constants.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -export const SDK_VERSION: string = "1.0.0-beta.2"; +export const SDK_VERSION: string = "1.0.0-beta.3"; export const LIB_INFO = `azsdk-js-data-tables/${SDK_VERSION}`; export const HeaderConstants = { diff --git a/sdk/textanalytics/ai-text-analytics/CHANGELOG.md b/sdk/textanalytics/ai-text-analytics/CHANGELOG.md index 53ce5051ee2c..ddc2fff97d55 100644 --- a/sdk/textanalytics/ai-text-analytics/CHANGELOG.md +++ b/sdk/textanalytics/ai-text-analytics/CHANGELOG.md @@ -1,5 +1,8 @@ # Release History +## 5.1.0-beta.3 (Unreleased) + + ## 5.1.0-beta.2 (2020-10-06) - [Breaking] The `length` property is removed from `SentenceSentiment`, `Entity`, `Match`, `PiiEntity`, and `CategorizedEntity` because the length information can be accessed from the text property itself using the string's length property. diff --git a/sdk/textanalytics/ai-text-analytics/package.json b/sdk/textanalytics/ai-text-analytics/package.json index e12810a32fe6..11e6882159fc 100644 --- a/sdk/textanalytics/ai-text-analytics/package.json +++ b/sdk/textanalytics/ai-text-analytics/package.json @@ -3,7 +3,7 @@ "sdk-type": "client", "author": "Microsoft Corporation", "description": "An isomorphic client library for the Azure Text Analytics service.", - "version": "5.1.0-beta.2", + "version": "5.1.0-beta.3", "keywords": [ "node", "azure", diff --git a/sdk/textanalytics/ai-text-analytics/src/constants.ts b/sdk/textanalytics/ai-text-analytics/src/constants.ts index 685cac7578c5..73683a51156b 100644 --- a/sdk/textanalytics/ai-text-analytics/src/constants.ts +++ b/sdk/textanalytics/ai-text-analytics/src/constants.ts @@ -1,4 +1,4 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -export const SDK_VERSION: string = "5.1.0-beta.2"; +export const SDK_VERSION: string = "5.1.0-beta.3"; diff --git a/sdk/textanalytics/ai-text-analytics/src/generated/generatedClientContext.ts b/sdk/textanalytics/ai-text-analytics/src/generated/generatedClientContext.ts index 97e3f6e65aa8..341661a1a5a0 100644 --- a/sdk/textanalytics/ai-text-analytics/src/generated/generatedClientContext.ts +++ b/sdk/textanalytics/ai-text-analytics/src/generated/generatedClientContext.ts @@ -10,7 +10,7 @@ import * as coreHttp from "@azure/core-http"; import { GeneratedClientOptionalParams } from "./models"; const packageName = "@azure/ai-text-analytics"; -const packageVersion = "5.1.0-beta.2"; +const packageVersion = "5.1.0-beta.3"; export class GeneratedClientContext extends coreHttp.ServiceClient { endpoint: string;