diff --git a/.github/workflows/event.yml b/.github/workflows/event.yml index 3a88082782..76c184c71c 100644 --- a/.github/workflows/event.yml +++ b/.github/workflows/event.yml @@ -1,4 +1,7 @@ -name: GitHub Event Handler +# NOTE: currently azure-sdk-actions only hosts check enforcer code. +# If further functionality is added, this name should be updated to reflect +# the more generic behavior +name: Check Enforcer on: check_suite: @@ -6,8 +9,14 @@ on: issue_comment: types: [created] +permissions: {} + jobs: event-handler: + permissions: + statuses: write # to set status (azure/azure-sdk-actions) + pull-requests: read # to read pull requests (azure/azure-sdk-actions) + checks: read # to read check status (azure/azure-sdk-actions) name: Handle ${{ github.event_name }} ${{ github.event.action }} event runs-on: ubuntu-latest steps: diff --git a/.vscode/cspell.json b/.vscode/cspell.json index 37c27178e6..fbd5d8dda6 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -186,6 +186,12 @@ "SECP" ] }, + { + "filename": "**/sdk/core/azure-core/**", + "words": [ + "TEAMPROJECTID" + ] + }, { "filename": "**/sdk/core/azure-core/README.md", "words": [ @@ -235,10 +241,10 @@ ] }, { - "filename": "**/sdk/storage/azure-storage-files-shares/**/*", - "words": [ - "mibps" - ] + "filename": "**/sdk/storage/azure-storage-files-shares/**/*", + "words": [ + "mibps" + ] }, { "filename": "**/cmake-modules/**/*", diff --git a/CMakeSettings.json b/CMakeSettings.json index c10c6410f7..093d2f651c 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -56,12 +56,65 @@ "buildCommandArgs": "", "ctestCommandArgs": "", "inheritEnvironments": [ "msvc_x86" ], + "variables": [ + { + "name": "BUILD_TESTING", + "value": "True", + "type": "BOOL" + }, + { + "name": "VCPKG_TARGET_TRIPLET", + "value": "x86-windows-static", + "type": "STRING" + }, + { + "name": "MSVC_USE_STATIC_CRT", + "value": "True", + "type": "BOOL" + } + ] + }, + { + "name": "x86-Release-static_curl", + "generator": "Ninja", + "configurationType": "MinSizeRel", + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "msvc_x86" ], "variables": [ { "name": "VCPKG_TARGET_TRIPLET", "value": "x86-windows-static", "type": "STRING" }, + { + "name": "BUILD_TESTING", + "value": "True", + "type": "BOOL" + }, + { + "name": "DISABLE_PROXY_TESTS", + "value": "True", + "type": "BOOL" + }, + { + "name": "BUILD_PERFORMANCE_TESTS", + "value": "True", + "type": "BOOL" + }, + { + "name": "RUN_LONG_UNIT_TESTS", + "value": "True", + "type": "BOOL" + }, + { + "name": "BUILD_TRANSPORT_CURL", + "value": "True", + "type": "BOOL" + }, { "name": "MSVC_USE_STATIC_CRT", "value": "True", diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6eab9f5cab..e35adf304c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,7 @@ Thank you for your interest in contributing to Azure SDK for C++. - **DO** submit all code changes via pull requests (PRs) rather than through a direct commit. PRs will be reviewed and potentially merged by the repo maintainers after a peer review that includes at least one maintainer. - **DO** review your own PR to make sure there aren't any unintended changes or commits before submitting it. - **DO NOT** submit "work in progress" PRs. A PR should only be submitted when it is considered ready for review and subsequent merging by the contributor. - - If the change is work-in-progress or an experiment, **DO** start if off as a temporary draft PR. + - If the change is work-in-progress or an experiment, **DO** start it off as a temporary draft PR. - **DO** give PRs short-but-descriptive names (e.g. "Improve code coverage for Azure.Core by 10%", not "Fix #1234") and add a description which explains why the change is being made. - **DO** refer to any relevant issues, and include [keywords](https://docs.github.com/articles/closing-issues-via-commit-messages/) that automatically close issues when the PR is merged. - **DO** tag any users that should know about and/or review the change. @@ -48,13 +48,13 @@ Codespaces is new technology that allows you to use a container as your developm ### GitHub Codespaces 1. From the Azure SDK GitHub repo, click on the "Code -> Open with Codespaces" button. -1. Open a Terminal. The development environment will be ready for you. Continue to [Building and Testing](https://github.com/Azure/azure-sdk-for-cpp/blob/main/CONTRIBUTING.md#building-and-testing). +1. Open a Terminal. The development environment will be ready for you. Continue to [Building the project](#building-the-project). ### VS Code Codespaces 1. Install the [VS Code Remote Extension Pack](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack) 1. When you open the Azure SDK for C++ repo in VS Code, it will prompt you to open the project in the Dev Container. If it does not prompt you, then hit CTRL+P, and select "Remote-Containers: Open Folder in Container..." -1. Open a Terminal. The development environment will be ready for you. Continue to [Building and Testing](https://github.com/Azure/azure-sdk-for-cpp/blob/main/CONTRIBUTING.md#building-and-testing). +1. Open a Terminal. The development environment will be ready for you. Continue to [Building the project](#building-the-project). ## Full Local Setup diff --git a/doc/DistributedTracing.md b/doc/DistributedTracing.md index b9dfe7bc6b..863f4adac6 100644 --- a/doc/DistributedTracing.md +++ b/doc/DistributedTracing.md @@ -1,6 +1,4 @@ ---- -# cspell:words openetelemetry ---- + # Distributed Tracing in the C++ SDK Azure has adopted [W3C Distributed Tracing](https://www.w3.org/TR/trace-context/) as a paradigm for correlating diff --git a/eng/common/pipelines/templates/jobs/perf.yml b/eng/common/pipelines/templates/jobs/perf.yml index 7f0c7f8755..ecd794a1f6 100644 --- a/eng/common/pipelines/templates/jobs/perf.yml +++ b/eng/common/pipelines/templates/jobs/perf.yml @@ -32,9 +32,6 @@ parameters: - name: OperatingSystems type: string default: 'Linux' -- name: Language - type: string - default: '' - name: InstallLanguageSteps type: stepList default: [] @@ -63,19 +60,8 @@ parameters: type: object default: {} -resources: - repositories: - - repository: azure-sdk-tools - type: github - endpoint: Azure - name: Azure/azure-sdk-tools - ref: main - -variables: -- ${{ parameters.Variables }} - jobs: -- job: Perf +- job: ${{ parameters.JobName }} timeoutInMinutes: 360 strategy: matrix: diff --git a/eng/common/scripts/Helpers/DevOps-WorkItem-Helpers.ps1 b/eng/common/scripts/Helpers/DevOps-WorkItem-Helpers.ps1 index 07bd6f8848..ba299856b2 100644 --- a/eng/common/scripts/Helpers/DevOps-WorkItem-Helpers.ps1 +++ b/eng/common/scripts/Helpers/DevOps-WorkItem-Helpers.ps1 @@ -108,8 +108,8 @@ function LoginToAzureDevops([string]$devops_pat) if (!$devops_pat) { return } - $azCmdStr = "'$devops_pat' | az devops login $($ReleaseDevOpsOrgParameters -join ' ')" - Invoke-Expression $azCmdStr + # based on the docs at https://aka.ms/azure-devops-cli-auth the recommendation is to set this env variable to login + $env:AZURE_DEVOPS_EXT_PAT = $devops_pat } function BuildHashKeyNoNull() @@ -234,6 +234,7 @@ function FindPackageWorkItem($lang, $packageName, $version, $outputCommand = $tr $fields += "Custom.PackagePatchVersions" $fields += "Custom.Generated" $fields += "Custom.RoadmapState" + $fields += "Microsoft.VSTS.Common.StateChangeDate" $fieldList = ($fields | ForEach-Object { "[$_]"}) -join ", " $query = "SELECT ${fieldList} FROM WorkItems WHERE [Work Item Type] = 'Package'" @@ -466,7 +467,7 @@ function CreateOrUpdatePackageWorkItem($lang, $pkg, $verMajorMinor, $existingIte if ($pkgName -ne $existingItem.fields["Custom.Package"]) { $changedField = "Custom.Package" } if ($verMajorMinor -ne $existingItem.fields["Custom.PackageVersionMajorMinor"]) { $changedField = "Custom.PackageVersionMajorMinor" } if ($pkgDisplayName -ne $existingItem.fields["Custom.PackageDisplayName"]) { $changedField = "Custom.PackageDisplayName" } - if ($pkgType -ne $existingItem.fields["Custom.PackageType"]) { $changedField = "Custom.PackageType" } + if ($pkgType -ne [string]$existingItem.fields["Custom.PackageType"]) { $changedField = "Custom.PackageType" } if ($pkgNewLibrary -ne $existingItem.fields["Custom.PackageTypeNewLibrary"]) { $changedField = "Custom.PackageTypeNewLibrary" } if ($pkgRepoPath -ne $existingItem.fields["Custom.PackageRepoPath"]) { $changedField = "Custom.PackageRepoPath" } if ($serviceName -ne $existingItem.fields["Custom.ServiceName"]) { $changedField = "Custom.ServiceName" } @@ -884,6 +885,25 @@ function UpdatePackageVersions($pkgWorkItem, $plannedVersions, $shippedVersions) "value": "$shippedPackages" } "@ + + # If we shipped a version after we set "In Release" state then reset the state to "Next Release Unknown" + if ($pkgWorkItem.fields["System.State"] -eq "In Release") + { + $lastShippedDate = [DateTime]$newShippedVersions[0].Date + $markedInReleaseDate = ([DateTime]$pkgWorkItem.fields["Microsoft.VSTS.Common.StateChangeDate"]) + + # We just shipped so lets set the state to "Next Release Unknown" + if ($markedInReleaseDate -le $lastShippedDate) + { + $fieldUpdates += @' +{ + "op": "replace", + "path": "/fields/State", + "value": "Next Release Unknown" +} +'@ + } + } } # Full merged version set diff --git a/eng/common/scripts/Update-DevOps-Release-WorkItem.ps1 b/eng/common/scripts/Update-DevOps-Release-WorkItem.ps1 index 34c7540062..cb96691b83 100644 --- a/eng/common/scripts/Update-DevOps-Release-WorkItem.ps1 +++ b/eng/common/scripts/Update-DevOps-Release-WorkItem.ps1 @@ -33,6 +33,10 @@ az extension show -n azure-devops *> $null if (!$?){ Write-Host 'Installing azure-devops extension' az extension add --name azure-devops +} else { + # Force update the extension to the latest version if it was already installed + # this is needed to ensure we have the authentication issue fixed from earlier versions + az extension update -n azure-devops *> $null } . (Join-Path $PSScriptRoot SemVer.ps1) diff --git a/eng/common/testproxy/target_version.txt b/eng/common/testproxy/target_version.txt index 0ea1143fba..5cc40cb14c 100644 --- a/eng/common/testproxy/target_version.txt +++ b/eng/common/testproxy/target_version.txt @@ -1 +1 @@ -1.0.0-dev.20220810.2 +1.0.0-dev.20220928.2 diff --git a/eng/pipelines/templates/jobs/live.tests.yml b/eng/pipelines/templates/jobs/live.tests.yml index de57d3db24..ffb3678cd9 100644 --- a/eng/pipelines/templates/jobs/live.tests.yml +++ b/eng/pipelines/templates/jobs/live.tests.yml @@ -2,9 +2,6 @@ parameters: - name: Location type: string default: '' -- name: SubscriptionConfiguration - type: string - default: $(sub-config-azure-cloud-test-resources) - name: ServiceDirectory type: string default: not-specified @@ -115,7 +112,7 @@ jobs: dotnet tool install dotnet-reportgenerator-globaltool --tool-path tools displayName: Install coverage tools # CODE_COVERAGE variable is '' (do-not-generate) in all matrix but linux-gcc - # It is 'enabled' by default on linux-gcc but it can be opt-out by each pipeline (disabled) + # It is 'enabled' by default on linux-gcc but it can be opt-out by each pipeline (disabled) condition: and(succeededOrFailed(), ne(variables['CODE_COVERAGE'], 'disabled'), ne(variables['CODE_COVERAGE'], '')) - template: /eng/pipelines/templates/steps/cmake-build.yml @@ -125,12 +122,18 @@ jobs: BuildArgs: "$(BuildArgs)" Env: "$(CmakeEnvArg)" + - template: /eng/common/TestResources/build-test-resource-config.yml + parameters: + SubscriptionConfiguration: ${{ parameters.CloudConfig.SubscriptionConfiguration }} + SubscriptionConfigurations: ${{ parameters.CloudConfig.SubscriptionConfigurations }} + - template: /eng/common/TestResources/deploy-test-resources.yml parameters: ServiceDirectory: ${{ parameters.ServiceDirectory }} - ${{ if or(parameters.Location, parameters.CloudConfig.Location) }}: - Location: ${{ coalesce(parameters.Location, parameters.CloudConfig.Location) }} - SubscriptionConfiguration: ${{ parameters.CloudConfig.SubscriptionConfiguration }} + Location: ${{ coalesce(parameters.Location, parameters.CloudConfig.Location) }} + SubscriptionConfiguration: $(SubscriptionConfiguration) + + - ${{ parameters.PreTestSteps }} - ${{ parameters.PreTestSteps }} @@ -201,9 +204,9 @@ jobs: codeCoverageTool: Cobertura summaryFileLocation: '$(Build.SourcesDirectory)/**/Cobertura.xml' displayName: Publish Code Coverage to DevOps - condition: and(succeededOrFailed(), ne(variables['CODE_COVERAGE'], 'disabled'), ne(variables['CODE_COVERAGE'], '')) + condition: and(succeededOrFailed(), ne(variables['CODE_COVERAGE'], 'disabled'), ne(variables['CODE_COVERAGE'], '')) - template: /eng/common/TestResources/remove-test-resources.yml parameters: ServiceDirectory: ${{ parameters.ServiceDirectory }} - SubscriptionConfiguration: ${{ parameters.SubscriptionConfiguration }} + SubscriptionConfiguration: $(SubscriptionConfiguration) diff --git a/eng/pipelines/templates/jobs/perf.yml b/eng/pipelines/templates/jobs/perf.yml new file mode 100644 index 0000000000..4e1d328449 --- /dev/null +++ b/eng/pipelines/templates/jobs/perf.yml @@ -0,0 +1,44 @@ +parameters: +- name: ServiceDirectory + type: string + default: '' +- name: Services + type: string + default: '' +- name: PackageVersions + type: string + default: '.*' +- name: Tests + type: string + default: '.*' +- name: Arguments + type: string + default: '.*' +- name: Iterations + type: number + default: '5' +- name: AdditionalArguments + type: string + default: '' +- name: EnvVars + type: object + default: [] + +extends: + template: /eng/common/pipelines/templates/jobs/perf.yml + parameters: + Variables: + - template: /eng/pipelines/templates/variables/globals.yml + Language: Cpp + ServiceDirectory: ${{ parameters.ServiceDirectory }} + Services: ${{ parameters.Services }} + PackageVersions: ${{ parameters.PackageVersions }} + Tests: ${{ parameters.Tests }} + Arguments: ${{ parameters.Arguments }} + Iterations: ${{ parameters.Iterations }} + AdditionalArguments: ${{ parameters.AdditionalArguments }} + EnvVars: ${{ parameters.EnvVars}} + InstallLanguageSteps: + - template: /eng/pipelines/templates/steps/vcpkg-clone.yml + parameters: + RepoOwner: Microsoft diff --git a/eng/pipelines/templates/stages/archetype-cpp-release.yml b/eng/pipelines/templates/stages/archetype-cpp-release.yml index e4070400a6..aaf9eeb9f1 100644 --- a/eng/pipelines/templates/stages/archetype-cpp-release.yml +++ b/eng/pipelines/templates/stages/archetype-cpp-release.yml @@ -144,6 +144,7 @@ stages: parameters: RepoOwner: Azure RepoName: azure-sdk-vcpkg-betas + SetVcpkgRoot: false - template: /eng/pipelines/templates/steps/vcpkg-publish.yml parameters: diff --git a/eng/pipelines/templates/stages/platform-matrix-live.json b/eng/pipelines/templates/stages/platform-matrix-live.json index ceb385618d..e2e7f2a803 100644 --- a/eng/pipelines/templates/stages/platform-matrix-live.json +++ b/eng/pipelines/templates/stages/platform-matrix-live.json @@ -1,18 +1,22 @@ { "displayNames": { - "MacOS": "" + "_": "" }, "include": [ { "StaticConfigs": { - "x64_with_unit_test": { + "macOS-11": { "Pool": "Azure Pipelines", "OSVmImage": "macos-11", "VCPKG_DEFAULT_TRIPLET": "x64-osx", - "CmakeArgs": " -DBUILD_TESTING=ON -DRUN_LONG_UNIT_TESTS=ON -DBUILD_PERFORMANCE_TESTS=ON -DBUILD_SAMPLES=ON -DDISABLE_PROXY_TESTS=ON ", - "AZURE_CORE_ENABLE_JSON_TESTS": 1, "BuildArgs": "-j 4" } + }, + "BuildConfig": { + "x64_with_unit_test": { + "CmakeArgs": " -DBUILD_TESTING=ON -DRUN_LONG_UNIT_TESTS=ON -DBUILD_PERFORMANCE_TESTS=ON -DBUILD_SAMPLES=ON -DDISABLE_PROXY_TESTS=ON ", + "AZURE_CORE_ENABLE_JSON_TESTS": 1 + } } }, { @@ -49,7 +53,7 @@ "RunProxyTests": true } }, - "BuildConfiguration": { + "BuildConfig": { "x64_with_unit_test": { "CmakeArgs": " -DBUILD_TESTING=ON -DBUILD_PERFORMANCE_TESTS=ON -DRUN_LONG_UNIT_TESTS=ON -DCMAKE_BUILD_TYPE=Release -DBUILD_SAMPLES=ON", "AZURE_CORE_ENABLE_JSON_TESTS": 1 diff --git a/eng/pipelines/templates/steps/vcpkg-clone.yml b/eng/pipelines/templates/steps/vcpkg-clone.yml index b374bee15d..eb0f1dc8ab 100644 --- a/eng/pipelines/templates/steps/vcpkg-clone.yml +++ b/eng/pipelines/templates/steps/vcpkg-clone.yml @@ -3,6 +3,7 @@ parameters: RepoOwner: not-set RepoName: vcpkg PRBranchName: not-set + SetVcpkgRoot: true steps: - pwsh: | @@ -14,6 +15,13 @@ steps: } displayName: Clone vcpkg (${{ parameters.RepoOwner }}/${{ parameters.RepoName }}) + - ${{ if eq(parameters.SetVcpkgRoot, true) }}: + - pwsh: | + $vcpkgRoot = Resolve-Path "${{ parameters.Workspace }}/${{ parameters.RepoName }}" + Write-Host "Set VCPKG_ROOT: $vcpkgRoot" + Write-Host "##vso[task.setvariable variable=VCPKG_ROOT]$vcpkgRoot" + displayName: Set VCPKG_ROOT + # Check out the PR branch if it's already in remote. Ignore failures. - pwsh: | $ErrorActionPreference = "Continue" diff --git a/eng/pipelines/templates/variables/globals.yml b/eng/pipelines/templates/variables/globals.yml new file mode 100644 index 0000000000..b782b88239 --- /dev/null +++ b/eng/pipelines/templates/variables/globals.yml @@ -0,0 +1,22 @@ +variables: + # True if 'Enable system diagnostics' is checked when running a pipeline manually + IsDebug: $[coalesce(variables['System.Debug'], 'false')] + + AdditionalOptions: '' + + # Exists if needed in coalesce situations. + DefaultTestGoals: 'surefire:test' + # This will be overwritten by the test matrix, if configured. + TestGoals: $(DefaultTestGoals) + + # This will be overwritten by the test matrix, if configured. + TestOptions: '' + # TestFromSource is one of the cache keys but isn't set until the test matrix + # has been processed. Without a default value it'll be treated as a string literal + # "$(TestFromSource)" instead of true/false. It'll be overwritten when the test + # matrix has been processed + TestFromSource: false + + skipComponentGovernanceDetection: true + DisableDockerDetector: true + Package.EnableSBOMSigning: true diff --git a/sdk/attestation/azure-security-attestation/CHANGELOG.md b/sdk/attestation/azure-security-attestation/CHANGELOG.md index b032e5a8d2..e4300cd817 100644 --- a/sdk/attestation/azure-security-attestation/CHANGELOG.md +++ b/sdk/attestation/azure-security-attestation/CHANGELOG.md @@ -6,6 +6,11 @@ ### Breaking Changes +- Changed `AttestationClient::AttestTpm` to match `AttestOpenEnclave` and `AttestSgxEnclave` +- Added `std::vector` dataToAttest parameter. +- Removed `Payload` in `TpmAttestationOptions` +- Changed `TpmResult` in `TpmAttestationResult` to type `std::vector` + ### Bugs Fixed ### Other Changes diff --git a/sdk/attestation/azure-security-attestation/README.md b/sdk/attestation/azure-security-attestation/README.md index a04514ca14..e4f267cb53 100644 --- a/sdk/attestation/azure-security-attestation/README.md +++ b/sdk/attestation/azure-security-attestation/README.md @@ -1,7 +1,4 @@ ---- -# cspell:words opentelemetry ---- - + # Azure Attestation Package client library for C++ Microsoft Azure Attestation is a unified solution for remotely verifying the trustworthiness of a platform and integrity of the binaries running inside it. The service supports attestation of the platforms backed by Trusted Platform Modules (TPMs) alongside the ability to attest to the state of Trusted Execution Environments (TEEs) such as Intel(tm) Software Guard Extensions (SGX) enclaves and Virtualization-based Security (VBS) enclaves. diff --git a/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client.hpp b/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client.hpp index 4aa60061ed..d7c44d4941 100644 --- a/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client.hpp +++ b/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client.hpp @@ -223,26 +223,20 @@ namespace Azure { namespace Security { namespace Attestation { Azure::Core::Context const& context = Azure::Core::Context{}) const; /** - * @brief Perform a single leg - * - * Processes attestation evidence from a VBS enclave, producing an attestation result. - * + * @brief Sends TPM-based attestation data to the service. * The TPM attestation protocol is defined * [here](https://docs.microsoft.com/azure/attestation/virtualization-based-security-protocol') * - * Unlike OpenEnclave reports and SGX enclave quotes, TPM attestation is implemented using - * JSON encoded strings. * - * The client formats a string serialized JSON request to the - * service, which responds with a JSON response. The serialized JSON object exchange continues - * until the service responds with a JSON string with a property named {@code "report"}, whose - * value will be an attestation result token. + * @param dataToAttest - Attestation request data. + * @param options - Options to the attestation request. + * @param context - Context for the operation. * - * @param options sent to the service for Trusted Platform Module (TPM) attestation. - * @return attestation response for Trusted Platform Module (TPM) attestation. + * @return Response - The result of the attestation operation */ Response AttestTpm( - AttestTpmOptions const& options, + std::vector const& dataToAttest, + AttestTpmOptions const& options = AttestTpmOptions{}, Azure::Core::Context const& context = Azure::Core::Context{}) const; private: diff --git a/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client_models.hpp b/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client_models.hpp index 2fb15bcc51..c4db47e2ae 100644 --- a/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client_models.hpp +++ b/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client_models.hpp @@ -448,12 +448,13 @@ namespace Azure { namespace Security { namespace Attestation { namespace Models */ struct TpmAttestationResult final { - /** @brief The JSON encoded value returned from TPM attestation. + /** @brief Attestation response data. + * * The TPM attestation protocol is defined * [here](https://docs.microsoft.com/azure/attestation/virtualization-based-security-protocol') * */ - std::string TpmResult; + std::vector TpmResult; }; /** diff --git a/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client_options.hpp b/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client_options.hpp index a94cf6092e..b9f1a2450a 100644 --- a/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client_options.hpp +++ b/sdk/attestation/azure-security-attestation/inc/azure/attestation/attestation_client_options.hpp @@ -261,12 +261,6 @@ namespace Azure { namespace Security { namespace Attestation { */ struct AttestTpmOptions final { - /** - * @brief JSON Data to send to the attestation service for TPM attestation. - * @details The TPM attestation protocol is defined - * [here](https://docs.microsoft.com/azure/attestation/virtualization-based-security-protocol') - */ - std::string Payload; }; /** @brief The AttestationSigningKey represents a tuple of asymmetric private cryptographic key diff --git a/sdk/attestation/azure-security-attestation/src/attestation_client.cpp b/sdk/attestation/azure-security-attestation/src/attestation_client.cpp index 1e0077adc3..8786466e1d 100644 --- a/sdk/attestation/azure-security-attestation/src/attestation_client.cpp +++ b/sdk/attestation/azure-security-attestation/src/attestation_client.cpp @@ -196,13 +196,14 @@ Azure::Response> AttestationClient::AttestOp } Azure::Response AttestationClient::AttestTpm( - AttestTpmOptions const& attestTpmOptions, + std::vector const& dataToAttest, + AttestTpmOptions const&, Azure::Core::Context const& context) const { auto tracingContext(m_tracingFactory.CreateTracingContext("AttestTpm", context)); try { - std::string jsonToSend = TpmDataSerializer::Serialize(attestTpmOptions.Payload); + std::string jsonToSend = TpmDataSerializer::Serialize(dataToAttest); auto encodedVector = std::vector(jsonToSend.begin(), jsonToSend.end()); Azure::Core::IO::MemoryBodyStream stream(encodedVector); @@ -212,7 +213,7 @@ Azure::Response AttestationClient::AttestTpm( // Send the request to the service. auto response = AttestationCommonRequest::SendRequest(*m_pipeline, request, tracingContext.Context); - std::string returnedBody(TpmDataSerializer::Deserialize(response)); + std::vector returnedBody{TpmDataSerializer::Deserialize(response)}; return Response(TpmAttestationResult{returnedBody}, std::move(response)); } catch (std::runtime_error const& ex) diff --git a/sdk/attestation/azure-security-attestation/src/private/attestation_deserializers_private.cpp b/sdk/attestation/azure-security-attestation/src/private/attestation_deserializers_private.cpp index 580fcdf503..684cec9432 100644 --- a/sdk/attestation/azure-security-attestation/src/private/attestation_deserializers_private.cpp +++ b/sdk/attestation/azure-security-attestation/src/private/attestation_deserializers_private.cpp @@ -397,21 +397,21 @@ namespace Azure { namespace Security { namespace Attestation { namespace _detail returnValue.CertificateThumbprint, jsonResult, "x-ms-certificate-thumbprint"); return returnValue; } - std::string TpmDataSerializer::Serialize(std::string const& tpmData) + std::string TpmDataSerializer::Serialize(std::vector const& tpmData) { Azure::Core::Json::_internal::json jsonData; - jsonData["data"] = Azure::Core::_internal::Base64Url::Base64UrlEncode( - std::vector(tpmData.begin(), tpmData.end())); + jsonData["data"] = Azure::Core::_internal::Base64Url::Base64UrlEncode(tpmData); return jsonData.dump(); } - std::string TpmDataSerializer::Deserialize(Azure::Core::Json::_internal::json const& jsonData) + std::vector TpmDataSerializer::Deserialize( + Azure::Core::Json::_internal::json const& jsonData) { std::vector returnValue; JsonOptional::SetIfExists>( returnValue, jsonData, "data", Azure::Core::_internal::Base64Url::Base64UrlDecode); - return std::string(returnValue.begin(), returnValue.end()); + return returnValue; } - std::string TpmDataSerializer::Deserialize( + std::vector TpmDataSerializer::Deserialize( std::unique_ptr const& response) { return TpmDataSerializer::Deserialize( diff --git a/sdk/attestation/azure-security-attestation/src/private/attestation_deserializers_private.hpp b/sdk/attestation/azure-security-attestation/src/private/attestation_deserializers_private.hpp index 6cc7d1279b..9b72f35fac 100644 --- a/sdk/attestation/azure-security-attestation/src/private/attestation_deserializers_private.hpp +++ b/sdk/attestation/azure-security-attestation/src/private/attestation_deserializers_private.hpp @@ -136,9 +136,10 @@ namespace Azure { namespace Security { namespace Attestation { namespace _detail struct TpmDataSerializer { - static std::string Serialize(std::string const& tpmData); - static std::string Deserialize(Azure::Core::Json::_internal::json const& jsonData); - static std::string Deserialize(std::unique_ptr const& response); + static std::string Serialize(std::vector const& tpmData); + static std::vector Deserialize(Azure::Core::Json::_internal::json const& jsonData); + static std::vector Deserialize( + std::unique_ptr const& response); }; }}}} // namespace Azure::Security::Attestation::_detail diff --git a/sdk/attestation/azure-security-attestation/test/ut/tpmattestation_test.cpp b/sdk/attestation/azure-security-attestation/test/ut/tpmattestation_test.cpp index dad0c78f55..2d0737e12c 100644 --- a/sdk/attestation/azure-security-attestation/test/ut/tpmattestation_test.cpp +++ b/sdk/attestation/azure-security-attestation/test/ut/tpmattestation_test.cpp @@ -118,7 +118,8 @@ namespace Azure { namespace Security { namespace Attestation { namespace Test { { auto client(CreateClient(InstanceType::AAD)); - auto response(client.AttestTpm(AttestTpmOptions{R"({"payload": { "type": "aikcert" } })"})); + std::string tpmQuote = R"({"payload": { "type": "aikcert" } })"; + auto response(client.AttestTpm(std::vector(tpmQuote.begin(), tpmQuote.end()))); Azure::Core::Json::_internal::json parsedResponse( Azure::Core::Json::_internal::json::parse(response.Value.TpmResult)); diff --git a/sdk/core/azure-core/CHANGELOG.md b/sdk/core/azure-core/CHANGELOG.md index e7add57eed..e83939cde4 100644 --- a/sdk/core/azure-core/CHANGELOG.md +++ b/sdk/core/azure-core/CHANGELOG.md @@ -6,9 +6,20 @@ - Added support for the `WebSockets` protocol via the `Azure::Core::Http::WebSockets::WebSocket` class. - Added support for HTTP proxy servers, both unauthenticated and with Plain authentication. +- Added universal support for several TLS options: + - Added the ability to set the expected TLS root certificate for TLS connection (useful if a proxy server uses a TLS certificate that is not chained to a known root). + - Added the ability to enable TLS certificate revocation list checks (off by default). + - For libcurl only: Allow TLS connection to succeed if CRL retrieval fails. + - *NOTE*: This change only applies if libcurl is built using the OpenSSL crypto backend. It does NOT apply if libcurl uses the schannel (Windows default) or SecureTransport (macOS/iOS default). ### Breaking Changes +- Updated retry policy timeouts to conform to Azure guidelines. + - The default delay between retries is changed from 4 seconds to 800ms. + - The maximum retry delay is changed from 2 minutes to 60 seconds (one minute). + + If the original behavior is desired, customers can adjust these timeouts by changing the `RetryDelay` and `MaxRetryDelay` fields in in the `TransportOptions` structure. + ### Bugs Fixed ### Other Changes diff --git a/sdk/core/azure-core/CMakeLists.txt b/sdk/core/azure-core/CMakeLists.txt index 4cf4415ad1..94ff527cd4 100644 --- a/sdk/core/azure-core/CMakeLists.txt +++ b/sdk/core/azure-core/CMakeLists.txt @@ -36,6 +36,10 @@ if(BUILD_TRANSPORT_CURL) message("Libcurl version ${CURL_VERSION_STRING}") endif() +if(BUILD_TRANSPORT_WINHTTP) + find_package(wil CONFIG REQUIRED) +endif() + if(BUILD_TRANSPORT_CURL) SET(CURL_TRANSPORT_ADAPTER_SRC src/http/curl/curl.cpp @@ -52,10 +56,12 @@ endif() if(BUILD_TRANSPORT_WINHTTP) SET(WIN_TRANSPORT_ADAPTER_SRC src/http/winhttp/win_http_transport.cpp - src/http/winhttp/win_http_websockets.cpp) + src/http/winhttp/win_http_websockets.cpp + ) SET(WIN_TRANSPORT_ADAPTER_INC inc/azure/core/http/win_http_transport.hpp - inc/azure/core/http/websockets/win_http_websockets_transport.hpp) + inc/azure/core/http/websockets/win_http_websockets_transport.hpp + ) endif() set( @@ -182,7 +188,7 @@ if(BUILD_TRANSPORT_CURL) target_link_libraries(azure-core PUBLIC CURL::libcurl) endif() if(BUILD_TRANSPORT_WINHTTP) - target_link_libraries(azure-core PRIVATE winhttp) + target_link_libraries(azure-core PRIVATE winhttp WIL::WIL) endif() get_az_version("${CMAKE_CURRENT_SOURCE_DIR}/src/private/package_version.hpp") diff --git a/sdk/core/azure-core/cgmanifest.json b/sdk/core/azure-core/cgmanifest.json index a84431c793..e2a629c88f 100644 --- a/sdk/core/azure-core/cgmanifest.json +++ b/sdk/core/azure-core/cgmanifest.json @@ -21,6 +21,16 @@ }, "DevelopmentDependency": false }, + { + "Component": { + "Type": "git", + "git": { + "RepositoryUrl": "https://github.com/microsoft/wil", + "CommitHash": "f9284c19c9873664978b873b8858d7dfacc6af1e" + } + }, + "DevelopmentDependency": false + }, { "Component": { "Type": "git", diff --git a/sdk/core/azure-core/inc/azure/core/base64.hpp b/sdk/core/azure-core/inc/azure/core/base64.hpp index b5262e7a94..6f65a0b78d 100644 --- a/sdk/core/azure-core/inc/azure/core/base64.hpp +++ b/sdk/core/azure-core/inc/azure/core/base64.hpp @@ -72,7 +72,7 @@ namespace Azure { namespace Core { * @brief Encodes a string using Base64 encoding. * * @param data The input string that contains data to be encoded. - * @return The Base64 encoded contents of the vector. + * @return The Base64 encoded contents of the string. */ static std::string Base64Encode(const std::string& data); }; diff --git a/sdk/core/azure-core/inc/azure/core/context.hpp b/sdk/core/azure-core/inc/azure/core/context.hpp index 68ee8b31cd..b46b01e63c 100644 --- a/sdk/core/azure-core/inc/azure/core/context.hpp +++ b/sdk/core/azure-core/inc/azure/core/context.hpp @@ -146,23 +146,6 @@ namespace Azure { namespace Core { */ Context() : m_contextSharedState(std::make_shared()) {} - /** - * @brief Constructs a `%Context` from another `%Context` instance. - * - * @param that Another instance to copy. - * - */ - Context(Context const& that) = default; - - /** - * @brief Assigns `%Context` to another `%Context` instance. - * - * @param other Another instance to copy. - * - * @return A reference to this `%Context`. - */ - Context& operator=(const Context& other) = default; - /** * @brief Creates a context with a deadline. * diff --git a/sdk/core/azure-core/inc/azure/core/http/curl_transport.hpp b/sdk/core/azure-core/inc/azure/core/http/curl_transport.hpp index cf6ef84ae3..7db6266c7a 100644 --- a/sdk/core/azure-core/inc/azure/core/http/curl_transport.hpp +++ b/sdk/core/azure-core/inc/azure/core/http/curl_transport.hpp @@ -10,6 +10,7 @@ #include "azure/core/context.hpp" #include "azure/core/http/http.hpp" +#include "azure/core/http/policies/policy.hpp" #include "azure/core/http/transport.hpp" namespace Azure { namespace Core { namespace Http { @@ -28,7 +29,7 @@ namespace Azure { namespace Core { namespace Http { * @brief The available options to set libcurl SSL options. * * @remark The SDK will map the enum option to libcurl's specific option. See more info here: - * https://curl.haxx.se/libcurl/c/CURLOPT_SSL_OPTIONS.html + * https://curl.se/libcurl/c/CURLOPT_SSL_OPTIONS.html * */ struct CurlTransportSslOptions final @@ -38,7 +39,7 @@ namespace Azure { namespace Core { namespace Http { * * @remark Libcurl does revocation list check by default for SSL backends that supports this * feature. However, the Azure SDK overrides libcurl's behavior and disables the revocation list - * check by default. This ensures that the LibCURL behavior matches the WinHTTP behavior. + * check by default. This ensures that the libcurl behavior matches the WinHTTP behavior. */ bool EnableCertificateRevocationListCheck = false; @@ -46,8 +47,8 @@ namespace Azure { namespace Core { namespace Http { * @brief This option allows SSL connections to proceed even if there is an error retrieving the * Certificate Revocation List. * - * @remark Note that this only works when LibCURL is configured to use openssl as its TLS - * provider. That functionally limits this check to Linux only, and then only when openssl is + * @remark Note that this only works when libcurl is configured to use OpenSSL as its TLS + * provider. That functionally limits this check to Linux only, and only when openssl is * configured (the default). */ bool AllowFailedCrlRetrieval = false; @@ -59,7 +60,7 @@ namespace Azure { namespace Core { namespace Http { * @remark The Azure SDK will not directly validate these certificates. * * @remark More about this option: - * https://curl.haxx.se/libcurl/c/CURLOPT_CAINFO_BLOB.html + * https://curl.se/libcurl/c/CURLOPT_CAINFO_BLOB.html * */ std::string PemEncodedExpectedRootCertificates; @@ -78,7 +79,7 @@ namespace Azure { namespace Core { namespace Http { * proxy settings from the system (use no proxy). * * @remark No validation for the string is done by the Azure SDK. More about this option: - * https://curl.haxx.se/libcurl/c/CURLOPT_PROXY.html. + * https://curl.se/libcurl/c/CURLOPT_PROXY.html. * * @remark The default value is an empty string (no proxy). * @@ -89,23 +90,24 @@ namespace Azure { namespace Core { namespace Http { * @brief Username to be used for proxy connections. * * @remark No validation for the string is done by the Azure SDK. More about this option: - * https://curl.haxx.se/libcurl/c/CURLOPT_PROXY_USERNAME.html. + * https://curl.se/libcurl/c/CURLOPT_PROXYUSERNAME.html. * * @remark The default value is an empty string (no proxy). * */ - std::string ProxyUsername; + Azure::Nullable ProxyUsername; /** * @brief Password to be used for proxy connections. * * @remark No validation for the string is done by the Azure SDK. More about this option: - * https://curl.haxx.se/libcurl/c/CURLOPT_PROXY_PASSWORD.html. + * https://curl.se/libcurl/c/CURLOPT_PROXYPASSWORD.html. * - * @remark The default value is an empty string (no proxy). + * @remark If a value is provided, the value will be used (this allows the caller to provide an + * empty password) * */ - std::string ProxyPassword; + Azure::Nullable ProxyPassword; /** * @brief Path to a PEM encoded file containing the certificate authorities sent to libcurl * handle directly. @@ -113,7 +115,7 @@ namespace Azure { namespace Core { namespace Http { * @remark The Azure SDK will not check if the path is valid or not. * * @remark The default is the built-in system specific path. More about this option: - * https://curl.haxx.se/libcurl/c/CURLOPT_CAINFO.html + * https://curl.se/libcurl/c/CURLOPT_CAINFO.html * */ std::string CAInfo; @@ -135,7 +137,7 @@ namespace Azure { namespace Core { namespace Http { * certificate. * * @remark The default value is `true`. More about this option: - * https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html + * https://curl.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html * */ bool SslVerifyPeer = true; @@ -143,7 +145,7 @@ namespace Azure { namespace Core { namespace Http { /** * @brief Define the SSL options for the libcurl handle. * - * @remark See more info here: https://curl.haxx.se/libcurl/c/CURLOPT_SSL_OPTIONS.html. + * @remark See more info here: https://curl.se/libcurl/c/CURLOPT_SSL_OPTIONS.html. * The default option is all options `false`. * */ @@ -170,7 +172,7 @@ namespace Azure { namespace Core { namespace Http { std::chrono::milliseconds ConnectionTimeout = _detail::DefaultConnectionTimeout; /** - * @brief If set, enables extended tracing from LibCURL. + * @brief If set, integrates libcurl's internal tracing with Azure logging. */ bool EnableCurlTracing = false; }; @@ -182,7 +184,6 @@ namespace Azure { namespace Core { namespace Http { private: CurlTransportOptions m_options; - protected: /** * @brief Called when an HTTP response indicates the connection should be upgraded to * a websocket. Takes ownership of the CurlNetworkConnection object. @@ -203,8 +204,19 @@ namespace Azure { namespace Core { namespace Http { // [Core Guidelines C.35: "A base class destructor should be either public // and virtual or protected and // non-virtual"](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c35-a-base-class-destructor-should-be-either-public-and-virtual-or-protected-and-non-virtual) + + /** + * @brief Destroys a CurlTransport object. + */ virtual ~CurlTransport() = default; + /** + * @brief Construct a new CurlTransport object based on common Azure HTTP Transport Options + * + * @param options Common Azure Core Transport Options. + */ + CurlTransport(Azure::Core::Http::Policies::TransportOptions const& options); + /** * @brief Implements interface to send an HTTP Request and produce an HTTP RawResponse * diff --git a/sdk/core/azure-core/inc/azure/core/http/policies/policy.hpp b/sdk/core/azure-core/inc/azure/core/http/policies/policy.hpp index 61e144939d..eb47716bb0 100644 --- a/sdk/core/azure-core/inc/azure/core/http/policies/policy.hpp +++ b/sdk/core/azure-core/inc/azure/core/http/policies/policy.hpp @@ -97,7 +97,7 @@ namespace Azure { namespace Core { namespace Http { namespace Policies { * @note See https://en.cppreference.com/w/cpp/chrono/duration. * */ - std::chrono::milliseconds MaxRetryDelay = std::chrono::minutes(2); + std::chrono::milliseconds MaxRetryDelay = std::chrono::seconds(60); /** * @brief The HTTP status codes that indicate when an operation should be retried. @@ -137,29 +137,40 @@ namespace Azure { namespace Core { namespace Http { namespace Policies { */ struct TransportOptions final { -#if !defined(BUILD_TRANSPORT_CUSTOM_ADAPTER) -#if defined(BUILD_TRANSPORT_WINHTTP_ADAPTER) || defined(BUILD_CURL_HTTP_TRANSPORT_ADAPTER) /** - * @brief Http Proxies used when making an HTTP connection. + * @brief The URL for the proxy server to use for this connection. * - * @remark The URL for the proxy server to use for this connection. + * @remark If an empty string is specified, it instructs the transport to disable all proxies, + * including system proxies. + * + * @remark This field is only used if the customer has not specified a default transport + * adapter. If the customer has set a Transport adapter, this option is ignored. */ Azure::Nullable HttpProxy{}; /** * @brief The username to use when authenticating with the proxy server. + * + * @remark This field is only used if the customer has not specified a default transport + * adapter. If the customer has set a Transport adapter, this option is ignored. */ - std::string ProxyUserName{}; + Azure::Nullable ProxyUserName{}; /** * @brief The password to use when authenticating with the proxy server. + * + * @remark This field is only used if the customer has not specified a default transport + * adapter. If the customer has set a Transport adapter, this option is ignored. */ - std::string ProxyPassword{}; + Azure::Nullable ProxyPassword{}; /** * @brief Enable TLS Certificate validation against a certificate revocation list. * - * @remark Note that by default CRL validation is *disabled*. + * @remark Note that by default, CRL validation is *disabled*. + * + * @remark This field is only used if the customer has not specified a default transport + * adapter. If the customer has set a Transport adapter, this option is ignored. */ bool EnableCertificateRevocationListCheck{false}; @@ -167,15 +178,15 @@ namespace Azure { namespace Core { namespace Http { namespace Policies { * @brief Base64 encoded DER representation of an X.509 certificate expected in the certificate * chain used in TLS connections. * - * @remark Note that with the schannel and sectransp crypto backends, settting the + * @remark Note that with the schannel and sectransp crypto backends, setting the * expected root certificate disables access to the system certificate store. * This means that the expected root certificate is the only certificate that will be trusted. + * + * @remark This field is only used if the customer has not specified a default transport + * adapter. If the customer has set a Transport adapter, this option is ignored. */ std::string ExpectedTlsRootCertificate{}; -#endif // defined(CURL_ADAPTER) || defined(WINHTTP_ADAPTER) -#endif // !defined(BUILD_TRANSPORT_CUSTOM_ADAPTER) - /** * @brief #Azure::Core::Http::HttpTransport that the transport policy will use to send and * receive requests and responses over the wire. @@ -189,6 +200,10 @@ namespace Azure { namespace Core { namespace Http { namespace Policies { * @remark When using a custom transport adapter, the implementation for * `::AzureSdkGetCustomHttpTransport()` must be linked in the end-user application. * + * @remark If the caller specifies a value for Transport, then all the other options in + * TransportOptions will be ignored, since the caller will have already configured the + * transport. + * */ std::shared_ptr Transport; }; diff --git a/sdk/core/azure-core/inc/azure/core/http/websockets/win_http_websockets_transport.hpp b/sdk/core/azure-core/inc/azure/core/http/websockets/win_http_websockets_transport.hpp index 8fdf5b533c..4d7fb045f3 100644 --- a/sdk/core/azure-core/inc/azure/core/http/websockets/win_http_websockets_transport.hpp +++ b/sdk/core/azure-core/inc/azure/core/http/websockets/win_http_websockets_transport.hpp @@ -23,13 +23,13 @@ namespace Azure { namespace Core { namespace Http { namespace WebSockets { */ class WinHttpWebSocketTransport : public WebSocketTransport, public WinHttpTransport { - Azure::Core::Http::_detail::unique_HINTERNET m_socketHandle; + Azure::Core::_internal::UniqueHandle m_socketHandle; std::mutex m_sendMutex; std::mutex m_receiveMutex; // Called by the void OnUpgradedConnection( - Azure::Core::Http::_detail::unique_HINTERNET const& requestHandle) override; + Azure::Core::_internal::UniqueHandle const& requestHandle) override; public: /** diff --git a/sdk/core/azure-core/inc/azure/core/http/win_http_transport.hpp b/sdk/core/azure-core/inc/azure/core/http/win_http_transport.hpp index 9001cbcbb5..74c7c5bcc0 100644 --- a/sdk/core/azure-core/inc/azure/core/http/win_http_transport.hpp +++ b/sdk/core/azure-core/inc/azure/core/http/win_http_transport.hpp @@ -6,12 +6,15 @@ * @brief #Azure::Core::Http::HttpTransport implementation via WinHTTP. * cspell:words HCERTIFICATECHAIN PCCERT CCERT HCERTCHAINENGINE HCERTSTORE */ +// cspell:words HCERTIFICATECHAIN PCCERT CCERT HCERTCHAINENGINE HCERTSTORE #pragma once #include "azure/core/context.hpp" #include "azure/core/http/http.hpp" +#include "azure/core/http/policies/policy.hpp" #include "azure/core/http/transport.hpp" +#include "azure/core/internal/unique_handle.hpp" #include @@ -32,291 +35,256 @@ #include #include -namespace Azure { namespace Core { namespace Http { - - namespace _detail { - - constexpr static size_t DefaultUploadChunkSize = 1024 * 64; - constexpr static size_t MaximumUploadChunkSize = 1024 * 1024; - - // unique_ptr class wrapping an HINTERNET handle - class HINTERNET_deleter { - public: - void operator()(HINTERNET handle) noexcept - { - if (handle != nullptr) - { - WinHttpCloseHandle(handle); - } - } - }; - using unique_HINTERNET = std::unique_ptr; - - // unique_ptr class wrapping a PCCERT_CHAIN_CONTEXT - struct HCERTIFICATECHAIN_deleter +namespace Azure { namespace Core { + namespace _internal { + /** + * @brief Unique handle for WinHTTP HINTERNET handles. + * + * @note HINTERNET is declared as a "void *". THis means that this definition subsumes all other + * `void *` types when used with Azure::Core::_internal::UniqueHandle. + * + */ + template <> struct UniqueHandleHelper { - void operator()(PCCERT_CHAIN_CONTEXT handle) - { - // unique_ptr class wrapping an HINTERNET handle - { - CertFreeCertificateChain(handle); - } - } - }; - using unique_CCERT_CHAIN_CONTEXT - = std::unique_ptr; + static void FreeHandle(HINTERNET obj) { WinHttpCloseHandle(obj); } - // unique_ptr class wrapping an HCERTCHAINENGINE handle - struct HCERTCHAINENGINE_deleter - { - void operator()(HCERTCHAINENGINE handle) noexcept - { - if (handle != nullptr) - { - CertFreeCertificateChainEngine(handle); - } - } + using type = BasicUniqueHandle; }; - using unique_HCERTCHAINENGINE = std::unique_ptr; - - // unique_ptr class wrapping an HCERTSTORE handle - struct HCERTSTORE_deleter - { - public: - void operator()(HCERTSTORE handle) noexcept - { - if (handle != nullptr) + } // namespace _internal + + namespace Http { + + namespace _detail { + + constexpr static size_t DefaultUploadChunkSize = 1024 * 64; + constexpr static size_t MaximumUploadChunkSize = 1024 * 1024; + + class WinHttpStream final : public Azure::Core::IO::BodyStream { + private: + Azure::Core::_internal::UniqueHandle m_requestHandle; + bool m_isEOF; + + /** + * @brief This is a copy of the value of an HTTP response header `content-length`. The value + * is received as string and parsed to size_t. This field avoids parsing the string header + * every time from HTTP RawResponse. + * + * @remark This value is also used to avoid trying to read more data from network than what + * we are expecting to. + * + * @remark A value of -1 means the transfer encoding was chunked. + * + */ + int64_t m_contentLength; + + int64_t m_streamTotalRead; + + /** + * @brief Implement #Azure::Core::IO::BodyStream::OnRead(). Calling this function pulls data + * from the wire. + * + * @param context A context to control the request lifetime. + * @param buffer Buffer where data from wire is written to. + * @param count The number of bytes to read from the network. + * @return The actual number of bytes read from the network. + */ + size_t OnRead(uint8_t* buffer, size_t count, Azure::Core::Context const& context) override; + + public: + WinHttpStream( + Azure::Core::_internal::UniqueHandle& requestHandle, + int64_t contentLength) + : m_requestHandle(std::move(requestHandle)), m_contentLength(contentLength), + m_isEOF(false), m_streamTotalRead(0) { - CertCloseStore(handle, 0); } - } - }; - using unique_HCERTSTORE = std::unique_ptr; - // unique_ptr class wrapping a PCCERT_CONTEXT - struct CERTCONTEXT_deleter + /** + * @brief Implement #Azure::Core::IO::BodyStream length. + * + * @return The size of the payload. + */ + int64_t Length() const override { return this->m_contentLength; } + }; + } // namespace _detail + + /** + * @brief Sets the WinHTTP session and connection options used to customize the behavior of the + * transport. + */ + struct WinHttpTransportOptions final { - public: - void operator()(PCCERT_CONTEXT handle) noexcept - { - if (handle != nullptr) - { - CertFreeCertificateContext(handle); - } - } - }; - using unique_PCCERT_CONTEXT = std::unique_ptr; + /** + * @brief When `true`, allows an invalid certificate authority. + */ + bool IgnoreUnknownCertificateAuthority{false}; - class WinHttpStream final : public Azure::Core::IO::BodyStream { - private: - _detail::unique_HINTERNET m_requestHandle; - bool m_isEOF; + /** + * Proxy information. + */ /** - * @brief This is a copy of the value of an HTTP response header `content-length`. The value - * is received as string and parsed to size_t. This field avoids parsing the string header - * every time from HTTP RawResponse. - * - * @remark This value is also used to avoid trying to read more data from network than what we - * are expecting to. + * @brief If True, enables the use of the system default proxy. * - * @remark A value of -1 means the transfer encoding was chunked. + * @remarks Set this to "true" if you would like to use a local HTTP proxy like "Fiddler" to + * capture and analyze HTTP traffic. * + * Set to "false" by default because it is not recommended to use a proxy for production and + * Fiddler's proxy interferes with the HTTP functional tests. */ - int64_t m_contentLength; - - int64_t m_streamTotalRead; + bool EnableSystemDefaultProxy{false}; /** - * @brief Implement #Azure::Core::IO::BodyStream::OnRead(). Calling this function pulls data - * from the wire. - * - * @param context A context to control the request lifetime. - * @param buffer Buffer where data from wire is written to. - * @param count The number of bytes to read from the network. - * @return The actual number of bytes read from the network. + * @brief If True, enables checks for certificate revocation. */ - size_t OnRead(uint8_t* buffer, size_t count, Azure::Core::Context const& context) override; - - public: - WinHttpStream(_detail::unique_HINTERNET& requestHandle, int64_t contentLength) - : m_requestHandle(std::move(requestHandle)), m_contentLength(contentLength), - m_isEOF(false), m_streamTotalRead(0) - { - } + bool EnableCertificateRevocationListCheck{false}; /** - * @brief Implement #Azure::Core::IO::BodyStream length. + * @brief Proxy information. + * + * @remark The Proxy Information string is composed of a set of elements + * formatted as follows: + * ([=]["://"][":"]) * - * @return The size of the payload. + * Each element should be separated with semicolons or whitespace. */ - int64_t Length() const override { return this->m_contentLength; } - }; - } // namespace _detail - - /** - * @brief Sets the WinHTTP session and connection options used to customize the behavior of the - * transport. - */ - struct WinHttpTransportOptions final - { - /** - * @brief When `true`, allows an invalid certificate authority. - */ - bool IgnoreUnknownCertificateAuthority{false}; + std::string ProxyInformation; - /** - * Proxy information. - */ + /** + * @brief User name for proxy authentication. + */ + Azure::Nullable ProxyUserName; - /** - * @brief If True, enables the use of the system default proxy. - * - * @remarks Set this to "true" if you would like to use a local HTTP proxy like "Fiddler" to - * capture and analyze HTTP traffic. - * - * Set to "false" by default because it is not recommended to use a proxy for production and - * Fiddler's proxy interferes with the HTTP functional tests. - */ - bool EnableSystemDefaultProxy{false}; + /** + * @brief Password for proxy authentication. + */ + Azure::Nullable ProxyPassword; - /** - * @brief If True, enables checks for certificate revocation. - */ - bool EnableCertificateRevocationListCheck{false}; + /** + * @brief Array of Base64 encoded DER encoded X.509 certificate. These certificates should + * form a chain of certificates which will be used to validate the server certificate sent by + * the server. + */ + std::vector ExpectedTlsRootCertificates; + }; /** - * @brief Proxy information. - * - * @remark The Proxy Information string is composed of a set of elements - * formatted as follows: - * ([=]["://"][":"]) - * - * Each element should be separated with semicolons or whitespace. + * @brief Concrete implementation of an HTTP transport that uses WinHTTP when sending and + * receiving requests and responses over the wire. */ - std::string ProxyInformation; + class WinHttpTransport : public HttpTransport { + private: + WinHttpTransportOptions m_options; + + // This should remain immutable and not be modified after calling the ctor, to avoid threading + // issues. + Azure::Core::_internal::UniqueHandle m_sessionHandle; + bool m_requestHandleClosed{false}; + + Azure::Core::_internal::UniqueHandle CreateSessionHandle(); + Azure::Core::_internal::UniqueHandle CreateConnectionHandle( + Azure::Core::Url const& url, + Azure::Core::Context const& context); + Azure::Core::_internal::UniqueHandle CreateRequestHandle( + Azure::Core::_internal::UniqueHandle const& connectionHandle, + Azure::Core::Url const& url, + Azure::Core::Http::HttpMethod const& method); + void Upload( + Azure::Core::_internal::UniqueHandle const& requestHandle, + Azure::Core::Http::Request& request, + Azure::Core::Context const& context); + void SendRequest( + Azure::Core::_internal::UniqueHandle const& requestHandle, + Azure::Core::Http::Request& request, + Azure::Core::Context const& context); + void ReceiveResponse( + Azure::Core::_internal::UniqueHandle const& requestHandle, + Azure::Core::Context const& context); + int64_t GetContentLength( + Azure::Core::_internal::UniqueHandle const& requestHandle, + HttpMethod requestMethod, + HttpStatusCode responseStatusCode); + std::unique_ptr SendRequestAndGetResponse( + Azure::Core::_internal::UniqueHandle& requestHandle, + HttpMethod requestMethod); + + /* + * Callback from WinHTTP called after the TLS certificates are received when the caller sets + * expected TLS root certificates. + */ + static void CALLBACK StatusCallback( + HINTERNET hInternet, + DWORD_PTR dwContext, + DWORD dwInternetStatus, + LPVOID lpvStatusInformation, + DWORD dwStatusInformationLength) noexcept; + /* + * Callback from WinHTTP called after the TLS certificates are received when the caller sets + * expected TLS root certificates. + */ + void OnHttpStatusOperation(HINTERNET hInternet, DWORD dwInternetStatus); + /* + * Adds the specified trusted certificates to the specified certificate store. + */ + bool AddCertificatesToStore( + std::vector const& trustedCertificates, + HCERTSTORE const hCertStore); + /* + * Verifies that the certificate context is in the trustedCertificates set of certificates. + */ + bool VerifyCertificatesInChain( + std::vector const& trustedCertificates, + PCCERT_CONTEXT serverCertificate); - /** - * @brief User name for proxy authentication. - */ - std::string ProxyUserName; + // Callback to allow a derived transport to extract the request handle. Used for WebSocket + // transports. + virtual void OnUpgradedConnection(Azure::Core::_internal::UniqueHandle const&){}; - /** - * @brief Password for proxy authentication. - */ - std::string ProxyPassword; + protected: + /** + * @brief Throw an exception based on the Win32 Error code + * + * @param exceptionMessage Message describing error. + * @param error Win32 Error code. + */ + void GetErrorAndThrow(const std::string& exceptionMessage, DWORD error = GetLastError()); - /** - * @brief Array of Base64 encoded DER encoded X.509 certificate. These certificates should form - * a chain of certificates which will be used to validate the server certificate sent by the - * server. - */ - std::vector ExpectedTlsRootCertificates; - }; - - /** - * @brief Concrete implementation of an HTTP transport that uses WinHTTP when sending and - * receiving requests and responses over the wire. - */ - class WinHttpTransport : public HttpTransport { - private: - WinHttpTransportOptions m_options; - - // This should remain immutable and not be modified after calling the ctor, to avoid threading - // issues. - _detail::unique_HINTERNET m_sessionHandle; - bool m_requestHandleClosed{false}; - - _detail::unique_HINTERNET CreateSessionHandle(); - _detail::unique_HINTERNET CreateConnectionHandle( - Azure::Core::Url const& url, - Azure::Core::Context const& context); - _detail::unique_HINTERNET CreateRequestHandle( - _detail::unique_HINTERNET const& connectionHandle, - Azure::Core::Url const& url, - Azure::Core::Http::HttpMethod const& method); - void Upload( - _detail::unique_HINTERNET const& requestHandle, - Azure::Core::Http::Request& request, - Azure::Core::Context const& context); - void SendRequest( - _detail::unique_HINTERNET const& requestHandle, - Azure::Core::Http::Request& request, - Azure::Core::Context const& context); - void ReceiveResponse( - _detail::unique_HINTERNET const& requestHandle, - Azure::Core::Context const& context); - int64_t GetContentLength( - _detail::unique_HINTERNET const& requestHandle, - HttpMethod requestMethod, - HttpStatusCode responseStatusCode); - std::unique_ptr SendRequestAndGetResponse( - _detail::unique_HINTERNET& requestHandle, - HttpMethod requestMethod); - - /* - * Callback from WinHTTP called after the TLS certificates are received when the caller sets - * expected TLS root certificates. - */ - static void CALLBACK StatusCallback( - HINTERNET hInternet, - DWORD_PTR dwContext, - DWORD dwInternetStatus, - LPVOID lpvStatusInformation, - DWORD dwStatusInformationLength) noexcept; - /* - * Callback from WinHTTP called after the TLS certificates are received when the caller sets - * expected TLS root certificates. - */ - void OnHttpStatusOperation(HINTERNET hInternet, DWORD dwInternetStatus); - /* - * Adds the specified trusted certificates to the specified certificate store. - */ - bool AddCertificatesToStore( - std::vector const& trustedCertificates, - _detail::unique_HCERTSTORE const& hCertStore); - /* - * Verifies that the certificate context is in the trustedCertificates set of certificates. - */ - bool VerifyCertificatesInChain( - std::vector const& trustedCertificates, - _detail::unique_PCCERT_CONTEXT const& serverCertificate); - - // Callback to allow a derived transport to extract the request handle. Used for WebSocket - // transports. - protected: - virtual void OnUpgradedConnection(_detail::unique_HINTERNET const&){}; - /** - * @brief Throw an exception based on the Win32 Error code - * - * @param exceptionMessage Message describing error. - * @param error Win32 Error code. - */ - void GetErrorAndThrow(const std::string& exceptionMessage, DWORD error = GetLastError()); + public: + /** + * @brief Constructs `%WinHttpTransport`. + * + * @param options Optional parameter to override the default settings. + */ + WinHttpTransport(WinHttpTransportOptions const& options = WinHttpTransportOptions()); - public: - /** - * @brief Constructs `%WinHttpTransport`. - * - * @param options Optional parameter to override the default settings. - */ - WinHttpTransport(WinHttpTransportOptions const& options = WinHttpTransportOptions()); + /** + * @brief Constructs `%WinHttpTransport`. + * + * @param options Optional parameter to override the default settings. + */ + /** + * @brief Constructs `%WinHttpTransport` object based on common Azure HTTP Transport Options + * + * @param options Common Azure Core Transport Options to override the default settings. + */ + WinHttpTransport(Azure::Core::Http::Policies::TransportOptions const& options); - /** - * @brief Implements the HTTP transport interface to send an HTTP Request and produce an HTTP - * RawResponse. - * - * @param context A context to control the request lifetime. - * @param request an HTTP request to be send. - * @return A unique pointer to an HTTP RawResponse. - */ - virtual std::unique_ptr Send(Request& request, Context const& context) override; + /** + * @brief Implements the HTTP transport interface to send an HTTP Request and produce an HTTP + * RawResponse. + * + * @param context A context to control the request lifetime. + * @param request an HTTP request to be send. + * @return A unique pointer to an HTTP RawResponse. + */ + virtual std::unique_ptr Send(Request& request, Context const& context) override; - // See also: - // [Core Guidelines C.35: "A base class destructor should be either public - // and virtual or protected and - // non-virtual"](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c35-a-base-class-destructor-should-be-either-public-and-virtual-or-protected-and-non-virtual) - virtual ~WinHttpTransport() = default; - }; + // See also: + // [Core Guidelines C.35: "A base class destructor should be either public + // and virtual or protected and + // non-virtual"](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c35-a-base-class-destructor-should-be-either-public-and-virtual-or-protected-and-non-virtual) + virtual ~WinHttpTransport() = default; + }; -}}} // namespace Azure::Core::Http + } // namespace Http +}} // namespace Azure::Core diff --git a/sdk/core/azure-core/inc/azure/core/internal/unique_handle.hpp b/sdk/core/azure-core/inc/azure/core/internal/unique_handle.hpp new file mode 100644 index 0000000000..788eaf0bf6 --- /dev/null +++ b/sdk/core/azure-core/inc/azure/core/internal/unique_handle.hpp @@ -0,0 +1,66 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT +#pragma once +#include + +namespace Azure { namespace Core { namespace _internal { + + /** + * Helpers to provide RAII wrappers for OpenSSL, WinHTTP, CURL, and other types. + * + * These classes enable callers to wrap std::unique_ptr for arbitrary 3rd party library types. + * + * To add support for a 3rd party type, you need to define a helper structure which lets + * std::unique_ptr know how to delete the underlying object: + * + * template <> struct UniqueHandleHelper + * { + * using type = BasicUniqueHandle; + * }; + * + * Note that for some types (HINTERNET for example), the helper needs to be a bit more + * complicated: template <> struct UniqueHandleHelper + * { + * static void FreeHandle(HINTERNET obj) { WinHttpCloseHandle(obj); } + * using type = BasicUniqueHandle; + * }; + * + * This is because WinHttpCloseHandle returns a BOOL, not void, so we need to wrap the call to + * WinHttpCloseHandle(). In addition, an HINTERNET is a `void *` type, which means that the + * std::unique_handle underlying type needs to be `void`. + * + */ + + /** + * @brief std::unique_ptr deleter class which provides a specialization for a deleter function. + */ + template struct UniqueHandleDeleter + { + void operator()(T* obj) { Deleter(obj); } + }; + + /** + * @brief Inner specialization for std::unique_ptr for the + */ + template + using BasicUniqueHandle = std::unique_ptr>; + + /** + * @brief Helper template structure to wrap the map between the type and free function + * + * template <> struct UniqueHandleHelper + * { + * using type = BasicUniqueHandle; + * }; + * + * template <> struct UniqueHandleHelper + * { + * using type = BasicUniqueHandle; + * }; + */ + // *** Given just T, map it to the corresponding FreeFunc + template struct UniqueHandleHelper; + + // *** Now users can say UniqueHandle if they want: + template using UniqueHandle = typename UniqueHandleHelper::type; +}}} // namespace Azure::Core::_internal diff --git a/sdk/core/azure-core/src/cryptography/md5.cpp b/sdk/core/azure-core/src/cryptography/md5.cpp index 79a4a1210f..1bfb9c23e2 100644 --- a/sdk/core/azure-core/src/cryptography/md5.cpp +++ b/sdk/core/azure-core/src/cryptography/md5.cpp @@ -167,7 +167,7 @@ class Md5OpenSSL final : public Azure::Core::Cryptography::Hash { { if (1 != EVP_DigestUpdate(m_context, data, length)) { - throw std::runtime_error("Crypto error while updating Md5Hash."); + throw std::runtime_error("Crypto error while updating Md5Hash."); // LCOV_EXCL_LINE } } @@ -178,7 +178,7 @@ class Md5OpenSSL final : public Azure::Core::Cryptography::Hash { unsigned char hash[EVP_MAX_MD_SIZE]; if (1 != EVP_DigestFinal(m_context, hash, &size)) { - throw std::runtime_error("Crypto error while computing Md5Hash."); + throw std::runtime_error("Crypto error while computing Md5Hash."); // LCOV_EXCL_LINE } return std::vector(std::begin(hash), std::begin(hash) + size); @@ -194,7 +194,7 @@ class Md5OpenSSL final : public Azure::Core::Cryptography::Hash { } if (1 != EVP_DigestInit_ex(m_context, EVP_md5(), NULL)) { - throw std::runtime_error("Crypto error while init Md5Hash."); + throw std::runtime_error("Crypto error while init Md5Hash."); // LCOV_EXCL_LINE } } diff --git a/sdk/core/azure-core/src/cryptography/sha_hash.cpp b/sdk/core/azure-core/src/cryptography/sha_hash.cpp index 95b06b7d7a..bc4017ef65 100644 --- a/sdk/core/azure-core/src/cryptography/sha_hash.cpp +++ b/sdk/core/azure-core/src/cryptography/sha_hash.cpp @@ -44,7 +44,7 @@ class SHAWithOpenSSL final : public Azure::Core::Cryptography::Hash { unsigned char finalHash[EVP_MAX_MD_SIZE]; if (1 != EVP_DigestFinal(m_context, finalHash, &size)) { - throw std::runtime_error("Crypto error while computing Sha256Hash."); + throw std::runtime_error("Crypto error while computing Sha256Hash."); // LCOV_EXCL_LINE } return std::vector(std::begin(finalHash), std::begin(finalHash) + size); } @@ -53,7 +53,7 @@ class SHAWithOpenSSL final : public Azure::Core::Cryptography::Hash { { if (1 != EVP_DigestUpdate(m_context, data, length)) { - throw std::runtime_error("Crypto error while updating Sha256Hash."); + throw std::runtime_error("Crypto error while updating Sha256Hash."); // LCOV_EXCL_LINE } } @@ -62,41 +62,41 @@ class SHAWithOpenSSL final : public Azure::Core::Cryptography::Hash { { if ((m_context = EVP_MD_CTX_new()) == NULL) { - throw std::runtime_error("Crypto error while creating EVP context."); + throw std::runtime_error("Crypto error while creating EVP context."); // LCOV_EXCL_LINE } switch (size) { case SHASize::SHA1: { if (1 != EVP_DigestInit_ex(m_context, EVP_sha1(), NULL)) { - throw std::runtime_error("Crypto error while initializing Sha1Hash."); + throw std::runtime_error("Crypto error while initializing Sha1Hash."); // LCOV_EXCL_LINE } break; } case SHASize::SHA256: { if (1 != EVP_DigestInit_ex(m_context, EVP_sha256(), NULL)) { - throw std::runtime_error("Crypto error while init Sha256Hash."); + throw std::runtime_error("Crypto error while init Sha256Hash."); // LCOV_EXCL_LINE } break; } case SHASize::SHA384: { if (1 != EVP_DigestInit_ex(m_context, EVP_sha384(), NULL)) { - throw std::runtime_error("Crypto error while init Sha384Hash."); + throw std::runtime_error("Crypto error while init Sha384Hash."); // LCOV_EXCL_LINE } break; } case SHASize::SHA512: { if (1 != EVP_DigestInit_ex(m_context, EVP_sha512(), NULL)) { - throw std::runtime_error("Crypto error while init Sha512Hash."); + throw std::runtime_error("Crypto error while init Sha512Hash."); // LCOV_EXCL_LINE } break; } default: // imposible to get here - AZURE_UNREACHABLE_CODE(); + AZURE_UNREACHABLE_CODE(); // LCOV_EXCL_LINE } } diff --git a/sdk/core/azure-core/src/http/curl/curl.cpp b/sdk/core/azure-core/src/http/curl/curl.cpp index e15aa1569a..3263b8cc5e 100644 --- a/sdk/core/azure-core/src/http/curl/curl.cpp +++ b/sdk/core/azure-core/src/http/curl/curl.cpp @@ -14,6 +14,17 @@ #endif #endif +#include "azure/core/platform.hpp" + +#if defined(AZ_PLATFORM_WINDOWS) +#if !defined(WIN32_LEAN_AND_MEAN) +#define WIN32_LEAN_AND_MEAN +#endif +#if !defined(NOMINMAX) +#define NOMINMAX +#endif +#endif + #include "azure/core/http/curl_transport.hpp" #include "azure/core/http/http.hpp" #include "azure/core/http/policies/policy.hpp" @@ -56,7 +67,7 @@ template #pragma warning(disable : 26812) #endif inline bool SetLibcurlOption( - Azure::Core::Http::_detail::unique_CURL const& handle, + Azure::Core::_internal::UniqueHandle const& handle, CURLoption option, T value, CURLcode* outError) @@ -243,6 +254,48 @@ static void CleanupThread() // Do actual connections release work here, without holding the mutex. } } + +std::string PemEncodeFromBase64(std::string const& base64, std::string const& pemType) +{ + std::stringstream rv; + rv << "-----BEGIN " << pemType << "-----" << std::endl; + std::string encodedValue(base64); + + // Insert crlf characters every 80 characters into the base64 encoded key to make it + // prettier. + size_t insertPos = 80; + while (insertPos < encodedValue.length()) + { + encodedValue.insert(insertPos, "\r\n"); + insertPos += 82; /* 80 characters plus the \r\n we just inserted */ + } + + rv << encodedValue << std::endl << "-----END " << pemType << "-----" << std::endl; + return rv.str(); +} + +Azure::Core::Http::CurlTransportOptions CurlTransportOptionsFromTransportOptions( + Azure::Core::Http::Policies::TransportOptions const& transportOptions) +{ + Azure::Core::Http::CurlTransportOptions curlOptions; + curlOptions.Proxy = transportOptions.HttpProxy; + if (transportOptions.ProxyUserName.HasValue()) + { + curlOptions.ProxyUsername = transportOptions.ProxyUserName; + } + curlOptions.ProxyPassword = transportOptions.ProxyPassword; + + curlOptions.SslOptions.EnableCertificateRevocationListCheck + = transportOptions.EnableCertificateRevocationListCheck; + + if (!transportOptions.ExpectedTlsRootCertificate.empty()) + { + curlOptions.SslOptions.PemEncodedExpectedRootCertificates + = PemEncodeFromBase64(transportOptions.ExpectedTlsRootCertificate, "CERTIFICATE"); + } + return curlOptions; +} + } // namespace using Azure::Core::Context; @@ -260,6 +313,11 @@ using Azure::Core::Http::_detail::CurlConnectionPool; Azure::Core::Http::_detail::CurlConnectionPool Azure::Core::Http::_detail::CurlConnectionPool::g_curlConnectionPool; +CurlTransport::CurlTransport(Azure::Core::Http::Policies::TransportOptions const& options) + : CurlTransport(CurlTransportOptionsFromTransportOptions(options)) +{ +} + std::unique_ptr CurlTransport::Send(Request& request, Context const& context) { // Create CurlSession to perform request @@ -348,15 +406,15 @@ CURLcode CurlSession::Perform(Context const& context) } // If we are using an HTTP proxy, connecting to an HTTP resource and it has been configured with a // username and password, we want to set the proxy authentication header. - if (m_httpProxy.HasValue() && m_request.GetUrl().GetScheme() == "http" && !m_httpProxyUser.empty() - && !m_httpProxyPassword.empty()) + if (m_httpProxy.HasValue() && m_request.GetUrl().GetScheme() == "http" + && m_httpProxyUser.HasValue() && m_httpProxyPassword.HasValue()) { Log::Write(Logger::Level::Verbose, LogMsgPrefix + "Setting proxy authentication header"); this->m_request.SetHeader( "Proxy-Authorization", "Basic " + Azure::Core::_internal::Convert::Base64Encode( - m_httpProxyUser + ":" + m_httpProxyPassword)); + m_httpProxyUser.Value() + ":" + m_httpProxyPassword.Value())); } // use expect:100 for PUT requests. Server will decide if it can take our request @@ -818,7 +876,7 @@ void CurlSession::ReadStatusLineAndHeadersFromRawResponse( auto isTransferEncodingHeaderInResponse = headers.find("transfer-encoding"); if (isTransferEncodingHeaderInResponse != headers.end()) { - auto headerValue = isTransferEncodingHeaderInResponse->second; + auto& headerValue = isTransferEncodingHeaderInResponse->second; auto isChunked = headerValue.find("chunked"); if (isChunked != std::string::npos) @@ -1107,9 +1165,7 @@ size_t CurlSession::ResponseBufferParser::Parse( { // Should never happen that parser is not statusLIne or Headers and we still try // to parse more. - // LCOV_EXCL_START - AZURE_UNREACHABLE_CODE(); - // LCOV_EXCL_STOP + AZURE_UNREACHABLE_CODE(); // LCOV_EXCL_LINE } // clean internal buffer this->m_internalBuffer.clear(); @@ -1147,9 +1203,7 @@ size_t CurlSession::ResponseBufferParser::Parse( { // Should never happen that parser is not statusLIne or Headers and we still try // to parse more. - // LCOV_EXCL_START - AZURE_UNREACHABLE_CODE(); - // LCOV_EXCL_STOP + AZURE_UNREACHABLE_CODE(); // LCOV_EXCL_LINE } } } @@ -1189,11 +1243,13 @@ inline std::string GetConnectionKey(std::string const& host, CurlTransportOption key.append(","); key.append(!options.CAInfo.empty() ? options.CAInfo : "0"); key.append(","); - key.append(options.Proxy ? (options.Proxy->empty() ? "NoProxy" : options.Proxy.Value()) : "0"); + key.append( + options.Proxy.HasValue() ? (options.Proxy.Value().empty() ? "NoProxy" : options.Proxy.Value()) + : "0"); key.append(","); - key.append(options.ProxyUsername.empty() ? "0" : options.ProxyUsername); + key.append(options.ProxyUsername.ValueOr("0")); key.append(","); - key.append(options.ProxyPassword.empty() ? "0" : options.ProxyPassword); + key.append(options.ProxyPassword.ValueOr("0")); key.append(","); key.append(!options.SslOptions.EnableCertificateRevocationListCheck ? "1" : "0"); key.append(","); @@ -1305,423 +1361,416 @@ int CurlConnection::CurlLoggingCallback(CURL*, curl_infotype type, char* data, s } return 0; } -#if !defined(AZ_PLATFORM_WINDOWS) -namespace Azure { namespace Core { namespace Http { - namespace _detail { - // Helpers to provide RAII wrappers for OpenSSL types. - template struct openssl_deleter - { - void operator()(T* obj) { Deleter(obj); } - }; - template - using basic_openssl_unique_ptr = std::unique_ptr>; +// On Windows and macOS, libcurl uses native crypto backends, this functionality depends on +// the OpenSSL backend. +#if !defined(AZ_PLATFORM_WINDOWS) && !defined(AZ_PLATFORM_MAC) +namespace Azure { namespace Core { + namespace _internal { - // *** Given just T, map it to the corresponding FreeFunc: - template struct type_map_helper; - template <> struct type_map_helper + template <> struct UniqueHandleHelper { - using type = basic_openssl_unique_ptr; + using type = BasicUniqueHandle; }; - template <> struct type_map_helper + template <> struct UniqueHandleHelper { - using type = basic_openssl_unique_ptr; + using type = BasicUniqueHandle; }; - template <> struct type_map_helper + template <> struct UniqueHandleHelper { - using type = basic_openssl_unique_ptr; + using type = BasicUniqueHandle; }; - template <> struct type_map_helper + template <> struct UniqueHandleHelper { static void FreeCrlStack(STACK_OF(X509_CRL) * obj) { sk_X509_CRL_pop_free(obj, X509_CRL_free); } - using type = basic_openssl_unique_ptr; + using type = BasicUniqueHandle; }; - // *** Now users can say openssl_unique_ptr if they want: - template using openssl_unique_ptr = typename type_map_helper::type; - - // *** Or the current solution's convenience aliases: - using openssl_bio = openssl_unique_ptr; - using openssl_x509 = openssl_unique_ptr; - using openssl_x509_crl = openssl_unique_ptr; - using openssl_x509_crl_stack = openssl_unique_ptr; - - template - auto make_openssl_unique(Api& OpensslApi, Args&&... args) + template auto MakeUniqueHandle(Api& OpensslApi, Args&&... args) { auto raw = OpensslApi(std::forward( args)...); // forwarding is probably unnecessary, could use const Args&... // check raw using T = std::remove_pointer_t; // no need to request T when we can see // what OpensslApi returned - return openssl_unique_ptr{raw}; + return UniqueHandle{raw}; } - - // Disable Code Coverage across GetOpenSSLError because we don't have a good way of forcing - // OpenSSL to fail. - // LCOV_EXCL_START - std::string GetOpenSSLError(std::string const& what) - { - auto bio(make_openssl_unique(BIO_new, BIO_s_mem())); - - BIO_printf(bio.get(), "Error in %hs: ", what.c_str()); - if (ERR_peek_error() != 0) - { - ERR_print_errors(bio.get()); - } - else + } // namespace _internal + namespace Http { + namespace _detail { + + // Disable Code Coverage across GetOpenSSLError because we don't have a good way of forcing + // OpenSSL to fail. + // LCOV_EXCL_START + std::string GetOpenSSLError(std::string const& what) { - BIO_printf(bio.get(), "Unknown error."); - } - - uint8_t* bioData; - long bufferSize = BIO_get_mem_data(bio.get(), &bioData); - std::string returnValue; - returnValue.resize(bufferSize); - memcpy(&returnValue[0], bioData, bufferSize); + auto bio(Azure::Core::_internal::MakeUniqueHandle(BIO_new, BIO_s_mem())); - return returnValue; - } - // LCOV_EXCL_STOP - - } // namespace _detail + BIO_printf(bio.get(), "Error in %hs: ", what.c_str()); + if (ERR_peek_error() != 0) + { + ERR_print_errors(bio.get()); + } + else + { + BIO_printf(bio.get(), "Unknown error."); + } - namespace { - // int g_ssl_crl_max_size_in_kb = 20; - /** - * @brief THe Cryptography class provides a set of basic cryptographic primatives required - * by the attestation samples. - */ + uint8_t* bioData; + long bufferSize = BIO_get_mem_data(bio.get(), &bioData); + std::string returnValue; + returnValue.resize(bufferSize); + memcpy(&returnValue[0], bioData, bufferSize); - _detail::openssl_x509_crl LoadCrlFromUrl(std::string const& url) - { - Log::Write(Logger::Level::Informational, "Load CRL from Url: " + url); - auto crl = _detail::make_openssl_unique(X509_CRL_load_http, url.c_str(), nullptr, nullptr, 5); - if (!crl) - { - Log::Write(Logger::Level::Error, _detail::GetOpenSSLError("Load CRL")); + return returnValue; } + // LCOV_EXCL_STOP - return crl; - } - - enum class CrlFormat : int - { - Http, - Asn1, - PEM, - }; + } // namespace _detail - _detail::openssl_x509_crl LoadCrl(std::string const& source, CrlFormat format) - { - _detail::openssl_x509_crl x; - _detail::openssl_bio in; + namespace { + // int g_ssl_crl_max_size_in_kb = 20; + /** + * @brief THe Cryptography class provides a set of basic cryptographic primatives required + * by the attestation samples. + */ - if (format == CrlFormat::Http) + Azure::Core::_internal::UniqueHandle LoadCrlFromUrl(std::string const& url) { - return LoadCrlFromUrl(source); - } - return x; - } + Log::Write(Logger::Level::Informational, "Load CRL from Url: " + url); + auto crl = Azure::Core::_internal::MakeUniqueHandle( + X509_CRL_load_http, url.c_str(), nullptr, nullptr, 5); + if (!crl) + { + Log::Write(Logger::Level::Error, _detail::GetOpenSSLError("Load CRL")); + } - bool IsCrlValid(X509_CRL* crl) - { - const ASN1_TIME* at = X509_CRL_get0_nextUpdate(crl); + return crl; + } - int day = -1; - int sec = -1; - if (!ASN1_TIME_diff(&day, &sec, nullptr, at)) + enum class CrlFormat : int + { + Http, + Asn1, + PEM, + }; + + Azure::Core::_internal::UniqueHandle LoadCrl( + std::string const& source, + CrlFormat format) { - Log::Write(Logger::Level::Error, "Could not check expiration"); - return false; /* Safe default, invalid */ + Azure::Core::_internal::UniqueHandle x; + Azure::Core::_internal::UniqueHandle in; + + if (format == CrlFormat::Http) + { + return LoadCrlFromUrl(source); + } + return x; } - if (day > 0 || sec > 0) + bool IsCrlValid(X509_CRL* crl) { - return true; /* Later, valid */ - } - return false; /* Before or same, invalid */ - } + const ASN1_TIME* at = X509_CRL_get0_nextUpdate(crl); - const char* GetDistributionPointUrl(DIST_POINT* dp) - { - GENERAL_NAMES* gens; - GENERAL_NAME* gen; - int i, nameType; - ASN1_STRING* uri; + int day = -1; + int sec = -1; + if (!ASN1_TIME_diff(&day, &sec, nullptr, at)) + { + Log::Write(Logger::Level::Error, "Could not check expiration"); + return false; /* Safe default, invalid */ + } - if (!dp->distpoint) - { - Log::Write(Logger::Level::Informational, "returning, dp->distpoint is null"); - return nullptr; + if (day > 0 || sec > 0) + { + return true; /* Later, valid */ + } + return false; /* Before or same, invalid */ } - if (dp->distpoint->type != 0) + const char* GetDistributionPointUrl(DIST_POINT* dp) { - Log::Write( - Logger::Level::Informational, - "returning, dp->distpoint->type is " + std::to_string(dp->distpoint->type)); - return nullptr; - } + GENERAL_NAMES* gens; + GENERAL_NAME* gen; + int i, nameType; + ASN1_STRING* uri; - gens = dp->distpoint->name.fullname; + if (!dp->distpoint) + { + Log::Write(Logger::Level::Informational, "returning, dp->distpoint is null"); + return nullptr; + } - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) - { - gen = sk_GENERAL_NAME_value(gens, i); - uri = static_cast(GENERAL_NAME_get0_value(gen, &nameType)); + if (dp->distpoint->type != 0) + { + Log::Write( + Logger::Level::Informational, + "returning, dp->distpoint->type is " + std::to_string(dp->distpoint->type)); + return nullptr; + } - if (nameType == GEN_URI && ASN1_STRING_length(uri) > 6) + gens = dp->distpoint->name.fullname; + + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - const char* uptr = reinterpret_cast(ASN1_STRING_get0_data(uri)); - if (strncmp(uptr, "http://", 7) == 0) + gen = sk_GENERAL_NAME_value(gens, i); + uri = static_cast(GENERAL_NAME_get0_value(gen, &nameType)); + + if (nameType == GEN_URI && ASN1_STRING_length(uri) > 6) { - return uptr; + const char* uptr = reinterpret_cast(ASN1_STRING_get0_data(uri)); + if (strncmp(uptr, "http://", 7) == 0) + { + return uptr; + } } } - } - return nullptr; - } - - std::mutex crl_cache_lock; - std::vector crl_cache; + return nullptr; + } - bool SaveCertificateCrlToMemory(X509* cert, _detail::openssl_x509_crl const& crl) - { - std::unique_lock lockResult(crl_cache_lock); + std::mutex crl_cache_lock; + std::vector crl_cache; - // update existing - X509_NAME* cert_issuer = cert ? X509_get_issuer_name(cert) : nullptr; - for (auto it = crl_cache.begin(); it != crl_cache.end(); ++it) + bool SaveCertificateCrlToMemory( + X509* cert, + Azure::Core::_internal::UniqueHandle const& crl) { - X509_CRL* cacheEntry = *it; - if (!cacheEntry) - { - continue; - } + std::unique_lock lockResult(crl_cache_lock); - X509_NAME* crl_issuer = X509_CRL_get_issuer(cacheEntry); - if (!crl_issuer || !cert_issuer) + // update existing + X509_NAME* cert_issuer = cert ? X509_get_issuer_name(cert) : nullptr; + for (auto it = crl_cache.begin(); it != crl_cache.end(); ++it) { - continue; + X509_CRL* cacheEntry = *it; + if (!cacheEntry) + { + continue; + } + + X509_NAME* crl_issuer = X509_CRL_get_issuer(cacheEntry); + if (!crl_issuer || !cert_issuer) + { + continue; + } + + // If we are getting a new CRL for an existing CRL, update the + // CRL with the new CRL. + if (0 == X509_NAME_cmp(crl_issuer, cert_issuer)) + { + // Bump the refcount on the new CRL before adding it to the cache. + X509_CRL_free(*it); + X509_CRL_up_ref(crl.get()); + *it = crl.get(); + return true; + } } - // If we are getting a new CRL for an existing CRL, update the - // CRL with the new CRL. - if (0 == X509_NAME_cmp(crl_issuer, cert_issuer)) + // not found, so try to find slot by purging outdated + for (auto it = crl_cache.begin(); it != crl_cache.end(); ++it) { - // Bump the refcount on the new CRL before adding it to the cache. - X509_CRL_free(*it); - X509_CRL_up_ref(crl.get()); - *it = crl.get(); - return true; + if (!*it) + { + // set new + X509_CRL_free(*it); + X509_CRL_up_ref(crl.get()); + *it = crl.get(); + return true; + } + + if (!IsCrlValid(*it)) + { + // remove stale + X509_CRL_free(*it); + X509_CRL_up_ref(crl.get()); + *it = crl.get(); + return true; + } } + + // Clone the certificate and add it to the cache. + X509_CRL_up_ref(crl.get()); + crl_cache.push_back(crl.get()); + return true; } - // not found, so try to find slot by purging outdated - for (auto it = crl_cache.begin(); it != crl_cache.end(); ++it) + Azure::Core::_internal::UniqueHandle LoadCertificateCrlFromMemory(X509* cert) { - if (!*it) - { - // set new - X509_CRL_free(*it); - X509_CRL_up_ref(crl.get()); - *it = crl.get(); - return true; - } + X509_NAME* cert_issuer = cert ? X509_get_issuer_name(cert) : nullptr; - if (!IsCrlValid(*it)) + std::unique_lock lockResult(crl_cache_lock); + + for (auto it = crl_cache.begin(); it != crl_cache.end(); ++it) { - // remove stale - X509_CRL_free(*it); - X509_CRL_up_ref(crl.get()); - *it = crl.get(); - return true; - } - } + X509_CRL* crl = *it; + if (!*it) + { + continue; + } - // Clone the certificate and add it to the cache. - X509_CRL_up_ref(crl.get()); - crl_cache.push_back(crl.get()); - return true; - } + // names don't match up. probably a hash collision + // so lets test if there is another crl on disk. + X509_NAME* crl_issuer = X509_CRL_get_issuer(crl); + if (!crl_issuer || !cert_issuer) + { + continue; + } - _detail::openssl_x509_crl LoadCertificateCrlFromMemory(X509* cert) - { - X509_NAME* cert_issuer = cert ? X509_get_issuer_name(cert) : nullptr; + if (0 != X509_NAME_cmp(crl_issuer, cert_issuer)) + { + continue; + } + + if (!IsCrlValid(crl)) + { + Log::Write(Logger::Level::Informational, "Discarding outdated CRL"); + X509_CRL_free(*it); + *it = nullptr; + continue; + } - std::unique_lock lockResult(crl_cache_lock); + X509_CRL_up_ref(crl); + return Azure::Core::_internal::UniqueHandle(crl); + } + return nullptr; + } - for (auto it = crl_cache.begin(); it != crl_cache.end(); ++it) + Azure::Core::_internal::UniqueHandle LoadCrlFromCacheAndDistributionPoint( + X509* cert, + STACK_OF(DIST_POINT) * crlDistributionPointStack) { - X509_CRL* crl = *it; - if (!*it) + int i; + + Azure::Core::_internal::UniqueHandle crl = LoadCertificateCrlFromMemory(cert); + if (crl) { - continue; + return crl; } - // names don't match up. probably a hash collision - // so lets test if there is another crl on disk. - X509_NAME* crl_issuer = X509_CRL_get_issuer(crl); - if (!crl_issuer || !cert_issuer) + // file was not found on disk cache, + // so, now loading from web. + // Walk through the possible CRL distribution points + // looking for one which has a URL that we can download. + const char* urlptr = nullptr; + for (i = 0; i < sk_DIST_POINT_num(crlDistributionPointStack); i++) { - continue; + DIST_POINT* dp = sk_DIST_POINT_value(crlDistributionPointStack, i); + + urlptr = GetDistributionPointUrl(dp); + if (urlptr) + { + // try to load from web, exit loop if + // successfully downloaded + crl = LoadCrl(urlptr, CrlFormat::Http); + if (crl) + break; + } } - if (0 != X509_NAME_cmp(crl_issuer, cert_issuer)) + if (!urlptr) { - continue; + Log::Write(Logger::Level::Error, "No CRL dist point qualified for downloading."); } - if (!IsCrlValid(crl)) + if (crl) { - Log::Write(Logger::Level::Informational, "Discarding outdated CRL"); - X509_CRL_free(*it); - *it = nullptr; - continue; + // save it to memory + SaveCertificateCrlToMemory(cert, crl); } - X509_CRL_up_ref(crl); - return _detail::openssl_x509_crl(crl); - } - return nullptr; - } - - _detail::openssl_x509_crl LoadCrlFromCacheAndDistributionPoint( - X509* cert, - STACK_OF(DIST_POINT) * crlDistributionPointStack) - { - int i; - - _detail::openssl_x509_crl crl = LoadCertificateCrlFromMemory(cert); - if (crl) - { return crl; } - // file was not found on disk cache, - // so, now loading from web. - // Walk through the possible CRL distribution points - // looking for one which has a URL that we can download. - const char* urlptr = nullptr; - for (i = 0; i < sk_DIST_POINT_num(crlDistributionPointStack); i++) + /** + * @brief Retrieve the CRL associated with the provided store context, if available. + * + */ + STACK_OF(X509_CRL) * CrlHttpCallback(const X509_STORE_CTX* context, const X509_NAME*) { - DIST_POINT* dp = sk_DIST_POINT_value(crlDistributionPointStack, i); + Azure::Core::_internal::UniqueHandle crl; + STACK_OF(DIST_POINT) * crlDistributionPoint; - urlptr = GetDistributionPointUrl(dp); - if (urlptr) + Azure::Core::_internal::UniqueHandle crlStack + = Azure::Core::_internal::UniqueHandle(sk_X509_CRL_new_null()); + if (crlStack == nullptr) { - // try to load from web, exit loop if - // successfully downloaded - crl = LoadCrl(urlptr, CrlFormat::Http); - if (crl) - break; + Log::Write(Logger::Level::Error, "Failed to allocate STACK_OF(X509_CRL)"); + return nullptr; } - } - - if (!urlptr) - { - Log::Write(Logger::Level::Error, "No CRL dist point qualified for downloading."); - } - if (crl) - { - // save it to memory - SaveCertificateCrlToMemory(cert, crl); - } + X509* currentCertificate = X509_STORE_CTX_get_current_cert(context); - return crl; - } + // try to download Crl + crlDistributionPoint = static_cast( + X509_get_ext_d2i(currentCertificate, NID_crl_distribution_points, nullptr, nullptr)); + if (!crlDistributionPoint + && X509_NAME_cmp( + X509_get_issuer_name(currentCertificate), + X509_get_subject_name(currentCertificate)) + != 0) + { + Log::Write( + Logger::Level::Error, + "No CRL distribution points defined on non self-issued cert, CRL check may fail."); + return nullptr; + } - /** - * @brief Retrieve the CRL associated with the provided store context, if available. - * - */ - STACK_OF(X509_CRL) * CrlHttpCallback(const X509_STORE_CTX* context, const X509_NAME*) - { - _detail::openssl_x509_crl crl; - STACK_OF(DIST_POINT) * crlDistributionPoint; + crl = LoadCrlFromCacheAndDistributionPoint(currentCertificate, crlDistributionPoint); - _detail::openssl_x509_crl_stack crlStack - = _detail::openssl_x509_crl_stack(sk_X509_CRL_new_null()); - if (crlStack == nullptr) - { - Log::Write(Logger::Level::Error, "Failed to allocate STACK_OF(X509_CRL)"); - return nullptr; - } + sk_DIST_POINT_pop_free(crlDistributionPoint, DIST_POINT_free); + if (!crl) + { + Log::Write(Logger::Level::Error, "Unable to retrieve CRL, CRL check may fail."); + return nullptr; + } - X509* currentCertificate = X509_STORE_CTX_get_current_cert(context); + sk_X509_CRL_push(crlStack.get(), X509_CRL_dup(crl.get())); - // try to download Crl - crlDistributionPoint = static_cast( - X509_get_ext_d2i(currentCertificate, NID_crl_distribution_points, nullptr, nullptr)); - if (!crlDistributionPoint - && X509_NAME_cmp( - X509_get_issuer_name(currentCertificate), - X509_get_subject_name(currentCertificate)) - != 0) - { - Log::Write( - Logger::Level::Error, - "No CRL distribution points defined on non self-issued cert, CRL check may fail."); - return nullptr; - } + // try to download delta Crl + crlDistributionPoint = static_cast( + X509_get_ext_d2i(currentCertificate, NID_freshest_crl, nullptr, nullptr)); + if (crlDistributionPoint != nullptr) + { + crl = LoadCrlFromCacheAndDistributionPoint(currentCertificate, crlDistributionPoint); - crl = LoadCrlFromCacheAndDistributionPoint(currentCertificate, crlDistributionPoint); + sk_DIST_POINT_pop_free(crlDistributionPoint, DIST_POINT_free); + if (crl) + { + sk_X509_CRL_push(crlStack.get(), X509_CRL_dup(crl.get())); + } + } - sk_DIST_POINT_pop_free(crlDistributionPoint, DIST_POINT_free); - if (!crl) - { - Log::Write(Logger::Level::Error, "Unable to retrieve CRL, CRL check may fail."); - return nullptr; + return crlStack.release(); } - sk_X509_CRL_push(crlStack.get(), X509_CRL_dup(crl.get())); - - // try to download delta Crl - crlDistributionPoint = static_cast( - X509_get_ext_d2i(currentCertificate, NID_freshest_crl, nullptr, nullptr)); - if (crlDistributionPoint != nullptr) + int GetOpenSSLContextConnectionIndex() { - crl = LoadCrlFromCacheAndDistributionPoint(currentCertificate, crlDistributionPoint); - - sk_DIST_POINT_pop_free(crlDistributionPoint, DIST_POINT_free); - if (crl) + static int openSslConnectionIndex = -1; + if (openSslConnectionIndex < 0) { - sk_X509_CRL_push(crlStack.get(), X509_CRL_dup(crl.get())); + openSslConnectionIndex + = X509_STORE_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr); } + return openSslConnectionIndex; } - - return crlStack.release(); - } - - int GetOpenSSLContextConnectionIndex() - { - static int openSslConnectionIndex = -1; - if (openSslConnectionIndex < 0) - { - openSslConnectionIndex = X509_STORE_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr); - } - return openSslConnectionIndex; - } - int GetOpenSSLContextLastVerifyFunction() - { - static int openSslLastVerifyFunctionIndex = -1; - if (openSslLastVerifyFunctionIndex < 0) + int GetOpenSSLContextLastVerifyFunction() { - openSslLastVerifyFunctionIndex - = X509_STORE_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr); + static int openSslLastVerifyFunctionIndex = -1; + if (openSslLastVerifyFunctionIndex < 0) + { + openSslLastVerifyFunctionIndex + = X509_STORE_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr); + } + return openSslLastVerifyFunctionIndex; } - return openSslLastVerifyFunctionIndex; - } - } // namespace -}}} // namespace Azure::Core::Http + } // namespace + } // namespace Http +}} // namespace Azure::Core // OpenSSL X509 Certificate Validation function - based off of the example found at: // https://linux.die.net/man/3/x509_store_ctx_set_verify_cb @@ -1731,7 +1780,8 @@ int CurlConnection::VerifyCertificateError(int ok, X509_STORE_CTX* storeContext) X509_STORE* certStore = X509_STORE_CTX_get0_store(storeContext); X509* err_cert; int err, depth; - _detail::openssl_bio bio_err(_detail::make_openssl_unique(BIO_new, BIO_s_mem())); + Azure::Core::_internal::UniqueHandle bio_err( + Azure::Core::_internal::MakeUniqueHandle(BIO_new, BIO_s_mem())); err_cert = X509_STORE_CTX_get_current_cert(storeContext); err = X509_STORE_CTX_get_error(storeContext); @@ -1989,9 +2039,9 @@ CurlConnection::CurlConnection( CurlTransportOptions const& options, std::string const& hostDisplayName, std::string const& connectionPropertiesKey) - : m_connectionKey(std::move(connectionPropertiesKey)) + : m_connectionKey(connectionPropertiesKey) { - m_handle = _detail::unique_CURL(curl_easy_init(), _detail::CURL_deleter{}); + m_handle = Azure::Core::_internal::UniqueHandle(curl_easy_init()); if (!m_handle) { throw Azure::Core::Http::TransportException( @@ -2078,23 +2128,25 @@ CurlConnection::CurlConnection( } } - if (!options.ProxyUsername.empty()) + if (options.ProxyUsername.HasValue()) { - if (!SetLibcurlOption(m_handle, CURLOPT_PROXYUSERNAME, options.ProxyUsername.c_str(), &result)) + if (!SetLibcurlOption( + m_handle, CURLOPT_PROXYUSERNAME, options.ProxyUsername.Value().c_str(), &result)) { throw TransportException( _detail::DefaultFailedToGetNewConnectionTemplate + hostDisplayName - + ". Failed to set proxy username to:" + options.ProxyUsername + ". " + + ". Failed to set proxy username to:" + options.ProxyUsername.Value() + ". " + std::string(curl_easy_strerror(result))); } } - if (!options.ProxyPassword.empty()) + if (options.ProxyPassword.HasValue()) { - if (!SetLibcurlOption(m_handle, CURLOPT_PROXYPASSWORD, options.ProxyPassword.c_str(), &result)) + if (!SetLibcurlOption( + m_handle, CURLOPT_PROXYPASSWORD, options.ProxyPassword.Value().c_str(), &result)) { throw TransportException( _detail::DefaultFailedToGetNewConnectionTemplate + hostDisplayName - + ". Failed to set proxy password to:" + options.ProxyPassword + ". " + + ". Failed to set proxy password to:" + options.ProxyPassword.Value() + ". " + std::string(curl_easy_strerror(result))); } } diff --git a/sdk/core/azure-core/src/http/curl/curl_connection_private.hpp b/sdk/core/azure-core/src/http/curl/curl_connection_private.hpp index ccf1b217b5..019dea9e77 100644 --- a/sdk/core/azure-core/src/http/curl/curl_connection_private.hpp +++ b/sdk/core/azure-core/src/http/curl/curl_connection_private.hpp @@ -10,6 +10,7 @@ #pragma once #include "azure/core/http/http.hpp" +#include "azure/core/internal/unique_handle.hpp" #include #include @@ -25,207 +26,212 @@ #pragma warning(pop) #endif +// Stolen from openssl/x509.h to avoid having to include openssl headers typedef struct x509_store_ctx_st X509_STORE_CTX; -namespace Azure { namespace Core { namespace Http { - - namespace _detail { - // libcurl CURL_MAX_WRITE_SIZE is 64k. Using same value for default uploading chunk size. - // This can be customizable in the HttpRequest - constexpr static size_t DefaultUploadChunkSize = 1024 * 64; - constexpr static size_t DefaultLibcurlReaderSize = 1024; - // Run time error template - constexpr static const char* DefaultFailedToGetNewConnectionTemplate - = "Fail to get a new connection for: "; - constexpr static int32_t DefaultMaxOpenNewConnectionIntentsAllowed = 10; - // After 3 connections are received from the pool and failed to send a request, the next - // connections would ask the pool to be clean and spawn new connection. - constexpr static int32_t RequestPoolResetAfterConnectionFailed = 3; - // 90 sec -> cleaner wait time before next clean routine - constexpr static int32_t DefaultCleanerIntervalMilliseconds = 1000 * 90; - // 60 sec -> expired connection is when it waits for 60 sec or more and it's not re-used - constexpr static int32_t DefaultConnectionExpiredMilliseconds = 1000 * 60; - // Define the maximun allowed connections per host-index in the pool. If this number is reached - // for the host-index, next connections trying to be added to the pool will be ignored. - constexpr static int32_t MaxConnectionsPerIndex = 1024; - - /** - * @brief std::default_delete for the CURL * type , used for std::unique_ptr - * - */ - class CURL_deleter { - public: - void operator()(CURL* handle) noexcept - { - if (handle != nullptr) - { - curl_easy_cleanup(handle); - } - } - }; - using unique_CURL = std::unique_ptr; - - } // namespace _detail - - /** - * @brief Interface for the connection to the network with Curl. - * - * @remark This interface enables to mock the communication to the network with any behavior for - * testing. - * - */ - class CurlNetworkConnection { - private: - bool m_isShutDown = false; - - public: - /** - * @brief Allow derived classes calling a destructor. - * - */ - virtual ~CurlNetworkConnection() = default; - - /** - * @brief Get the Connection Properties Key object - * - */ - virtual std::string const& GetConnectionKey() const = 0; - - /** - * @brief Update last usage time for the connection. - * - */ - virtual void UpdateLastUsageTime() = 0; - +namespace Azure { namespace Core { + namespace _internal { /** - * @brief Checks whether this CURL connection is expired. + * @brief Unique handle for WinHTTP HINTERNET handles. * - */ - virtual bool IsExpired() = 0; - - /** - * @brief This function is used when working with streams to pull more data from the wire. - * Function will try to keep pulling data from socket until the buffer is all written or until - * there is no more data to get from the socket. + * @note HINTERNET is declared as a "void *". THis means that this definition subsumes all other + * `void *` types when used with Azure::Core::_internal::UniqueHandle. * */ - virtual size_t ReadFromSocket(uint8_t* buffer, size_t bufferSize, Context const& context) = 0; - - /** - * @brief This method will use libcurl socket to write all the bytes from buffer. - * - */ - virtual CURLcode SendBuffer(uint8_t const* buffer, size_t bufferSize, Context const& context) - = 0; - - /** - * @brief Set the connection into an invalid and unusable state. - * - * @remark A connection won't be returned to the connection pool if it was shut it down. - * - */ - virtual void Shutdown() { m_isShutDown = true; } + template <> struct UniqueHandleHelper + { + using type = BasicUniqueHandle; + }; + } // namespace _internal + + namespace Http { + namespace _detail { + // libcurl CURL_MAX_WRITE_SIZE is 64k. Using same value for default uploading chunk size. + // This can be customizable in the HttpRequest + constexpr static size_t DefaultUploadChunkSize = 1024 * 64; + constexpr static size_t DefaultLibcurlReaderSize = 4 * 1024; + // Run time error template + constexpr static const char* DefaultFailedToGetNewConnectionTemplate + = "Fail to get a new connection for: "; + constexpr static int32_t DefaultMaxOpenNewConnectionIntentsAllowed = 10; + // After 3 connections are received from the pool and failed to send a request, the next + // connections would ask the pool to be clean and spawn new connection. + constexpr static int32_t RequestPoolResetAfterConnectionFailed = 3; + // 90 sec -> cleaner wait time before next clean routine + constexpr static int32_t DefaultCleanerIntervalMilliseconds = 1000 * 90; + // 60 sec -> expired connection is when it waits for 60 sec or more and it's not re-used + constexpr static int32_t DefaultConnectionExpiredMilliseconds = 1000 * 60; + // Define the maximun allowed connections per host-index in the pool. If this number is + // reached for the host-index, next connections trying to be added to the pool will be + // ignored. + constexpr static int32_t MaxConnectionsPerIndex = 1024; + + } // namespace _detail /** - * @brief Check if the the connection was shut it down. + * @brief Interface for the connection to the network with Curl. * - * @return `true` is the connection was shut it down; otherwise, `false`. - */ - bool IsShutdown() const { return m_isShutDown; } - }; - - /** - * @brief CURL HTTP connection. - * - */ - class CurlConnection final : public CurlNetworkConnection { - private: - _detail::unique_CURL m_handle; - curl_socket_t m_curlSocket; - std::chrono::steady_clock::time_point m_lastUseTime; - std::string m_connectionKey; - // CRL validation is disabled by default to be consistent with WinHTTP behavior - bool m_enableCrlValidation{false}; - // Allow the connection to proceed if retrieving the CRL failed. - bool m_allowFailedCrlRetrieval{true}; - - static int CurlLoggingCallback( - CURL* handle, - curl_infotype type, - char* data, - size_t size, - void* userp); - - static int CurlSslCtxCallback(CURL* curl, void* sslctx, void* parm); - int SslCtxCallback(CURL* curl, void* sslctx); - int VerifyCertificateError(int ok, X509_STORE_CTX* storeContext); - - public: - /** - * @brief Construct CURL HTTP connection. + * @remark This interface enables to mock the communication to the network with any behavior for + * testing. * - * @param request Remote request - * @param options Connection options. - * @param hostDisplayName Display name for remote host, used for diagnostics. - * - * @param connectionPropertiesKey CURL connection properties key */ - CurlConnection( - Azure::Core::Http::Request& request, - Azure::Core::Http::CurlTransportOptions const& options, - std::string const& hostDisplayName, - std::string const& connectionPropertiesKey); + class CurlNetworkConnection { + private: + bool m_isShutDown = false; - /** - * @brief Destructor. - * @details Cleans up CURL (invokes `curl_easy_cleanup()`). - */ - ~CurlConnection() override {} - - std::string const& GetConnectionKey() const override { return this->m_connectionKey; } + public: + /** + * @brief Allow derived classes calling a destructor. + * + */ + virtual ~CurlNetworkConnection() = default; + + /** + * @brief Get the Connection Properties Key object + * + */ + virtual std::string const& GetConnectionKey() const = 0; + + /** + * @brief Update last usage time for the connection. + * + */ + virtual void UpdateLastUsageTime() = 0; + + /** + * @brief Checks whether this CURL connection is expired. + * + */ + virtual bool IsExpired() = 0; + + /** + * @brief This function is used when working with streams to pull more data from the wire. + * Function will try to keep pulling data from socket until the buffer is all written or until + * there is no more data to get from the socket. + * + */ + virtual size_t ReadFromSocket(uint8_t* buffer, size_t bufferSize, Context const& context) = 0; + + /** + * @brief This method will use libcurl socket to write all the bytes from buffer. + * + */ + virtual CURLcode SendBuffer(uint8_t const* buffer, size_t bufferSize, Context const& context) + = 0; + + /** + * @brief Set the connection into an invalid and unusable state. + * + * @remark A connection won't be returned to the connection pool if it was shut it down. + * + */ + virtual void Shutdown() { m_isShutDown = true; } + + /** + * @brief Check if the the connection was shut it down. + * + * @return `true` is the connection was shut it down; otherwise, `false`. + */ + bool IsShutdown() const { return m_isShutDown; } + }; /** - * @brief Update last usage time for the connection. + * @brief CURL HTTP connection. * */ - void UpdateLastUsageTime() override { this->m_lastUseTime = std::chrono::steady_clock::now(); } + class CurlConnection final : public CurlNetworkConnection { + private: + Azure::Core::_internal::UniqueHandle m_handle; + curl_socket_t m_curlSocket; + std::chrono::steady_clock::time_point m_lastUseTime; + std::string m_connectionKey; + // CRL validation is disabled by default to be consistent with WinHTTP behavior + bool m_enableCrlValidation{false}; + // Allow the connection to proceed if retrieving the CRL failed. + bool m_allowFailedCrlRetrieval{true}; + + static int CurlLoggingCallback( + CURL* handle, + curl_infotype type, + char* data, + size_t size, + void* userp); + + static int CurlSslCtxCallback(CURL* curl, void* sslctx, void* parm); + int SslCtxCallback(CURL* curl, void* sslctx); + int VerifyCertificateError(int ok, X509_STORE_CTX* storeContext); - /** - * @brief Checks whether this CURL connection is expired. - * @return `true` if this connection is considered expired; otherwise, `false`. - */ - bool IsExpired() override - { - auto connectionOnWaitingTimeMs = std::chrono::duration_cast( - std::chrono::steady_clock::now() - this->m_lastUseTime); - return connectionOnWaitingTimeMs.count() >= _detail::DefaultConnectionExpiredMilliseconds; - } - - /** - * @brief This function is used when working with streams to pull more data from the wire. - * Function will try to keep pulling data from socket until the buffer is all written or until - * there is no more data to get from the socket. - * - * @param context A context to control the request lifetime. - * @param buffer ptr to buffer where to copy bytes from socket. - * @param bufferSize size of the buffer and the requested bytes to be pulled from wire. - * @return return the numbers of bytes pulled from socket. It can be less than what it was - * requested. - */ - size_t ReadFromSocket(uint8_t* buffer, size_t bufferSize, Context const& context) override; + public: + /** + * @brief Construct CURL HTTP connection. + * + * @param request Remote request + * @param options Connection options. + * @param hostDisplayName Display name for remote host, used for diagnostics. + * + * @param connectionPropertiesKey CURL connection properties key + */ + CurlConnection( + Azure::Core::Http::Request& request, + Azure::Core::Http::CurlTransportOptions const& options, + std::string const& hostDisplayName, + std::string const& connectionPropertiesKey); + + /** + * @brief Destructor. + * @details Cleans up CURL (invokes `curl_easy_cleanup()`). + */ + ~CurlConnection() override {} + + std::string const& GetConnectionKey() const override { return this->m_connectionKey; } + + /** + * @brief Update last usage time for the connection. + * + */ + void UpdateLastUsageTime() override + { + this->m_lastUseTime = std::chrono::steady_clock::now(); + } - /** - * @brief This method will use libcurl socket to write all the bytes from buffer. - * - * @remarks Hardcoded timeout is used in case a socket stop responding. - * - * @param context A context to control the request lifetime. - * @param buffer ptr to the data to be sent to wire. - * @param bufferSize size of the buffer to send. - * @return CURL_OK when response is sent successfully. - */ - CURLcode SendBuffer(uint8_t const* buffer, size_t bufferSize, Context const& context) override; + /** + * @brief Checks whether this CURL connection is expired. + * @return `true` if this connection is considered expired; otherwise, `false`. + */ + bool IsExpired() override + { + auto connectionOnWaitingTimeMs = std::chrono::duration_cast( + std::chrono::steady_clock::now() - this->m_lastUseTime); + return connectionOnWaitingTimeMs.count() >= _detail::DefaultConnectionExpiredMilliseconds; + } - void Shutdown() override; - }; -}}} // namespace Azure::Core::Http + /** + * @brief This function is used when working with streams to pull more data from the wire. + * Function will try to keep pulling data from socket until the buffer is all written or until + * there is no more data to get from the socket. + * + * @param context A context to control the request lifetime. + * @param buffer ptr to buffer where to copy bytes from socket. + * @param bufferSize size of the buffer and the requested bytes to be pulled from wire. + * @return return the numbers of bytes pulled from socket. It can be less than what it was + * requested. + */ + size_t ReadFromSocket(uint8_t* buffer, size_t bufferSize, Context const& context) override; + + /** + * @brief This method will use libcurl socket to write all the bytes from buffer. + * + * @remarks Hardcoded timeout is used in case a socket stop responding. + * + * @param context A context to control the request lifetime. + * @param buffer ptr to the data to be sent to wire. + * @param bufferSize size of the buffer to send. + * @return CURL_OK when response is sent successfully. + */ + CURLcode SendBuffer(uint8_t const* buffer, size_t bufferSize, Context const& context) + override; + + void Shutdown() override; + }; + } // namespace Http +}} // namespace Azure::Core diff --git a/sdk/core/azure-core/src/http/curl/curl_session_private.hpp b/sdk/core/azure-core/src/http/curl/curl_session_private.hpp index fb805080fb..1d8d1ae7d4 100644 --- a/sdk/core/azure-core/src/http/curl/curl_session_private.hpp +++ b/sdk/core/azure-core/src/http/curl/curl_session_private.hpp @@ -365,8 +365,8 @@ namespace Azure { namespace Core { namespace Http { bool m_keepAlive = true; Azure::Nullable m_httpProxy; - std::string m_httpProxyUser; - std::string m_httpProxyPassword; + Azure::Nullable m_httpProxyUser; + Azure::Nullable m_httpProxyPassword; /** * @brief Implement #Azure::Core::IO::BodyStream::OnRead(). Calling this function pulls data diff --git a/sdk/core/azure-core/src/http/transport_policy.cpp b/sdk/core/azure-core/src/http/transport_policy.cpp index f2d9e4eec8..ec90e0253c 100644 --- a/sdk/core/azure-core/src/http/transport_policy.cpp +++ b/sdk/core/azure-core/src/http/transport_policy.cpp @@ -23,33 +23,17 @@ using namespace Azure::Core::Http::Policies::_internal; namespace Azure { namespace Core { namespace Http { namespace Policies { namespace _detail { namespace { - bool AnyTransportOptionsSpecified(TransportOptions const& transportOptions) + /** + * @brief Returns "true" if any specific transport options have been specified. + */ + bool AreAnyTransportOptionsSpecified(TransportOptions const& transportOptions) { return ( - transportOptions.HttpProxy.HasValue() || !transportOptions.ProxyPassword.empty() - || !transportOptions.ProxyUserName.empty() + transportOptions.HttpProxy.HasValue() || transportOptions.ProxyPassword.HasValue() + || transportOptions.ProxyUserName.HasValue() || transportOptions.EnableCertificateRevocationListCheck || !transportOptions.ExpectedTlsRootCertificate.empty()); } - - std::string PemEncodeFromBase64(std::string const& base64, std::string const& pemType) - { - std::stringstream rv; - rv << "-----BEGIN " << pemType << "-----" << std::endl; - std::string encodedValue(base64); - - // Insert crlf characters every 80 characters into the base64 encoded key to make it - // prettier. - size_t insertPos = 80; - while (insertPos < encodedValue.length()) - { - encodedValue.insert(insertPos, "\r\n"); - insertPos += 82; /* 80 characters plus the \r\n we just inserted */ - } - - rv << encodedValue << std::endl << "-----END " << pemType << "-----" << std::endl; - return rv.str(); - } } // namespace std::shared_ptr GetTransportAdapter(TransportOptions const& transportOptions) @@ -63,41 +47,9 @@ namespace Azure { namespace Core { namespace Http { namespace Policies { namespa // concurrently, the initialization occurs exactly once. We depend on this behavior to ensure // that the singleton defaultTransport is correctly initialized. static std::shared_ptr defaultTransport(std::make_shared()); - if (AnyTransportOptionsSpecified(transportOptions)) + if (AreAnyTransportOptionsSpecified(transportOptions)) { - WinHttpTransportOptions httpOptions; - if (transportOptions.HttpProxy.HasValue()) - { - // WinHTTP proxy strings are semicolon separated elements, each of which - // has the following format: - // ([=]["://"][":"]) - std::string proxyString; - proxyString = "http=" + transportOptions.HttpProxy.Value(); - proxyString += ";"; - proxyString += "https=" + transportOptions.HttpProxy.Value(); - httpOptions.ProxyInformation = proxyString; - } - httpOptions.ProxyUserName = transportOptions.ProxyUserName; - httpOptions.ProxyPassword = transportOptions.ProxyPassword; - // Note that WinHTTP accepts a set of root certificates, even though transportOptions only - // specifies a single one. - if (!transportOptions.ExpectedTlsRootCertificate.empty()) - { - httpOptions.ExpectedTlsRootCertificates.push_back( - transportOptions.ExpectedTlsRootCertificate); - } - if (transportOptions.EnableCertificateRevocationListCheck) - { - httpOptions.EnableCertificateRevocationListCheck; - } - // If you specify an expected TLS root certificate, you also need to enable ignoring unknown - // CAs. - if (!transportOptions.ExpectedTlsRootCertificate.empty()) - { - httpOptions.IgnoreUnknownCertificateAuthority; - } - - return std::make_shared(httpOptions); + return std::make_shared(transportOptions); } else { @@ -108,33 +60,9 @@ namespace Azure { namespace Core { namespace Http { namespace Policies { namespa } #elif defined(BUILD_CURL_HTTP_TRANSPORT_ADAPTER) static std::shared_ptr defaultTransport(std::make_shared()); - if (AnyTransportOptionsSpecified(transportOptions)) + if (AreAnyTransportOptionsSpecified(transportOptions)) { - CurlTransportOptions curlOptions; - curlOptions.EnableCurlTracing = true; - if (transportOptions.HttpProxy.HasValue()) - { - curlOptions.Proxy = transportOptions.HttpProxy; - } - if (!transportOptions.ProxyUserName.empty()) - { - curlOptions.ProxyUsername = transportOptions.ProxyUserName; - } - if (!transportOptions.ProxyPassword.empty()) - { - curlOptions.ProxyPassword = transportOptions.ProxyPassword; - } - - curlOptions.SslOptions.EnableCertificateRevocationListCheck - = transportOptions.EnableCertificateRevocationListCheck; - - if (!transportOptions.ExpectedTlsRootCertificate.empty()) - { - curlOptions.SslOptions.PemEncodedExpectedRootCertificates - = PemEncodeFromBase64(transportOptions.ExpectedTlsRootCertificate, "CERTIFICATE"); - } - - return std::make_shared(curlOptions); + return std::make_shared(transportOptions); } return defaultTransport; #else @@ -150,7 +78,7 @@ TransportPolicy::TransportPolicy(TransportOptions const& options) : m_options(op if (m_options.Transport) { #if !defined(BUILD_TRANSPORT_CUSTOM_ADAPTER) - if (_detail::AnyTransportOptionsSpecified(options)) + if (_detail::AreAnyTransportOptionsSpecified(options)) { AZURE_ASSERT_MSG( false, "Invalid parameter: Proxies cannot be specified when a transport is specified."); diff --git a/sdk/core/azure-core/src/http/winhttp/win_http_transport.cpp b/sdk/core/azure-core/src/http/winhttp/win_http_transport.cpp index feadd948b2..2d51637cf5 100644 --- a/sdk/core/azure-core/src/http/winhttp/win_http_transport.cpp +++ b/sdk/core/azure-core/src/http/winhttp/win_http_transport.cpp @@ -8,15 +8,20 @@ #include "azure/core/diagnostics/logger.hpp" #include "azure/core/internal/diagnostics/log.hpp" #include "azure/core/internal/strings.hpp" +#include "azure/core/internal/unique_handle.hpp" #if defined(BUILD_TRANSPORT_WINHTTP_ADAPTER) #include "azure/core/http/win_http_transport.hpp" #endif - #include #include #include #include +#pragma warning(push) +#pragma warning(disable : 6553) +#include // definitions for wil::unique_cert_chain_context and other RAII type wrappers for Windows types. +#pragma warning(pop) + #include #include @@ -209,14 +214,14 @@ std::string GetHeadersAsString(Azure::Core::Http::Request const& request) // For each certificate specified in trustedCertificate, add to certificateStore. bool WinHttpTransport::AddCertificatesToStore( std::vector const& trustedCertificates, - _detail::unique_HCERTSTORE const& certificateStore) + HCERTSTORE certificateStore) { for (auto const& trustedCertificate : trustedCertificates) { auto derCertificate = Azure::Core::Convert::Base64Decode(trustedCertificate); if (!CertAddEncodedCertificateToStore( - certificateStore.get(), + certificateStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, derCertificate.data(), static_cast(derCertificate.size()), @@ -230,10 +235,10 @@ bool WinHttpTransport::AddCertificatesToStore( } // VerifyCertificateInChain determines whether the certificate in serverCertificate -// chains up to the PEM represented by trustedCertificate or not. +// chains up to one of the certificates represented by trustedCertificate or not. bool WinHttpTransport::VerifyCertificatesInChain( std::vector const& trustedCertificates, - _detail::unique_PCCERT_CONTEXT const& serverCertificate) + PCCERT_CONTEXT serverCertificate) { if ((trustedCertificates.empty()) || !serverCertificate) { @@ -241,7 +246,7 @@ bool WinHttpTransport::VerifyCertificatesInChain( } // Creates an in-memory certificate store that is destroyed at end of this function. - _detail::unique_HCERTSTORE certificateStore(CertOpenStore( + wil::unique_hcertstore certificateStore(CertOpenStore( CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, @@ -253,47 +258,48 @@ bool WinHttpTransport::VerifyCertificatesInChain( } // Add the trusted certificates to that store. - if (!AddCertificatesToStore(trustedCertificates, certificateStore)) + if (!AddCertificatesToStore(trustedCertificates, certificateStore.get())) { Log::Write(Logger::Level::Error, "Cannot add certificates to store"); return false; } - _detail::unique_HCERTCHAINENGINE certificateChainEngine; + // WIL doesn't declare a convenient wrapper for a HCERTCHAINENGINE, so we define a custom one. + wil::unique_any< + HCERTCHAINENGINE, + decltype(CertFreeCertificateChainEngine), + CertFreeCertificateChainEngine> + certificateChainEngine; { CERT_CHAIN_ENGINE_CONFIG EngineConfig{}; EngineConfig.cbSize = sizeof(EngineConfig); EngineConfig.dwFlags = CERT_CHAIN_ENABLE_CACHE_AUTO_UPDATE | CERT_CHAIN_ENABLE_SHARE_STORE; EngineConfig.hExclusiveRoot = certificateStore.get(); - HCERTCHAINENGINE engineHandle; - if (!CertCreateCertificateChainEngine(&EngineConfig, &engineHandle)) + if (!CertCreateCertificateChainEngine(&EngineConfig, certificateChainEngine.addressof())) { GetErrorAndThrow("CertCreateCertificateChainEngine failed"); } - certificateChainEngine.reset(engineHandle); } // Generate a certificate chain using the local chain engine and the certificate store containing // the trusted certificates. - _detail::unique_CCERT_CHAIN_CONTEXT chainContextToVerify; + wil::unique_cert_chain_context chainContextToVerify; { CERT_CHAIN_PARA ChainPara{}; ChainPara.cbSize = sizeof(ChainPara); - PCCERT_CHAIN_CONTEXT chainContext; if (!CertGetCertificateChain( certificateChainEngine.get(), - serverCertificate.get(), + serverCertificate, nullptr, certificateStore.get(), &ChainPara, 0, nullptr, - &chainContext)) + chainContextToVerify.addressof())) { GetErrorAndThrow("CertGetCertificateChain failed"); } - chainContextToVerify.reset(chainContext); } // And make sure that the certificate chain which was created matches the SSL chain. @@ -386,22 +392,20 @@ void WinHttpTransport::OnHttpStatusOperation(HINTERNET hInternet, DWORD dwIntern AZURE_ASSERT(!m_options.ExpectedTlsRootCertificates.empty()); // Ask WinHTTP for the server certificate - this won't be valid outside a status callback. - _detail::unique_PCCERT_CONTEXT serverCertificate; + wil::unique_cert_context serverCertificate; { - PCCERT_CONTEXT certContext; - DWORD bufferLength = sizeof(certContext); + DWORD bufferLength = sizeof(PCCERT_CONTEXT); if (!WinHttpQueryOption( hInternet, WINHTTP_OPTION_SERVER_CERT_CONTEXT, - reinterpret_cast(&certContext), + reinterpret_cast(serverCertificate.addressof()), &bufferLength)) { GetErrorAndThrow("Could not retrieve TLS server certificate."); } - serverCertificate.reset(certContext); } - if (!VerifyCertificatesInChain(m_options.ExpectedTlsRootCertificates, serverCertificate)) + if (!VerifyCertificatesInChain(m_options.ExpectedTlsRootCertificates, serverCertificate.get())) { Log::Write(Logger::Level::Error, "Server certificate is not trusted. Aborting HTTP request"); @@ -442,21 +446,19 @@ void WinHttpTransport::GetErrorAndThrow(const std::string& exceptionMessage, DWO throw Azure::Core::Http::TransportException(errorMessage); } -_detail::unique_HINTERNET WinHttpTransport::CreateSessionHandle() +Azure::Core::_internal::UniqueHandle WinHttpTransport::CreateSessionHandle() { // Use WinHttpOpen to obtain a session handle. // The dwFlags is set to 0 - all WinHTTP functions are performed synchronously. - _detail::unique_HINTERNET sessionHandle( - WinHttpOpen( - NULL, // Do not use a fallback user-agent string, and only rely on the header within the - // request itself. - // If the customer asks for it, enable use of the system default HTTP proxy. - (m_options.EnableSystemDefaultProxy ? WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY - : WINHTTP_ACCESS_TYPE_NO_PROXY), - WINHTTP_NO_PROXY_NAME, - WINHTTP_NO_PROXY_BYPASS, - 0), - _detail::HINTERNET_deleter{}); + Azure::Core::_internal::UniqueHandle sessionHandle(WinHttpOpen( + NULL, // Do not use a fallback user-agent string, and only rely on the header within the + // request itself. + // If the customer asks for it, enable use of the system default HTTP proxy. + (m_options.EnableSystemDefaultProxy ? WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY + : WINHTTP_ACCESS_TYPE_NO_PROXY), + WINHTTP_NO_PROXY_NAME, + WINHTTP_NO_PROXY_BYPASS, + 0)); if (!sessionHandle) { @@ -511,12 +513,57 @@ _detail::unique_HINTERNET WinHttpTransport::CreateSessionHandle() return sessionHandle; } +namespace { +WinHttpTransportOptions WinHttpTransportOptionsFromTransportOptions( + Azure::Core::Http::Policies::TransportOptions const& transportOptions) +{ + WinHttpTransportOptions httpOptions; + if (transportOptions.HttpProxy.HasValue()) + { + // WinHTTP proxy strings are semicolon separated elements, each of which + // has the following format: + // ([=]["://"][":"]) + std::string proxyString; + proxyString = "http=" + transportOptions.HttpProxy.Value(); + proxyString += ";"; + proxyString += "https=" + transportOptions.HttpProxy.Value(); + httpOptions.ProxyInformation = proxyString; + } + httpOptions.ProxyUserName = transportOptions.ProxyUserName; + httpOptions.ProxyPassword = transportOptions.ProxyPassword; + // Note that WinHTTP accepts a set of root certificates, even though transportOptions only + // specifies a single one. + if (!transportOptions.ExpectedTlsRootCertificate.empty()) + { + httpOptions.ExpectedTlsRootCertificates.push_back(transportOptions.ExpectedTlsRootCertificate); + } + if (transportOptions.EnableCertificateRevocationListCheck) + { + httpOptions.EnableCertificateRevocationListCheck; + } + // If you specify an expected TLS root certificate, you also need to enable ignoring unknown + // CAs. + if (!transportOptions.ExpectedTlsRootCertificate.empty()) + { + httpOptions.IgnoreUnknownCertificateAuthority; + } + + return httpOptions; +} +} // namespace + WinHttpTransport::WinHttpTransport(WinHttpTransportOptions const& options) : m_options(options), m_sessionHandle(CreateSessionHandle()) { } -_detail::unique_HINTERNET WinHttpTransport::CreateConnectionHandle( +WinHttpTransport::WinHttpTransport( + Azure::Core::Http::Policies::TransportOptions const& transportOptions) + : WinHttpTransport(WinHttpTransportOptionsFromTransportOptions(transportOptions)) +{ +} + +Azure::Core::_internal::UniqueHandle WinHttpTransport::CreateConnectionHandle( Azure::Core::Url const& url, Azure::Core::Context const& context) { @@ -527,13 +574,11 @@ _detail::unique_HINTERNET WinHttpTransport::CreateConnectionHandle( // Specify an HTTP server. // This function always operates synchronously. - _detail::unique_HINTERNET rv( - WinHttpConnect( - m_sessionHandle.get(), - StringToWideString(url.GetHost()).c_str(), - port == 0 ? INTERNET_DEFAULT_PORT : port, - 0), - _detail::HINTERNET_deleter{}); + Azure::Core::_internal::UniqueHandle rv(WinHttpConnect( + m_sessionHandle.get(), + StringToWideString(url.GetHost()).c_str(), + port == 0 ? INTERNET_DEFAULT_PORT : port, + 0)); if (!rv) { @@ -550,8 +595,8 @@ _detail::unique_HINTERNET WinHttpTransport::CreateConnectionHandle( return rv; } -_detail::unique_HINTERNET WinHttpTransport::CreateRequestHandle( - _detail::unique_HINTERNET const& connectionHandle, +Azure::Core::_internal::UniqueHandle WinHttpTransport::CreateRequestHandle( + Azure::Core::_internal::UniqueHandle const& connectionHandle, Azure::Core::Url const& url, Azure::Core::Http::HttpMethod const& method) { @@ -564,17 +609,15 @@ _detail::unique_HINTERNET WinHttpTransport::CreateRequestHandle( url.GetScheme(), WebSocketScheme)); // Create an HTTP request handle. - _detail::unique_HINTERNET request( - WinHttpOpenRequest( - connectionHandle.get(), - HttpMethodToWideString(requestMethod).c_str(), - path.empty() ? NULL : StringToWideString(path).c_str(), // Name of the target resource of - // the specified HTTP verb - NULL, // Use HTTP/1.1 - WINHTTP_NO_REFERER, - WINHTTP_DEFAULT_ACCEPT_TYPES, // No media types are accepted by the client - requestSecureHttp ? WINHTTP_FLAG_SECURE : 0), - _detail::HINTERNET_deleter{}); // Uses secure transaction semantics (SSL/TLS) + Azure::Core::_internal::UniqueHandle request(WinHttpOpenRequest( + connectionHandle.get(), + HttpMethodToWideString(requestMethod).c_str(), + path.empty() ? NULL : StringToWideString(path).c_str(), // Name of the target resource of + // the specified HTTP verb + NULL, // Use HTTP/1.1 + WINHTTP_NO_REFERER, + WINHTTP_DEFAULT_ACCEPT_TYPES, // No media types are accepted by the client + requestSecureHttp ? WINHTTP_FLAG_SECURE : 0)); // Uses secure transaction semantics (SSL/TLS) if (!request) { // Errors include: @@ -613,14 +656,14 @@ _detail::unique_HINTERNET WinHttpTransport::CreateRequestHandle( GetErrorAndThrow("Error while setting Proxy information."); } } - if (!m_options.ProxyUserName.empty() || !m_options.ProxyPassword.empty()) + if (m_options.ProxyUserName.HasValue() || m_options.ProxyPassword.HasValue()) { if (!WinHttpSetCredentials( request.get(), WINHTTP_AUTH_TARGET_PROXY, WINHTTP_AUTH_SCHEME_BASIC, - StringToWideString(m_options.ProxyUserName).c_str(), - StringToWideString(m_options.ProxyPassword).c_str(), + StringToWideString(m_options.ProxyUserName.Value()).c_str(), + StringToWideString(m_options.ProxyPassword.Value()).c_str(), 0)) { GetErrorAndThrow("Error while setting Proxy credentials."); @@ -661,7 +704,7 @@ _detail::unique_HINTERNET WinHttpTransport::CreateRequestHandle( // For PUT/POST requests, send additional data using WinHttpWriteData. void WinHttpTransport::Upload( - _detail::unique_HINTERNET const& requestHandle, + Azure::Core::_internal::UniqueHandle const& requestHandle, Azure::Core::Http::Request& request, Azure::Core::Context const& context) { @@ -701,7 +744,7 @@ void WinHttpTransport::Upload( } void WinHttpTransport::SendRequest( - _detail::unique_HINTERNET const& requestHandle, + Azure::Core::_internal::UniqueHandle const& requestHandle, Azure::Core::Http::Request& request, Azure::Core::Context const& context) { @@ -769,7 +812,7 @@ void WinHttpTransport::SendRequest( } void WinHttpTransport::ReceiveResponse( - _detail::unique_HINTERNET const& requestHandle, + Azure::Core::_internal::UniqueHandle const& requestHandle, Azure::Core::Context const& context) { context.ThrowIfCancelled(); @@ -792,7 +835,7 @@ void WinHttpTransport::ReceiveResponse( } int64_t WinHttpTransport::GetContentLength( - _detail::unique_HINTERNET const& requestHandle, + Azure::Core::_internal::UniqueHandle const& requestHandle, HttpMethod requestMethod, HttpStatusCode responseStatusCode) { @@ -828,7 +871,7 @@ int64_t WinHttpTransport::GetContentLength( } std::unique_ptr WinHttpTransport::SendRequestAndGetResponse( - _detail::unique_HINTERNET& requestHandle, + Azure::Core::_internal::UniqueHandle& requestHandle, HttpMethod requestMethod) { // First, use WinHttpQueryHeaders to obtain the size of the buffer. @@ -966,8 +1009,9 @@ std::unique_ptr WinHttpTransport::SendRequestAndGetResponse( std::unique_ptr WinHttpTransport::Send(Request& request, Context const& context) { - _detail::unique_HINTERNET connectionHandle = CreateConnectionHandle(request.GetUrl(), context); - _detail::unique_HINTERNET requestHandle + Azure::Core::_internal::UniqueHandle connectionHandle + = CreateConnectionHandle(request.GetUrl(), context); + Azure::Core::_internal::UniqueHandle requestHandle = CreateRequestHandle(connectionHandle, request.GetUrl(), request.GetMethod()); try { diff --git a/sdk/core/azure-core/src/http/winhttp/win_http_websockets.cpp b/sdk/core/azure-core/src/http/winhttp/win_http_websockets.cpp index 7d869ca709..ca1d42164e 100644 --- a/sdk/core/azure-core/src/http/winhttp/win_http_websockets.cpp +++ b/sdk/core/azure-core/src/http/winhttp/win_http_websockets.cpp @@ -6,6 +6,7 @@ #include "azure/core/http/transport.hpp" #include "azure/core/http/websockets/win_http_websockets_transport.hpp" #include "azure/core/internal/diagnostics/log.hpp" +#include "azure/core/internal/unique_handle.hpp" #include "azure/core/platform.hpp" #if defined(AZ_PLATFORM_POSIX) @@ -26,12 +27,11 @@ namespace Azure { namespace Core { namespace Http { namespace WebSockets { void WinHttpWebSocketTransport::OnUpgradedConnection( - Azure::Core::Http::_detail::unique_HINTERNET const& requestHandle) + Azure::Core::_internal::UniqueHandle const& requestHandle) { // Convert the request handle into a WebSocket handle for us to use later. - m_socketHandle = Azure::Core::Http::_detail::unique_HINTERNET( - WinHttpWebSocketCompleteUpgrade(requestHandle.get(), 0), - Azure::Core::Http::_detail::HINTERNET_deleter{}); + m_socketHandle = Azure::Core::_internal::UniqueHandle( + WinHttpWebSocketCompleteUpgrade(requestHandle.get(), 0)); if (!m_socketHandle) { GetErrorAndThrow("Error Upgrading HttpRequest handle to WebSocket handle."); diff --git a/sdk/core/azure-core/test/ut/CMakeLists.txt b/sdk/core/azure-core/test/ut/CMakeLists.txt index 610962a11c..bc307cd78d 100644 --- a/sdk/core/azure-core/test/ut/CMakeLists.txt +++ b/sdk/core/azure-core/test/ut/CMakeLists.txt @@ -34,8 +34,8 @@ endif() include(GoogleTest) if (NOT WIN32) -find_package(OpenSSL REQUIRED) -SET(OPENSSLCRYPTO OpenSSL::Crypto) + find_package(OpenSSL REQUIRED) + SET(OPENSSLCRYPTO OpenSSL::Crypto) endif() add_executable ( @@ -106,20 +106,27 @@ if (MSVC) endif() if (DISABLE_PROXY_TESTS) -message(STATUS "Disabling proxy tests because they cannot be supported on this environment." ) -add_compile_definitions(DISABLE_PROXY_TESTS) + message(STATUS "Disabling proxy tests because they cannot be supported on this environment." ) + add_compile_definitions(DISABLE_PROXY_TESTS) +endif() + +# If the System.TeamProjectId ADO variable is set, we are running in the pipeline, behave accordingly. +if (ENV{SYSTEM_TEAMPROJECTID}) + add_compile_definitions(IN_CI_PIPELINE) endif() # Additional test files to be copied to the output directory. -set(TEST_ADDITIONAL_FILES ${CMAKE_CURRENT_LIST_DIR}/websocket_server.py +set(TEST_ADDITIONAL_FILES ${CMAKE_CURRENT_LIST_DIR}/requirements.txt - ${CMAKE_CURRENT_LIST_DIR}/Start-WebSocketServer.ps1 -) + ${CMAKE_CURRENT_LIST_DIR}/websocket_server.py + ${CMAKE_CURRENT_LIST_DIR}/Start-WebSocketServer.ps1 + ) add_custom_command(TARGET azure-core-test POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${TEST_ADDITIONAL_FILES} ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${TEST_ADDITIONAL_FILES} - COMMENT 'Copying non-source output files') + COMMENT 'Copying non-source output files' + ) # Adding private headers from CORE to the tests so we can test the private APIs with no relative paths include. target_include_directories (azure-core-test PRIVATE $) diff --git a/sdk/core/azure-core/test/ut/azure_core_test.cpp b/sdk/core/azure-core/test/ut/azure_core_test.cpp index 9f82b4628d..bf312f1565 100644 --- a/sdk/core/azure-core/test/ut/azure_core_test.cpp +++ b/sdk/core/azure-core/test/ut/azure_core_test.cpp @@ -5,8 +5,13 @@ #if defined(BUILD_CURL_HTTP_TRANSPORT_ADAPTER) #include -#include #endif +#include +#include + +// C Runtime Library errors trigger SIGABRT. Catch that signal handler and report it on the test +// log. +void AbortHandler(int signal) { std::cout << "abort() has been called: " << signal << std::endl; } int main(int argc, char** argv) { @@ -16,6 +21,8 @@ int main(int argc, char** argv) signal(SIGPIPE, SIG_IGN); #endif + signal(SIGABRT, AbortHandler); + testing::InitGoogleTest(&argc, argv); auto r = RUN_ALL_TESTS(); diff --git a/sdk/core/azure-core/test/ut/curl_options_test.cpp b/sdk/core/azure-core/test/ut/curl_options_test.cpp index c8dc62238c..a1ffdf3aab 100644 --- a/sdk/core/azure-core/test/ut/curl_options_test.cpp +++ b/sdk/core/azure-core/test/ut/curl_options_test.cpp @@ -15,6 +15,7 @@ #endif #include +#include #include #include "transport_adapter_base_test.hpp" @@ -95,6 +96,26 @@ namespace Azure { namespace Core { namespace Test { .ConnectionPoolIndex.clear()); } + class CurlDerived : public Azure::Core::Http::CurlTransport { + std::unique_ptr m_connection; + + public: + void OnUpgradedConnection( + std::unique_ptr&& connection) override + { + m_connection = std::move(connection); + } + }; + + // Call the base OnUpgradedConnection method from a class derived from CurlTransport - this + // primarily is there to increase code coverage. + TEST(CurlTransportOptions, OnUpgradedConnection) + { + CurlDerived derived; + std::unique_ptr connection; + derived.OnUpgradedConnection(std::move(connection)); + } + /* // Requires libcurl version >= 7.68 TEST(CurlTransportOptions, nativeCA) diff --git a/sdk/core/azure-core/test/ut/proxy_tests/builddocker.ps1 b/sdk/core/azure-core/test/ut/proxy_tests/builddocker.ps1 index 55f3aea841..5b46f90c36 100644 --- a/sdk/core/azure-core/test/ut/proxy_tests/builddocker.ps1 +++ b/sdk/core/azure-core/test/ut/proxy_tests/builddocker.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + pushd .\localproxy docker build -t squid-local . popd diff --git a/sdk/core/azure-core/test/ut/proxy_tests/localproxy.passwd/Dockerfile b/sdk/core/azure-core/test/ut/proxy_tests/localproxy.passwd/Dockerfile index 45bd84dfa5..1f6e67252f 100644 --- a/sdk/core/azure-core/test/ut/proxy_tests/localproxy.passwd/Dockerfile +++ b/sdk/core/azure-core/test/ut/proxy_tests/localproxy.passwd/Dockerfile @@ -1,5 +1,6 @@ #@# vim: set filetype=dockerfile: -# Code taken from: https://github.com/hinata/nginx-forward-proxy +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT FROM ubuntu/squid LABEL maintainer "Larry Osterman" diff --git a/sdk/core/azure-core/test/ut/proxy_tests/localproxy/Dockerfile b/sdk/core/azure-core/test/ut/proxy_tests/localproxy/Dockerfile index dafba7640a..92bc800781 100644 --- a/sdk/core/azure-core/test/ut/proxy_tests/localproxy/Dockerfile +++ b/sdk/core/azure-core/test/ut/proxy_tests/localproxy/Dockerfile @@ -1,5 +1,6 @@ #@# vim: set filetype=dockerfile: -# Code taken from: https://github.com/hinata/nginx-forward-proxy +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT FROM ubuntu/squid LABEL maintainer "Larry Osterman" diff --git a/sdk/core/azure-core/test/ut/proxy_tests/remoteproxy.passwd/Dockerfile b/sdk/core/azure-core/test/ut/proxy_tests/remoteproxy.passwd/Dockerfile index 4bfef7bd1d..b040f26230 100644 --- a/sdk/core/azure-core/test/ut/proxy_tests/remoteproxy.passwd/Dockerfile +++ b/sdk/core/azure-core/test/ut/proxy_tests/remoteproxy.passwd/Dockerfile @@ -1,5 +1,6 @@ #@# vim: set filetype=dockerfile: -# Code taken from: https://github.com/hinata/nginx-forward-proxy +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT FROM ubuntu/squid LABEL maintainer "Larry Osterman" diff --git a/sdk/core/azure-core/test/ut/proxy_tests/remoteproxy/Dockerfile b/sdk/core/azure-core/test/ut/proxy_tests/remoteproxy/Dockerfile index dafba7640a..92bc800781 100644 --- a/sdk/core/azure-core/test/ut/proxy_tests/remoteproxy/Dockerfile +++ b/sdk/core/azure-core/test/ut/proxy_tests/remoteproxy/Dockerfile @@ -1,5 +1,6 @@ #@# vim: set filetype=dockerfile: -# Code taken from: https://github.com/hinata/nginx-forward-proxy +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT FROM ubuntu/squid LABEL maintainer "Larry Osterman" diff --git a/sdk/core/azure-core/test/ut/proxy_tests/run_wsl_proxy.ps1 b/sdk/core/azure-core/test/ut/proxy_tests/run_wsl_proxy.ps1 index 6d91729520..8de008e4ed 100644 --- a/sdk/core/azure-core/test/ut/proxy_tests/run_wsl_proxy.ps1 +++ b/sdk/core/azure-core/test/ut/proxy_tests/run_wsl_proxy.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + # cspell: words auxf wsl sudo apt-get -y install squid if (!$?) { diff --git a/sdk/core/azure-core/test/ut/proxy_tests/runproxy.ps1 b/sdk/core/azure-core/test/ut/proxy_tests/runproxy.ps1 index bb2db511d6..b3ca689f77 100644 --- a/sdk/core/azure-core/test/ut/proxy_tests/runproxy.ps1 +++ b/sdk/core/azure-core/test/ut/proxy_tests/runproxy.ps1 @@ -1,2 +1,5 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + docker run --rm -d -p 3128:3128 squid-local docker run --rm -d -p 3129:3129 squid-local.passwd diff --git a/sdk/core/azure-core/test/ut/proxy_tests/verify_proxy.ps1 b/sdk/core/azure-core/test/ut/proxy_tests/verify_proxy.ps1 index 1ac3d7b826..49b7ebc131 100644 --- a/sdk/core/azure-core/test/ut/proxy_tests/verify_proxy.ps1 +++ b/sdk/core/azure-core/test/ut/proxy_tests/verify_proxy.ps1 @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + Write-Host 'EnvVar: ' $env:ANONYMOUSCONTAINERIPV4ADDRESS Write-Host 'EnvVar: ' $env:AUTHENTICATEDCONTAINERIPV4ADDRESS if ($env:ANONYMOUSCONTAINERIPV4ADDRESS -ne $null) { diff --git a/sdk/core/azure-core/test/ut/request_activity_policy_test.cpp b/sdk/core/azure-core/test/ut/request_activity_policy_test.cpp index e2661f9c76..45b53d3799 100644 --- a/sdk/core/azure-core/test/ut/request_activity_policy_test.cpp +++ b/sdk/core/azure-core/test/ut/request_activity_policy_test.cpp @@ -16,6 +16,7 @@ using namespace Azure::Core::Tracing::_internal; using namespace Azure::Core::Tracing; namespace { + class NoOpPolicy final : public HttpPolicy { std::function(Request&)> m_createResponse{}; @@ -209,7 +210,9 @@ TEST(RequestActivityPolicy, Basic) // Final policy - equivalent to HTTP policy. policies.emplace_back(std::make_unique([&](Request& request) { userAgent = request.GetHeader("user-agent"); // Return success. - return std::make_unique(1, 1, HttpStatusCode::Ok, "Something"); + auto response = std::make_unique(1, 1, HttpStatusCode::Ok, "Something"); + response->SetHeader("x-ms-request-id", request.GetHeader("x-ms-client-request-id").Value()); + return response; })); Azure::Core::Http::_internal::HttpPipeline(policies).Send(request, callContext); @@ -221,6 +224,9 @@ TEST(RequestActivityPolicy, Basic) EXPECT_EQ("My API", tracer->GetSpans()[0]->GetName()); EXPECT_EQ("HTTP GET", tracer->GetSpans()[1]->GetName()); EXPECT_EQ("GET", tracer->GetSpans()[1]->GetAttributes().at("http.method")); + EXPECT_EQ( + request.GetHeaders()["x-ms-client-request-id"], + tracer->GetSpans()[1]->GetAttributes().at("requestId")); std::string expectedUserAgentPrefix{"azsdk-cpp-my-service-cpp/1.0.0.beta-2 ("}; EXPECT_EQ(expectedUserAgentPrefix, userAgent.Value().substr(0, expectedUserAgentPrefix.size())); } @@ -284,3 +290,53 @@ TEST(RequestActivityPolicy, TryRetries) EXPECT_EQ("200", tracer->GetSpans()[3]->GetAttributes().at("http.status_code")); } } + +TEST(RequestActivityPolicy, TryFailures) +{ + { + auto testTracer = std::make_shared(); + + Azure::Core::_internal::ClientOptions clientOptions; + clientOptions.Telemetry.TracingProvider = testTracer; + Azure::Core::Tracing::_internal::TracingContextFactory serviceTrace( + clientOptions, "my-service-cpp", "1.0b2"); + + auto contextAndSpan = serviceTrace.CreateTracingContext("My API", {}); + Azure::Core::Context callContext = std::move(contextAndSpan.Context); + Request request(HttpMethod::Get, Url("https://www.microsoft.com")); + + { + std::vector> policies; + + policies.emplace_back(std::make_unique()); + policies.emplace_back(std::make_unique(RetryOptions{})); + + // Add the request ID policy - this adds the x-ms-request-id attribute to the pipeline. + policies.emplace_back( + std::make_unique(Azure::Core::Http::_internal::HttpSanitizer{})); + // Final policy - equivalent to HTTP policy. + policies.emplace_back( + std::make_unique([&](Request&) -> std::unique_ptr { + throw Azure::Core::Http::TransportException("Throwing exceptions..."); + })); + + Azure::Core::Http::_internal::HttpPipeline pipeline(policies); + // Simulate retrying an HTTP operation 3 times on the pipeline: + EXPECT_THROW(pipeline.Send(request, callContext), Azure::Core::Http::TransportException); + } + + EXPECT_EQ(1ul, testTracer->GetTracers().size()); + auto& tracer = testTracer->GetTracers().front(); + EXPECT_EQ(5ul, tracer->GetSpans().size()); + EXPECT_EQ("My API", tracer->GetSpans()[0]->GetName()); + EXPECT_EQ("HTTP GET", tracer->GetSpans()[1]->GetName()); + EXPECT_EQ("HTTP GET", tracer->GetSpans()[2]->GetName()); + EXPECT_EQ("HTTP GET", tracer->GetSpans()[3]->GetName()); + EXPECT_EQ(1, tracer->GetSpans()[1]->GetEvents().size()); + EXPECT_EQ("Throwing exceptions...", tracer->GetSpans()[1]->GetEvents()[0]); + EXPECT_EQ(1, tracer->GetSpans()[2]->GetEvents().size()); + EXPECT_EQ("Throwing exceptions...", tracer->GetSpans()[2]->GetEvents()[0]); + EXPECT_EQ(1, tracer->GetSpans()[3]->GetEvents().size()); + EXPECT_EQ("Throwing exceptions...", tracer->GetSpans()[3]->GetEvents()[0]); + } +} diff --git a/sdk/core/azure-core/test/ut/transport_policy_options.cpp b/sdk/core/azure-core/test/ut/transport_policy_options.cpp index 398f40f3c2..1c930ca7a2 100644 --- a/sdk/core/azure-core/test/ut/transport_policy_options.cpp +++ b/sdk/core/azure-core/test/ut/transport_policy_options.cpp @@ -4,6 +4,9 @@ #include "azure/core/context.hpp" #include "azure/core/http/curl_transport.hpp" #include "azure/core/http/policies/policy.hpp" +#if defined(BUILD_TRANSPORT_WINHTTP_ADAPTER) +#include "azure/core/http/win_http_transport.hpp" +#endif #include "azure/core/internal/client_options.hpp" #include "azure/core/internal/environment.hpp" #include "azure/core/internal/http/pipeline.hpp" @@ -25,13 +28,6 @@ namespace Azure { namespace Core { namespace Test { class TransportAdapterOptions : public ::testing::Test { public: - enum class TestMode - { - UNKNOWN, - RECORD, - LIVE, - PLAYBACK, - }; struct AzureSdkHttpbinServer final { inline static std::string Get() @@ -92,47 +88,100 @@ namespace Azure { namespace Core { namespace Test { Azure::Core::Http::HttpStatusCode code, Azure::Core::Http::HttpStatusCode expectedCode = Azure::Core::Http::HttpStatusCode::Ok); - std::string HttpProxyServer() { return "http://127.0.0.1:3128"; } - std::string HttpProxyServerWithPassword() { return "http://127.0.0.1:3129"; } - - protected: - // Create - virtual void SetUp() override {} - - TestMode GetTestMode() + std::string HttpProxyServer() { - auto value = Azure::Core::_internal::Environment::GetVariable("AZURE_TEST_MODE"); - GTEST_LOG_(INFO) << "Azure Test Mode: " << value; - if (value.empty()) + std::string proxyUrl{Azure::Core::_internal::Environment::GetVariable("SQUID_PROXY_URL")}; + if (proxyUrl.empty()) { - GTEST_LOG_(INFO) << "Assume Live Test"; - - return TestMode::LIVE; + proxyUrl = "http://127.0.0.1:3128"; } - - if (Azure::Core::_internal::StringExtensions::LocaleInvariantCaseInsensitiveEqual( - value, "RECORD")) + return proxyUrl; + } + std::string HttpProxyServerWithPassword() + { + std::string proxyUrl{ + Azure::Core::_internal::Environment::GetVariable("SQUID_AUTH_PROXY_URL")}; + if (proxyUrl.empty()) { - GTEST_LOG_(INFO) << "TestMode:: Record."; - return TestMode::RECORD; + proxyUrl = "http://127.0.0.1:3129"; } - else if (Azure::Core::_internal::StringExtensions::LocaleInvariantCaseInsensitiveEqual( - value, "PLAYBACK")) + return proxyUrl; + } + std::string TestProxyUrl() + { + std::string proxyUrl{Azure::Core::_internal::Environment::GetVariable("PROXY_URL")}; + if (proxyUrl.empty()) { - GTEST_LOG_(INFO) << "TestMode:: Playback."; - return TestMode::PLAYBACK; + proxyUrl = "https://localhost:5001"; } - else if (Azure::Core::_internal::StringExtensions::LocaleInvariantCaseInsensitiveEqual( - value, "LIVE")) + return proxyUrl; + } + static bool ProxyStatusChecked; + static bool IsSquidProxyRunning; + static bool IsTestProxyRunning; + + protected: + // Create + virtual void SetUp() override + { +#if defined(IN_CI_PIPELINE) + // If we're in the CI pipeline, don't probe for the squid or test proxy running - just assume + // they are. + IsSquidProxyRunning = true; + IsTestProxyRunning = true; +#else // !defined(IN_CI_PIPELINE) + if (!ProxyStatusChecked) { - GTEST_LOG_(INFO) << "TestMode:: Live."; - return TestMode::LIVE; + Azure::Core::Http::Policies::TransportOptions options; + { + auto pipeline = CreateHttpPipeline(options); + auto request = Azure::Core::Http::Request( + Azure::Core::Http::HttpMethod::Get, Azure::Core::Url(HttpProxyServer()), false); + try + { + auto response = pipeline.Send(request, Azure::Core::Context::ApplicationContext); + IsSquidProxyRunning = true; + } + catch (Azure::Core::RequestFailedException& rfe) + { + IsSquidProxyRunning = false; + std::cout << "Skipping proxy tests. Error: " << rfe.what() << std::endl; + } + } + { +#if defined(BUILD_CURL_HTTP_TRANSPORT_ADAPTER) + Azure::Core::Http::CurlTransportOptions curlOptions; + curlOptions.SslVerifyPeer = false; + curlOptions.EnableCurlTracing = true; + options.Transport = std::make_shared(curlOptions); +#elif defined(BUILD_TRANSPORT_WINHTTP_ADAPTER) + Azure::Core::Http::WinHttpTransportOptions winHttpOptions; + winHttpOptions.IgnoreUnknownCertificateAuthority = true; + options.Transport = std::make_shared(winHttpOptions); +#endif + auto pipeline = CreateHttpPipeline(options); + auto request = Azure::Core::Http::Request( + Azure::Core::Http::HttpMethod::Get, + Azure::Core::Url(TestProxyUrl() + "/Admin/IsAlive")); + try + { + pipeline.Send(request, Azure::Core::Context::ApplicationContext); + IsTestProxyRunning = true; + } + catch (Azure::Core::RequestFailedException& rfe) + { + IsTestProxyRunning = false; + std::cout << "Skipping TestProxy tests: " << rfe.what() << std::endl; + } + } + ProxyStatusChecked = true; } - - // unexpected variable value - throw std::runtime_error("Invalid environment variable: " + value); +#endif } }; + bool TransportAdapterOptions::ProxyStatusChecked{false}; + bool TransportAdapterOptions::IsSquidProxyRunning{false}; + bool TransportAdapterOptions::IsTestProxyRunning{false}; void TransportAdapterOptions::checkResponseCode( Azure::Core::Http::HttpStatusCode code, @@ -179,7 +228,6 @@ namespace Azure { namespace Core { namespace Test { std::vector bodyVector = body->ReadToEnd(Azure::Core::Context::ApplicationContext); int64_t bodySize = body->Length(); EXPECT_EQ(bodySize, size); - bodySize = bodyVector.size(); if (size > 0) { // only for known body size @@ -228,6 +276,10 @@ namespace Azure { namespace Core { namespace Test { // constexpr char SocksProxyServer[] = "socks://98.162.96.41:4145"; TEST_F(TransportAdapterOptions, SimpleProxyTests) { + if (!IsSquidProxyRunning) + { + GTEST_SKIP_("Skipping proxy tests because proxy is not running."); + } Azure::Core::Url testUrl(AzureSdkHttpbinServer::Get()); std::string myIpAddress; { @@ -278,6 +330,10 @@ namespace Azure { namespace Core { namespace Test { TEST_F(TransportAdapterOptions, ProxyWithPasswordHttps) { + if (!IsSquidProxyRunning) + { + GTEST_SKIP_("Skipping proxy tests because proxy is not running."); + } Azure::Core::Url testUrl(AzureSdkHttpbinServer::Get()); // HTTPS Connections. @@ -323,6 +379,10 @@ namespace Azure { namespace Core { namespace Test { TEST_F(TransportAdapterOptions, ProxyWithPasswordHttp) { + if (!IsSquidProxyRunning) + { + GTEST_SKIP_("Skipping proxy tests because proxy is not running."); + } Azure::Core::Url testUrl(AzureSdkHttpbinServer::Get()); // HTTP Connections. testUrl.SetScheme("http"); @@ -376,6 +436,7 @@ namespace Azure { namespace Core { namespace Test { EXPECT_EQ(response->GetStatusCode(), Azure::Core::Http::HttpStatusCode::Ok); } #if !defined(DISABLE_PROXY_TESTS) + if (IsSquidProxyRunning) { Azure::Core::Http::Policies::TransportOptions transportOptions; @@ -447,6 +508,7 @@ namespace Azure { namespace Core { namespace Test { // the certificate for the test URL doesn't contain a CRL distribution points extension, // and by default there is no platform CRL present. Azure::Core::Http::CurlTransportOptions curlOptions; + curlOptions.EnableCurlTracing = true; curlOptions.SslOptions.AllowFailedCrlRetrieval = true; curlOptions.SslOptions.EnableCertificateRevocationListCheck = true; transportOptions.Transport = std::make_shared(curlOptions); @@ -466,7 +528,7 @@ namespace Azure { namespace Core { namespace Test { { std::vector testUrls{ AzureSdkHttpbinServer::Get(), - "https://www.microsoft.com/", + "https://twitter.com/", "https://www.example.com/", "https://www.google.com/", }; @@ -677,6 +739,15 @@ namespace Azure { namespace Core { namespace Test { // cspell:enable std::unique_ptr m_pipeline; + std::string TestProxyUrl() + { + std::string proxyUrl{Azure::Core::_internal::Environment::GetVariable("PROXY_URL")}; + if (proxyUrl.empty()) + { + proxyUrl = "https://localhost:5001"; + } + return proxyUrl; + } public: struct TestProxyOptions : Azure::Core::_internal::ClientOptions @@ -709,7 +780,7 @@ namespace Azure { namespace Core { namespace Test { Azure::Core::IO::MemoryBodyStream postBody(bodyVector); auto request = Azure::Core::Http::Request( Azure::Core::Http::HttpMethod::Post, - Azure::Core::Url("https://localhost:5001/record/start"), + Azure::Core::Url(TestProxyUrl() + "/record/start"), &postBody); auto response = m_pipeline->Send(request, Azure::Core::Context::ApplicationContext); @@ -721,8 +792,7 @@ namespace Azure { namespace Core { namespace Test { std::string const& recordingId) { auto request = Azure::Core::Http::Request( - Azure::Core::Http::HttpMethod::Post, - Azure::Core::Url("https://localhost:5001/record/stop")); + Azure::Core::Http::HttpMethod::Post, Azure::Core::Url(TestProxyUrl() + "/record/stop")); request.SetHeader("x-recording-id", recordingId); auto response = m_pipeline->Send(request, Azure::Core::Context::ApplicationContext); @@ -740,7 +810,7 @@ namespace Azure { namespace Core { namespace Test { Azure::Core::IO::MemoryBodyStream postBody(bodyVector); auto request = Azure::Core::Http::Request( Azure::Core::Http::HttpMethod::Post, - Azure::Core::Url("https://localhost:5001/playback/start"), + Azure::Core::Url(TestProxyUrl() + "/playback/start"), &postBody); auto response = m_pipeline->Send(request, Azure::Core::Context::ApplicationContext); @@ -753,8 +823,7 @@ namespace Azure { namespace Core { namespace Test { std::string const& recordingId) { auto request = Azure::Core::Http::Request( - Azure::Core::Http::HttpMethod::Post, - Azure::Core::Url("https://localhost:5001/playback/stop")); + Azure::Core::Http::HttpMethod::Post, Azure::Core::Url(TestProxyUrl() + "/playback/stop")); request.SetHeader("x-recording-id", recordingId); auto response = m_pipeline->Send(request, Azure::Core::Context::ApplicationContext); @@ -770,7 +839,7 @@ namespace Azure { namespace Core { namespace Test { Azure::Core::Url targetUrl{urlToRecord}; auto request = Azure::Core::Http::Request( Azure::Core::Http::HttpMethod::Get, - Azure::Core::Url("https://localhost:5001/" + targetUrl.GetRelativeUrl())); + Azure::Core::Url(TestProxyUrl() + "/" + targetUrl.GetRelativeUrl())); request.SetHeader( "x-recording-upstream-base-uri", targetUrl.GetScheme() + "://" + targetUrl.GetHost()); request.SetHeader("x-recording-id", recordingId); @@ -784,8 +853,7 @@ namespace Azure { namespace Core { namespace Test { Azure::Response IsAlive() { auto request = Azure::Core::Http::Request( - Azure::Core::Http::HttpMethod::Get, - Azure::Core::Url("https://localhost:5001/Admin/IsAlive")); + Azure::Core::Http::HttpMethod::Get, Azure::Core::Url(TestProxyUrl() + "/Admin/IsAlive")); auto response = m_pipeline->Send(request, Azure::Core::Context::ApplicationContext); auto statusCode = response->GetStatusCode(); return Azure::Response(statusCode, std::move(response)); @@ -796,6 +864,11 @@ namespace Azure { namespace Core { namespace Test { TEST_F(TransportAdapterOptions, AccessTestProxyServer) { + if (!IsTestProxyRunning) + { + GTEST_SKIP_("Skipping TestProxy tests because TestProxy is not running."); + } + TestProxy proxyServer; EXPECT_EQ(Azure::Core::Http::HttpStatusCode::Ok, proxyServer.IsAlive().Value); @@ -828,6 +901,11 @@ namespace Azure { namespace Core { namespace Test { TEST_F(TransportAdapterOptions, TestProxyServerWithInvalidCertificate) { + if (!IsTestProxyRunning) + { + GTEST_SKIP_("Skipping TestProxy tests because TestProxy is not running."); + } + TestProxy::TestProxyOptions options; options.Transport.ExpectedTlsRootCertificate = InvalidTestProxyHttpsCertificate; TestProxy proxyServer(options); diff --git a/sdk/core/azure-core/vcpkg.json b/sdk/core/azure-core/vcpkg.json index a8f96609de..f3168e17f8 100644 --- a/sdk/core/azure-core/vcpkg.json +++ b/sdk/core/azure-core/vcpkg.json @@ -1,69 +1,73 @@ { - "name": "azure-core-cpp", - "version-string": "1.4.0-beta.1", - "dependencies": [ + "name": "azure-core-cpp", + "version-string": "1.4.0-beta.1", + "dependencies": [ + { + "name": "openssl", + "platform": "!windows & !uwp" + }, + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + }, + { + "name": "wil", + "platform": "windows" + } + ], + "default-features": [ + "http" + ], + "features": { + "curl": { + "description": "Libcurl HTTP transport implementation", + "dependencies": [ { - "name": "openssl", - "platform": "!windows & !uwp" + "name": "azure-core-cpp", + "default-features": false }, { - "name": "vcpkg-cmake", - "host": true + "name": "curl", + "default-features": false, + "features": [ + "ssl" + ] + } + ] + }, + "http": { + "description": "All HTTP transport implementations available on the platform", + "dependencies": [ + { + "name": "azure-core-cpp", + "default-features": false, + "features": [ + "curl" + ] }, { - "name": "vcpkg-cmake-config", - "host": true + "name": "azure-core-cpp", + "default-features": false, + "features": [ + "curl", + "winhttp" + ], + "platform": "windows & !uwp" } - ], - "default-features": [ - "http" - ], - "features": { - "curl": { - "description": "Libcurl HTTP transport implementation", - "dependencies": [ - { - "name": "azure-core-cpp", - "default-features": false - }, - { - "name": "curl", - "default-features": false, - "features": [ - "ssl" - ] - } - ] - }, - "http": { - "description": "All HTTP transport implementations available on the platform", - "dependencies": [ - { - "name": "azure-core-cpp", - "default-features": false, - "features": [ - "curl" - ] - }, - { - "name": "azure-core-cpp", - "default-features": false, - "features": [ - "curl", - "winhttp" - ], - "platform": "windows & !uwp" - } - ] - }, - "winhttp": { - "description": "WinHTTP HTTP transport implementation", - "dependencies": [ - { - "name": "azure-core-cpp", - "default-features": false - } - ] + ] + }, + "winhttp": { + "description": "WinHTTP HTTP transport implementation", + "dependencies": [ + { + "name": "azure-core-cpp", + "default-features": false } + ] } + } } diff --git a/sdk/core/azure-core/vcpkg/Config.cmake.in b/sdk/core/azure-core/vcpkg/Config.cmake.in index fc0bf3d98d..8b22867ca2 100644 --- a/sdk/core/azure-core/vcpkg/Config.cmake.in +++ b/sdk/core/azure-core/vcpkg/Config.cmake.in @@ -10,7 +10,9 @@ if(@BUILD_TRANSPORT_CURL@) find_dependency(CURL @CURL_MIN_REQUIRED_VERSION@) endif() -if(NOT WIN32) +if(WIN32) + find_dependency(wil) +else() find_dependency(OpenSSL) endif() diff --git a/sdk/core/azure-core/vcpkg/vcpkg.json b/sdk/core/azure-core/vcpkg/vcpkg.json index 5c53637162..bc300bd5c9 100644 --- a/sdk/core/azure-core/vcpkg/vcpkg.json +++ b/sdk/core/azure-core/vcpkg/vcpkg.json @@ -22,6 +22,10 @@ { "name": "vcpkg-cmake-config", "host": true + }, + { + "name": "wil", + "platform": "windows" } ], "default-features": [ diff --git a/sdk/core/ci.yml b/sdk/core/ci.yml index 71fea0a3d9..7edefdcf61 100644 --- a/sdk/core/ci.yml +++ b/sdk/core/ci.yml @@ -41,7 +41,7 @@ stages: LiveTestCtestRegex: azure-core.|json-test LiveTestTimeoutInMinutes: 90 # default is 60 min. We need a little longer on worst case for Win+jsonTests LineCoverageTarget: 93 - BranchCoverageTarget: 55 + BranchCoverageTarget: 50 PreTestSteps: - task: UsePythonVersion@0 displayName: 'Use Python 3' @@ -73,8 +73,7 @@ stages: - pwsh: | docker build -t squid-local $(Build.SourcesDirectory)/sdk/core/azure-core/test/ut/proxy_tests/localproxy docker build -t squid-local.passwd $(Build.SourcesDirectory)/sdk/core/azure-core/test/ut/proxy_tests/localproxy.passwd - docker run --rm -d -p 3128:3128 squid-local - docker run --rm -d -p 3129:3129 squid-local.passwd + $(Build.SourcesDirectory)/sdk/core/azure-core/test/ut/proxy_tests/runproxy.ps1 displayName: Launch Linux Docker container proxy # If we're on Ubuntu and running proxy tests, build and launch a local squid proxy condition: and(succeeded(), contains(variables['Agent.OS'], 'linux'), variables.RunProxyTests, contains(variables.CmakeArgs, 'BUILD_TESTING=ON')) @@ -99,7 +98,7 @@ stages: parameters: runProxy: true targetVersion: 1.0.0-dev.20220810.2 - + condition: and(succeeded(), contains(variables.CmakeArgs, 'BUILD_TESTING=ON')) PostTestSteps: # Shut down the test server. This uses curl to send a request to the "terminateserver" websocket endpoint. # When the test server receives a request on terminateserver, it shuts down gracefully. diff --git a/sdk/core/perf.yml b/sdk/core/perf.yml new file mode 100644 index 0000000000..a8494272b1 --- /dev/null +++ b/sdk/core/perf.yml @@ -0,0 +1,32 @@ +parameters: +- name: PackageVersions + displayName: PackageVersions (regex of package versions to run) + type: string + default: 'source' +- name: Tests + displayName: Tests (regex of tests to run) + type: string + default: '^(extendedOptions)$' +- name: Arguments + displayName: Arguments (regex of arguments to run) + type: string + default: '.*' +- name: Iterations + displayName: Iterations (times to run each test) + type: number + default: '5' +- name: AdditionalArguments + displayName: AdditionalArguments (passed to PerfAutomation) + type: string + default: ' ' + +extends: + template: /eng/pipelines/templates/jobs/perf.yml + parameters: + ServiceDirectory: core + Services: "^core$" + PackageVersions: ${{ parameters.PackageVersions }} + Tests: ${{ parameters.Tests }} + Arguments: ${{ parameters.Arguments }} + Iterations: ${{ parameters.Iterations }} + AdditionalArguments: ${{ parameters.AdditionalArguments }} diff --git a/sdk/keyvault/azure-security-keyvault-certificates/test/ut/certificate_client_test.cpp b/sdk/keyvault/azure-security-keyvault-certificates/test/ut/certificate_client_test.cpp index b9e8d92f74..849919c8e9 100644 --- a/sdk/keyvault/azure-security-keyvault-certificates/test/ut/certificate_client_test.cpp +++ b/sdk/keyvault/azure-security-keyvault-certificates/test/ut/certificate_client_test.cpp @@ -27,7 +27,9 @@ TEST_F(KeyVaultCertificateClientTest, CreateCertificate) { auto response = client.StartDeleteCertificate(certificateName); + // double polling should not have an impact on the result auto result = response.PollUntilDone(m_defaultWait); + result = response.PollUntilDone(m_defaultWait); EXPECT_EQ(result.Value.Name(), certificateName); EXPECT_EQ(result.Value.Properties.Enabled.Value(), true); EXPECT_NE(result.Value.RecoveryIdUrl.length(), size_t(0)); @@ -64,8 +66,9 @@ TEST_F(KeyVaultCertificateClientTest, CreateCertificateResumeToken) auto fromToken = CreateCertificateOperation::CreateFromResumeToken(response.GetResumeToken(), client); - + // double polling should not have an impact on the result auto result = fromToken.PollUntilDone(m_defaultWait); + result = fromToken.PollUntilDone(m_defaultWait); auto cert = client.GetCertificate(certificateName); EXPECT_EQ(cert.Value.Name(), options.Properties.Name); @@ -192,7 +195,9 @@ TEST_F(KeyVaultCertificateClientTest, GetDeletedCertificate) } { auto response = client.StartRecoverDeletedCertificate(certificateName); + // double polling should not have an impact on the result auto result = response.PollUntilDone(m_defaultWait); + result = response.PollUntilDone(m_defaultWait); EXPECT_EQ(result.Value.Name(), certificateName); } { diff --git a/sdk/keyvault/azure-security-keyvault-certificates/test/ut/recordings/KeyVaultCertificateClientTest.CreateCertificate.json b/sdk/keyvault/azure-security-keyvault-certificates/test/ut/recordings/KeyVaultCertificateClientTest.CreateCertificate.json index 8d389a3920..214481e4cd 100644 --- a/sdk/keyvault/azure-security-keyvault-certificates/test/ut/recordings/KeyVaultCertificateClientTest.CreateCertificate.json +++ b/sdk/keyvault/azure-security-keyvault-certificates/test/ut/recordings/KeyVaultCertificateClientTest.CreateCertificate.json @@ -3,217 +3,244 @@ { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-certificates/4.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", - "x-ms-client-request-id": "209cf819-6de2-44e5-5183-a78e57f9a56b" + "user-agent": "azsdk-cpp-keyvault-certificates/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "bff9cf80-18eb-4038-7922-8ffde8839a77" }, "Method": "POST", "Response": { - "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending\",\"issuer\":{\"name\":\"Self\"},\"csr\":\"MIICfzCCAWcCAQAwDjEMMAoGA1UEAxMDeHl6MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvdA0sYYK4VZzuDRpce8x2kcefPFSRN2hkIuEJzjGCZYI1NW4Ilp57hEe1vuRXHWD9yjB3EtAzjlcXlFq6XS7VQJN1j/WwYFL3dc8utvbsdM5iH1h1+nmnQIsJLn3HC1Tjd1+WSol/uTzOSLJgAV26UbttISAruc5/CKSeljsrFM3IsOXkGXksW28shFJnFGcqeBr8qiyOkCbMNLfLpj+RFFFzR/0nvOBcA8s7rSC4W2ItSbj9bQ6TOk72emAbtx/5LfbUrXMuB3QwT0G29BZsoRRtMlZ5E3HO8vUvUZoY0fPAZxuc6TtEiNiCVMxKAvkvNw5obuIxGk13VMs+9yrcQIDAQABoCwwKgYJKoZIhvcNAQkOMR0wGzAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAGNkaupopx+3u+qn+/5/QhJ3oEBMOcocKGp1R79OSiwfiOepDIyLFQFSkGqZ7HTNQicxE909R9Vgn24ykGSdLwdfYuYL/KuM84e7LoT+L63LdkQXT9JzdrQYP0BCDuuBeKqnFYgQq3EfmsQwKUXF2A03V15bToYro2jD+oDAIRYowBqcGlUtzxSXsTSkFcA3ENoDrLJ2mVSlTo04zf+kRmrlXaGxjX+A0Fyq5i50u4MYP0lzh+ekVOAcDUe6IXrPiFwYSReqvElLgY2RbG9gJiuDB3NOmrabwwC6m8BfN9q0WIn+sMjK7gfW4KcZTvtvxCfqu+UX2CkM8LvyaSiEX6w==\",\"cancellation_requested\":false,\"status\":\"inProgress\",\"status_details\":\"Pending certificate created. Certificate request is in progress. This may take some time based on the issuer provider. Please check again later.\",\"request_id\":\"f5ec7c05820942c4a9472836f5de742d\"}", + "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending\",\"issuer\":{\"name\":\"Self\"},\"csr\":\"MIICfzCCAWcCAQAwDjEMMAoGA1UEAxMDeHl6MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr/iVL+sdbuOz71lrm7/39h4CCNEXxvBPtXvX7Q6orV8iZsQix4pIyxaL/7thSzBZwBlzztJ/JgjxYFbaN9YwJv6CZvIGnsJR3jjv+IYiDdPm7frk7O35R+TWsb0TGkjmYlMqhvO004QTbFcrYAcrFRALrqjZEzcnz/dR/pBd355yNl/IMaE4Bd1B2stOYx6q1cmn/Xy4KXPiwAFMAroN3YuylPPb6UzAmxT+4L+Kv2pHNE0n5aa7D57QDh/Rkk0tJDMmJLI8NsmzXqH2h+Xn/TKDtwYCH13sJJ98hsLYpXdueIbJ3md6JdizcTGYPWfVrQn8ybkETmaE7inurEXRIQIDAQABoCwwKgYJKoZIhvcNAQkOMR0wGzAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAW3vTP4U+Gd7kSqHb+rag/wjyMhLIEThiEjFULyO1WGgHKT0dXVHcIyeA+K0ioCowxfubecN3WShW3/sr1ejaXUbG+Mff4dZAda0j/N+ZzoR4FhnEiFuv5cdYcL3Pq2LemFgAfpq7vgKC9SZGS7rqB+rNYXFvgH8KdINMGh8qFX5fP9b0TTsT+XQ1okkoRBSusE0obFltVjD7FJSxZi1DkMaSITplLacT7srNDzcMYcQxhOdZcQ8DJWGeat6AqQIr/22GSTDfvX+jvLbWJWAlnGNJvEIfvL+yofPRUKEA0MTZqA2spVp12PI3a+yli2HvCccixM+eH1tBzdgg4iCaKw==\",\"cancellation_requested\":false,\"status\":\"inProgress\",\"status_details\":\"Pending certificate created. Certificate request is in progress. This may take some time based on the issuer provider. Please check again later.\",\"request_id\":\"810025c09b9c4ea78d6edefb43517995\"}", + "REASON_PHRASE": "Accepted", "STATUS_CODE": "202", "cache-control": "no-cache", - "content-length": "1244", + "content-length": "1241", "content-type": "application/json; charset=utf-8", - "date": "Thu, 04 Nov 2021 20:46:48 GMT", + "date": "Tue, 20 Sep 2022 17:55:28 GMT", "expires": "-1", - "location": "https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending?api-version=7.3&request_id=f5ec7c05820942c4a9472836f5de742d", + "location": "https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending?api-version=7.3&request_id=810025c09b9c4ea78d6edefb43517995", "pragma": "no-cache", "retry-after": "10", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "209cf819-6de2-44e5-5183-a78e57f9a56b", + "x-ms-client-request-id": "bff9cf80-18eb-4038-7922-8ffde8839a77", "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "westus2", - "x-ms-keyvault-service-version": "1.9.150.1", - "x-ms-request-id": "de58b45f-844d-4478-9cec-80a57f4f83f1", - "x-powered-by": "ASP.NET" + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "819b2c05-ddb9-47e5-b5ee-59e2086e3c6e" }, "Url": "https://REDACTED.vault.azure.net/certificates/CreateCertificate/create?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-certificates/4.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", - "x-ms-client-request-id": "867ce581-9fd1-47cb-7578-03e22659c409" + "user-agent": "azsdk-cpp-keyvault-certificates/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "95d30aa8-016b-42ee-5dbf-b0b304604fa9" }, "Method": "GET", "Response": { - "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending\",\"issuer\":{\"name\":\"Self\"},\"csr\":\"MIICfzCCAWcCAQAwDjEMMAoGA1UEAxMDeHl6MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvdA0sYYK4VZzuDRpce8x2kcefPFSRN2hkIuEJzjGCZYI1NW4Ilp57hEe1vuRXHWD9yjB3EtAzjlcXlFq6XS7VQJN1j/WwYFL3dc8utvbsdM5iH1h1+nmnQIsJLn3HC1Tjd1+WSol/uTzOSLJgAV26UbttISAruc5/CKSeljsrFM3IsOXkGXksW28shFJnFGcqeBr8qiyOkCbMNLfLpj+RFFFzR/0nvOBcA8s7rSC4W2ItSbj9bQ6TOk72emAbtx/5LfbUrXMuB3QwT0G29BZsoRRtMlZ5E3HO8vUvUZoY0fPAZxuc6TtEiNiCVMxKAvkvNw5obuIxGk13VMs+9yrcQIDAQABoCwwKgYJKoZIhvcNAQkOMR0wGzAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAGNkaupopx+3u+qn+/5/QhJ3oEBMOcocKGp1R79OSiwfiOepDIyLFQFSkGqZ7HTNQicxE909R9Vgn24ykGSdLwdfYuYL/KuM84e7LoT+L63LdkQXT9JzdrQYP0BCDuuBeKqnFYgQq3EfmsQwKUXF2A03V15bToYro2jD+oDAIRYowBqcGlUtzxSXsTSkFcA3ENoDrLJ2mVSlTo04zf+kRmrlXaGxjX+A0Fyq5i50u4MYP0lzh+ekVOAcDUe6IXrPiFwYSReqvElLgY2RbG9gJiuDB3NOmrabwwC6m8BfN9q0WIn+sMjK7gfW4KcZTvtvxCfqu+UX2CkM8LvyaSiEX6w==\",\"cancellation_requested\":false,\"status\":\"inProgress\",\"status_details\":\"Pending certificate created. Certificate request is in progress. This may take some time based on the issuer provider. Please check again later.\",\"request_id\":\"f5ec7c05820942c4a9472836f5de742d\"}", + "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending\",\"issuer\":{\"name\":\"Self\"},\"csr\":\"MIICfzCCAWcCAQAwDjEMMAoGA1UEAxMDeHl6MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr/iVL+sdbuOz71lrm7/39h4CCNEXxvBPtXvX7Q6orV8iZsQix4pIyxaL/7thSzBZwBlzztJ/JgjxYFbaN9YwJv6CZvIGnsJR3jjv+IYiDdPm7frk7O35R+TWsb0TGkjmYlMqhvO004QTbFcrYAcrFRALrqjZEzcnz/dR/pBd355yNl/IMaE4Bd1B2stOYx6q1cmn/Xy4KXPiwAFMAroN3YuylPPb6UzAmxT+4L+Kv2pHNE0n5aa7D57QDh/Rkk0tJDMmJLI8NsmzXqH2h+Xn/TKDtwYCH13sJJ98hsLYpXdueIbJ3md6JdizcTGYPWfVrQn8ybkETmaE7inurEXRIQIDAQABoCwwKgYJKoZIhvcNAQkOMR0wGzAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAW3vTP4U+Gd7kSqHb+rag/wjyMhLIEThiEjFULyO1WGgHKT0dXVHcIyeA+K0ioCowxfubecN3WShW3/sr1ejaXUbG+Mff4dZAda0j/N+ZzoR4FhnEiFuv5cdYcL3Pq2LemFgAfpq7vgKC9SZGS7rqB+rNYXFvgH8KdINMGh8qFX5fP9b0TTsT+XQ1okkoRBSusE0obFltVjD7FJSxZi1DkMaSITplLacT7srNDzcMYcQxhOdZcQ8DJWGeat6AqQIr/22GSTDfvX+jvLbWJWAlnGNJvEIfvL+yofPRUKEA0MTZqA2spVp12PI3a+yli2HvCccixM+eH1tBzdgg4iCaKw==\",\"cancellation_requested\":false,\"status\":\"inProgress\",\"status_details\":\"Pending certificate created. Certificate request is in progress. This may take some time based on the issuer provider. Please check again later.\",\"request_id\":\"810025c09b9c4ea78d6edefb43517995\"}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "1244", + "content-length": "1241", "content-type": "application/json; charset=utf-8", - "date": "Thu, 04 Nov 2021 20:46:48 GMT", + "date": "Tue, 20 Sep 2022 17:55:28 GMT", "expires": "-1", "pragma": "no-cache", "retry-after": "10", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "867ce581-9fd1-47cb-7578-03e22659c409", + "x-ms-client-request-id": "95d30aa8-016b-42ee-5dbf-b0b304604fa9", "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "westus2", - "x-ms-keyvault-service-version": "1.9.150.1", - "x-ms-request-id": "a5d089cf-7853-4719-bc14-7e8b7ed9cf30", - "x-powered-by": "ASP.NET" + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "c776d6dc-2f9e-40c0-a11c-c8d3c9191503" }, "Url": "https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-certificates/4.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", - "x-ms-client-request-id": "666dd27c-e108-458c-70e7-021438b43b36" + "user-agent": "azsdk-cpp-keyvault-certificates/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "1b5ec751-8d33-46b6-4cc7-36937ea3411a" }, "Method": "GET", "Response": { - "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending\",\"issuer\":{\"name\":\"Self\"},\"csr\":\"MIICfzCCAWcCAQAwDjEMMAoGA1UEAxMDeHl6MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvdA0sYYK4VZzuDRpce8x2kcefPFSRN2hkIuEJzjGCZYI1NW4Ilp57hEe1vuRXHWD9yjB3EtAzjlcXlFq6XS7VQJN1j/WwYFL3dc8utvbsdM5iH1h1+nmnQIsJLn3HC1Tjd1+WSol/uTzOSLJgAV26UbttISAruc5/CKSeljsrFM3IsOXkGXksW28shFJnFGcqeBr8qiyOkCbMNLfLpj+RFFFzR/0nvOBcA8s7rSC4W2ItSbj9bQ6TOk72emAbtx/5LfbUrXMuB3QwT0G29BZsoRRtMlZ5E3HO8vUvUZoY0fPAZxuc6TtEiNiCVMxKAvkvNw5obuIxGk13VMs+9yrcQIDAQABoCwwKgYJKoZIhvcNAQkOMR0wGzAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAGNkaupopx+3u+qn+/5/QhJ3oEBMOcocKGp1R79OSiwfiOepDIyLFQFSkGqZ7HTNQicxE909R9Vgn24ykGSdLwdfYuYL/KuM84e7LoT+L63LdkQXT9JzdrQYP0BCDuuBeKqnFYgQq3EfmsQwKUXF2A03V15bToYro2jD+oDAIRYowBqcGlUtzxSXsTSkFcA3ENoDrLJ2mVSlTo04zf+kRmrlXaGxjX+A0Fyq5i50u4MYP0lzh+ekVOAcDUe6IXrPiFwYSReqvElLgY2RbG9gJiuDB3NOmrabwwC6m8BfN9q0WIn+sMjK7gfW4KcZTvtvxCfqu+UX2CkM8LvyaSiEX6w==\",\"cancellation_requested\":false,\"status\":\"completed\",\"target\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate\",\"request_id\":\"f5ec7c05820942c4a9472836f5de742d\"}", + "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending\",\"issuer\":{\"name\":\"Self\"},\"csr\":\"MIICfzCCAWcCAQAwDjEMMAoGA1UEAxMDeHl6MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr/iVL+sdbuOz71lrm7/39h4CCNEXxvBPtXvX7Q6orV8iZsQix4pIyxaL/7thSzBZwBlzztJ/JgjxYFbaN9YwJv6CZvIGnsJR3jjv+IYiDdPm7frk7O35R+TWsb0TGkjmYlMqhvO004QTbFcrYAcrFRALrqjZEzcnz/dR/pBd355yNl/IMaE4Bd1B2stOYx6q1cmn/Xy4KXPiwAFMAroN3YuylPPb6UzAmxT+4L+Kv2pHNE0n5aa7D57QDh/Rkk0tJDMmJLI8NsmzXqH2h+Xn/TKDtwYCH13sJJ98hsLYpXdueIbJ3md6JdizcTGYPWfVrQn8ybkETmaE7inurEXRIQIDAQABoCwwKgYJKoZIhvcNAQkOMR0wGzAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAW3vTP4U+Gd7kSqHb+rag/wjyMhLIEThiEjFULyO1WGgHKT0dXVHcIyeA+K0ioCowxfubecN3WShW3/sr1ejaXUbG+Mff4dZAda0j/N+ZzoR4FhnEiFuv5cdYcL3Pq2LemFgAfpq7vgKC9SZGS7rqB+rNYXFvgH8KdINMGh8qFX5fP9b0TTsT+XQ1okkoRBSusE0obFltVjD7FJSxZi1DkMaSITplLacT7srNDzcMYcQxhOdZcQ8DJWGeat6AqQIr/22GSTDfvX+jvLbWJWAlnGNJvEIfvL+yofPRUKEA0MTZqA2spVp12PI3a+yli2HvCccixM+eH1tBzdgg4iCaKw==\",\"cancellation_requested\":false,\"status\":\"completed\",\"target\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate\",\"request_id\":\"810025c09b9c4ea78d6edefb43517995\"}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "1159", + "content-length": "1153", "content-type": "application/json; charset=utf-8", - "date": "Thu, 04 Nov 2021 20:47:07 GMT", + "date": "Tue, 20 Sep 2022 17:55:49 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "666dd27c-e108-458c-70e7-021438b43b36", + "x-ms-client-request-id": "1b5ec751-8d33-46b6-4cc7-36937ea3411a", "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "westus2", - "x-ms-keyvault-service-version": "1.9.150.1", - "x-ms-request-id": "b6cda11a-d102-43f8-ae3f-8bf20ca97b8f", - "x-powered-by": "ASP.NET" + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "bc1680af-7c72-48df-a49b-f4b94f1ac03f" }, "Url": "https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-certificates/4.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", - "x-ms-client-request-id": "d84dbf40-55fe-45e4-5f89-4a0cbe172df6" + "user-agent": "azsdk-cpp-keyvault-certificates/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "1e6d38d5-036a-4a80-4217-ee8f35c31e7a" }, "Method": "GET", "Response": { - "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/82d46b4abee54341a9f987905959c109\",\"kid\":\"https://REDACTED.vault.azure.net/keys/CreateCertificate/82d46b4abee54341a9f987905959c109\",\"sid\":\"https://REDACTED.vault.azure.net/secrets/CreateCertificate/82d46b4abee54341a9f987905959c109\",\"x5t\":\"KWXTUZpR6ERVNlu94XckXYVL5vw\",\"cer\":\"MIIDAzCCAeugAwIBAgIQNol28XtySdGgjuPBkxH3gzANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDEwN4eXowHhcNMjExMTA0MjAzNjQ5WhcNMjIxMTA0MjA0NjQ5WjAOMQwwCgYDVQQDEwN4eXowggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC90DSxhgrhVnO4NGlx7zHaRx588VJE3aGQi4QnOMYJlgjU1bgiWnnuER7W+5FcdYP3KMHcS0DOOVxeUWrpdLtVAk3WP9bBgUvd1zy629ux0zmIfWHX6eadAiwkufccLVON3X5ZKiX+5PM5IsmABXbpRu20hICu5zn8IpJ6WOysUzciw5eQZeSxbbyyEUmcUZyp4GvyqLI6QJsw0t8umP5EUUXNH/Se84FwDyzutILhbYi1JuP1tDpM6TvZ6YBu3H/kt9tStcy4HdDBPQbb0FmyhFG0yVnkTcc7y9S9RmhjR88BnG5zpO0SI2IJUzEoC+S83Dmhu4jEaTXdUyz73KtxAgMBAAGjXTBbMA4GA1UdDwEB/wQEAwIFoDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFNlzR3iP4/+2qTG0zDhg67FLxE4gMB0GA1UdDgQWBBTZc0d4j+P/tqkxtMw4YOuxS8ROIDANBgkqhkiG9w0BAQsFAAOCAQEAQ03NWMsIKXA3RjoZig264CJejb9dKG59lTbWFzD8PkHXXrRRKlrg2EDUaiwMjadd5N1NnQSvFeXwc3ZuBQKPZ+UyTzVuMNOkuaAhJbF0Mm+ZaebUdgD0IZAAONGXDhw1CdrkqiYkLCpRwK3DREKmGyDRQ61wf5rWt8HNB9r/bcgyNqeoGAVSnTvB/k3bPpJjzllvJtVy1jhcJyU53iRYQFo0zaQ+Pjrsx8vYKthp3LCY2OAHubvHLc7Y+N7faMrn9sTGNJne17CmYKSnumJr/MZZv4YapzP25mKx1s1ijbI4yhuKnbt+PUOK1WogPC+wzqR8D+nLG2FUHz0D7I5GwA==\",\"attributes\":{\"enabled\":true,\"nbf\":1636058209,\"exp\":1667594809,\"created\":1636058809,\"updated\":1636058809,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90},\"tags\":{},\"policy\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/policy\",\"key_props\":{\"exportable\":true,\"kty\":\"RSA\",\"key_size\":2048,\"reuse_key\":false},\"secret_props\":{\"contentType\":\"application/x-pkcs12\"},\"x509_props\":{\"subject\":\"CN=xyz\",\"ekus\":[],\"key_usage\":[\"digitalSignature\",\"keyEncipherment\"],\"validity_months\":12,\"basic_constraints\":{\"ca\":false}},\"lifetime_actions\":[{\"trigger\":{\"lifetime_percentage\":80},\"action\":{\"action_type\":\"AutoRenew\"}}],\"issuer\":{\"name\":\"Self\"},\"attributes\":{\"enabled\":true,\"created\":1636058808,\"updated\":1636058808}},\"pending\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending\"}}", + "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/8838738fd6b14e2196728afba1f0b904\",\"kid\":\"https://REDACTED.vault.azure.net/keys/CreateCertificate/8838738fd6b14e2196728afba1f0b904\",\"sid\":\"https://REDACTED.vault.azure.net/secrets/CreateCertificate/8838738fd6b14e2196728afba1f0b904\",\"x5t\":\"1Nnwp-etSDsHqoeGYtba3V6Hm8w\",\"cer\":\"MIIDAzCCAeugAwIBAgIQZDJboT7CS/+/G4NOUl8FUzANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDEwN4eXowHhcNMjIwOTIwMTc0NTMwWhcNMjMwOTIwMTc1NTMwWjAOMQwwCgYDVQQDEwN4eXowggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCv+JUv6x1u47PvWWubv/f2HgII0RfG8E+1e9ftDqitXyJmxCLHikjLFov/u2FLMFnAGXPO0n8mCPFgVto31jAm/oJm8gaewlHeOO/4hiIN0+bt+uTs7flH5NaxvRMaSOZiUyqG87TThBNsVytgBysVEAuuqNkTNyfP91H+kF3fnnI2X8gxoTgF3UHay05jHqrVyaf9fLgpc+LAAUwCug3di7KU89vpTMCbFP7gv4q/akc0TSflprsPntAOH9GSTS0kMyYksjw2ybNeofaH5ef9MoO3BgIfXewkn3yGwtild254hsneZ3ol2LNxMZg9Z9WtCfzJuQROZoTuKe6sRdEhAgMBAAGjXTBbMA4GA1UdDwEB/wQEAwIFoDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFCo7fntN0lkRqlXZAO6zhkNvmp81MB0GA1UdDgQWBBQqO357TdJZEapV2QDus4ZDb5qfNTANBgkqhkiG9w0BAQsFAAOCAQEAGZ8TCEGSzaBIQN1zf6lhcDio1i2eL5N9xZ3IKFX1+MXMnDN0D1eCXjJm+3bQ4/qTc9QNWT1hBxDQob5+mIWZdHpRXetwD95CS5/OoGN6vVKjJm8oDGJdPsX5GQOCe2Ytpmd0NJJ/XHeW2UIFC2GU5MVVvMZONmx5lymrq0RKNpLi4h+BGtqwwfKsjmIBUkoydtTtU3rxud9PTi1Ih+ubw6OS9yNaawQ01NVo1yn28PQNkw28WdmZjt845PI14dmXU7gFtvRYqAc/jnKNmdn7tE+v0xpHhY4ZT2BDsqNRhd3UJCC6+B5CNkOYk3nDyf3KjMrQsQrUu7nxlTge5LurrA==\",\"attributes\":{\"enabled\":true,\"nbf\":1663695930,\"exp\":1695232530,\"created\":1663696530,\"updated\":1663696530,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90},\"tags\":{},\"policy\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/policy\",\"key_props\":{\"exportable\":true,\"kty\":\"RSA\",\"key_size\":2048,\"reuse_key\":false},\"secret_props\":{\"contentType\":\"application/x-pkcs12\"},\"x509_props\":{\"subject\":\"CN=xyz\",\"ekus\":[],\"key_usage\":[\"digitalSignature\",\"keyEncipherment\"],\"validity_months\":12,\"basic_constraints\":{\"ca\":false}},\"lifetime_actions\":[{\"trigger\":{\"lifetime_percentage\":80},\"action\":{\"action_type\":\"AutoRenew\"}}],\"issuer\":{\"name\":\"Self\"},\"attributes\":{\"enabled\":true,\"created\":1663696529,\"updated\":1663696529}},\"pending\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending\"}}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "2240", + "content-length": "2225", "content-type": "application/json; charset=utf-8", - "date": "Thu, 04 Nov 2021 20:47:07 GMT", + "date": "Tue, 20 Sep 2022 17:55:49 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "d84dbf40-55fe-45e4-5f89-4a0cbe172df6", + "x-ms-client-request-id": "1e6d38d5-036a-4a80-4217-ee8f35c31e7a", "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "westus2", - "x-ms-keyvault-service-version": "1.9.150.1", - "x-ms-request-id": "89c6292f-4cc4-407b-99bf-964a268cf867", - "x-powered-by": "ASP.NET" + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "72adba26-b32e-4ba8-9da1-4f8ea39570db" }, "Url": "https://REDACTED.vault.azure.net/certificates/CreateCertificate?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-certificates/4.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", - "x-ms-client-request-id": "eff1d06e-8fb2-4817-6fd1-e18ea9bf315f" + "user-agent": "azsdk-cpp-keyvault-certificates/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "a81d73c1-794c-4139-6b11-7801b2a75c4d" }, "Method": "DELETE", "Response": { - "BODY": "{\"recoveryId\":\"https://REDACTED.vault.azure.net/deletedcertificates/CreateCertificate\",\"deletedDate\":1636058828,\"scheduledPurgeDate\":1643834828,\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/82d46b4abee54341a9f987905959c109\",\"kid\":\"https://REDACTED.vault.azure.net/keys/CreateCertificate/82d46b4abee54341a9f987905959c109\",\"sid\":\"https://REDACTED.vault.azure.net/secrets/CreateCertificate/82d46b4abee54341a9f987905959c109\",\"x5t\":\"KWXTUZpR6ERVNlu94XckXYVL5vw\",\"cer\":\"MIIDAzCCAeugAwIBAgIQNol28XtySdGgjuPBkxH3gzANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDEwN4eXowHhcNMjExMTA0MjAzNjQ5WhcNMjIxMTA0MjA0NjQ5WjAOMQwwCgYDVQQDEwN4eXowggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC90DSxhgrhVnO4NGlx7zHaRx588VJE3aGQi4QnOMYJlgjU1bgiWnnuER7W+5FcdYP3KMHcS0DOOVxeUWrpdLtVAk3WP9bBgUvd1zy629ux0zmIfWHX6eadAiwkufccLVON3X5ZKiX+5PM5IsmABXbpRu20hICu5zn8IpJ6WOysUzciw5eQZeSxbbyyEUmcUZyp4GvyqLI6QJsw0t8umP5EUUXNH/Se84FwDyzutILhbYi1JuP1tDpM6TvZ6YBu3H/kt9tStcy4HdDBPQbb0FmyhFG0yVnkTcc7y9S9RmhjR88BnG5zpO0SI2IJUzEoC+S83Dmhu4jEaTXdUyz73KtxAgMBAAGjXTBbMA4GA1UdDwEB/wQEAwIFoDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFNlzR3iP4/+2qTG0zDhg67FLxE4gMB0GA1UdDgQWBBTZc0d4j+P/tqkxtMw4YOuxS8ROIDANBgkqhkiG9w0BAQsFAAOCAQEAQ03NWMsIKXA3RjoZig264CJejb9dKG59lTbWFzD8PkHXXrRRKlrg2EDUaiwMjadd5N1NnQSvFeXwc3ZuBQKPZ+UyTzVuMNOkuaAhJbF0Mm+ZaebUdgD0IZAAONGXDhw1CdrkqiYkLCpRwK3DREKmGyDRQ61wf5rWt8HNB9r/bcgyNqeoGAVSnTvB/k3bPpJjzllvJtVy1jhcJyU53iRYQFo0zaQ+Pjrsx8vYKthp3LCY2OAHubvHLc7Y+N7faMrn9sTGNJne17CmYKSnumJr/MZZv4YapzP25mKx1s1ijbI4yhuKnbt+PUOK1WogPC+wzqR8D+nLG2FUHz0D7I5GwA==\",\"attributes\":{\"enabled\":true,\"nbf\":1636058209,\"exp\":1667594809,\"created\":1636058809,\"updated\":1636058809,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90},\"tags\":{},\"policy\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/policy\",\"key_props\":{\"exportable\":true,\"kty\":\"RSA\",\"key_size\":2048,\"reuse_key\":false},\"secret_props\":{\"contentType\":\"application/x-pkcs12\"},\"x509_props\":{\"subject\":\"CN=xyz\",\"ekus\":[],\"key_usage\":[\"digitalSignature\",\"keyEncipherment\"],\"validity_months\":12,\"basic_constraints\":{\"ca\":false}},\"lifetime_actions\":[{\"trigger\":{\"lifetime_percentage\":80},\"action\":{\"action_type\":\"AutoRenew\"}}],\"issuer\":{\"name\":\"Self\"},\"attributes\":{\"enabled\":true,\"created\":1636058808,\"updated\":1636058808}},\"pending\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending\"}}", + "BODY": "{\"recoveryId\":\"https://REDACTED.vault.azure.net/deletedcertificates/CreateCertificate\",\"deletedDate\":1663696549,\"scheduledPurgeDate\":1671472549,\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/8838738fd6b14e2196728afba1f0b904\",\"kid\":\"https://REDACTED.vault.azure.net/keys/CreateCertificate/8838738fd6b14e2196728afba1f0b904\",\"sid\":\"https://REDACTED.vault.azure.net/secrets/CreateCertificate/8838738fd6b14e2196728afba1f0b904\",\"x5t\":\"1Nnwp-etSDsHqoeGYtba3V6Hm8w\",\"cer\":\"MIIDAzCCAeugAwIBAgIQZDJboT7CS/+/G4NOUl8FUzANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDEwN4eXowHhcNMjIwOTIwMTc0NTMwWhcNMjMwOTIwMTc1NTMwWjAOMQwwCgYDVQQDEwN4eXowggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCv+JUv6x1u47PvWWubv/f2HgII0RfG8E+1e9ftDqitXyJmxCLHikjLFov/u2FLMFnAGXPO0n8mCPFgVto31jAm/oJm8gaewlHeOO/4hiIN0+bt+uTs7flH5NaxvRMaSOZiUyqG87TThBNsVytgBysVEAuuqNkTNyfP91H+kF3fnnI2X8gxoTgF3UHay05jHqrVyaf9fLgpc+LAAUwCug3di7KU89vpTMCbFP7gv4q/akc0TSflprsPntAOH9GSTS0kMyYksjw2ybNeofaH5ef9MoO3BgIfXewkn3yGwtild254hsneZ3ol2LNxMZg9Z9WtCfzJuQROZoTuKe6sRdEhAgMBAAGjXTBbMA4GA1UdDwEB/wQEAwIFoDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFCo7fntN0lkRqlXZAO6zhkNvmp81MB0GA1UdDgQWBBQqO357TdJZEapV2QDus4ZDb5qfNTANBgkqhkiG9w0BAQsFAAOCAQEAGZ8TCEGSzaBIQN1zf6lhcDio1i2eL5N9xZ3IKFX1+MXMnDN0D1eCXjJm+3bQ4/qTc9QNWT1hBxDQob5+mIWZdHpRXetwD95CS5/OoGN6vVKjJm8oDGJdPsX5GQOCe2Ytpmd0NJJ/XHeW2UIFC2GU5MVVvMZONmx5lymrq0RKNpLi4h+BGtqwwfKsjmIBUkoydtTtU3rxud9PTi1Ih+ubw6OS9yNaawQ01NVo1yn28PQNkw28WdmZjt845PI14dmXU7gFtvRYqAc/jnKNmdn7tE+v0xpHhY4ZT2BDsqNRhd3UJCC6+B5CNkOYk3nDyf3KjMrQsQrUu7nxlTge5LurrA==\",\"attributes\":{\"enabled\":true,\"nbf\":1663695930,\"exp\":1695232530,\"created\":1663696530,\"updated\":1663696530,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90},\"tags\":{},\"policy\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/policy\",\"key_props\":{\"exportable\":true,\"kty\":\"RSA\",\"key_size\":2048,\"reuse_key\":false},\"secret_props\":{\"contentType\":\"application/x-pkcs12\"},\"x509_props\":{\"subject\":\"CN=xyz\",\"ekus\":[],\"key_usage\":[\"digitalSignature\",\"keyEncipherment\"],\"validity_months\":12,\"basic_constraints\":{\"ca\":false}},\"lifetime_actions\":[{\"trigger\":{\"lifetime_percentage\":80},\"action\":{\"action_type\":\"AutoRenew\"}}],\"issuer\":{\"name\":\"Self\"},\"attributes\":{\"enabled\":true,\"created\":1663696529,\"updated\":1663696529}},\"pending\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending\"}}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "2388", + "content-length": "2370", "content-type": "application/json; charset=utf-8", - "date": "Thu, 04 Nov 2021 20:47:08 GMT", + "date": "Tue, 20 Sep 2022 17:55:49 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "eff1d06e-8fb2-4817-6fd1-e18ea9bf315f", + "x-ms-client-request-id": "a81d73c1-794c-4139-6b11-7801b2a75c4d", "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "westus2", - "x-ms-keyvault-service-version": "1.9.150.1", - "x-ms-request-id": "193a3b69-dc9d-4895-b4b2-3f2c3c008a0e", - "x-powered-by": "ASP.NET" + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "0188f2b5-4be8-4b2d-9dc3-3f251ea94151" }, "Url": "https://REDACTED.vault.azure.net/certificates/CreateCertificate?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-certificates/4.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", - "x-ms-client-request-id": "7fbc8be7-b592-4fcb-4fec-d53719a05134" + "user-agent": "azsdk-cpp-keyvault-certificates/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "f544226c-319b-41d3-44b2-9dbcbc7117d7" }, "Method": "GET", "Response": { "BODY": "{\"error\":{\"code\":\"CertificateNotFound\",\"message\":\"Deleted Certificate not found: CreateCertificate\"}}", + "REASON_PHRASE": "Not Found", "STATUS_CODE": "404", "cache-control": "no-cache", "content-length": "101", "content-type": "application/json; charset=utf-8", - "date": "Thu, 04 Nov 2021 20:47:08 GMT", + "date": "Tue, 20 Sep 2022 17:55:49 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "7fbc8be7-b592-4fcb-4fec-d53719a05134", + "x-ms-client-request-id": "f544226c-319b-41d3-44b2-9dbcbc7117d7", "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "westus2", - "x-ms-keyvault-service-version": "1.9.150.1", - "x-ms-request-id": "85060c6e-4792-40c0-bd43-dde17727e737", - "x-powered-by": "ASP.NET" + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "1d446d1b-5b1f-4903-974c-ebb527d56a1f" }, "Url": "https://REDACTED.vault.azure.net/deletedcertificates/CreateCertificate?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-certificates/4.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", - "x-ms-client-request-id": "6992f9ca-7d1a-4f60-5e6d-36b6abf740b4" + "user-agent": "azsdk-cpp-keyvault-certificates/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "d5cf6029-d3a6-4a39-66e8-1083c6cf4525" }, "Method": "GET", "Response": { - "BODY": "{\"recoveryId\":\"https://REDACTED.vault.azure.net/deletedcertificates/CreateCertificate\",\"deletedDate\":1636058828,\"scheduledPurgeDate\":1643834828,\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/82d46b4abee54341a9f987905959c109\",\"kid\":\"https://REDACTED.vault.azure.net/keys/CreateCertificate/82d46b4abee54341a9f987905959c109\",\"sid\":\"https://REDACTED.vault.azure.net/secrets/CreateCertificate/82d46b4abee54341a9f987905959c109\",\"x5t\":\"KWXTUZpR6ERVNlu94XckXYVL5vw\",\"cer\":\"MIIDAzCCAeugAwIBAgIQNol28XtySdGgjuPBkxH3gzANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDEwN4eXowHhcNMjExMTA0MjAzNjQ5WhcNMjIxMTA0MjA0NjQ5WjAOMQwwCgYDVQQDEwN4eXowggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC90DSxhgrhVnO4NGlx7zHaRx588VJE3aGQi4QnOMYJlgjU1bgiWnnuER7W+5FcdYP3KMHcS0DOOVxeUWrpdLtVAk3WP9bBgUvd1zy629ux0zmIfWHX6eadAiwkufccLVON3X5ZKiX+5PM5IsmABXbpRu20hICu5zn8IpJ6WOysUzciw5eQZeSxbbyyEUmcUZyp4GvyqLI6QJsw0t8umP5EUUXNH/Se84FwDyzutILhbYi1JuP1tDpM6TvZ6YBu3H/kt9tStcy4HdDBPQbb0FmyhFG0yVnkTcc7y9S9RmhjR88BnG5zpO0SI2IJUzEoC+S83Dmhu4jEaTXdUyz73KtxAgMBAAGjXTBbMA4GA1UdDwEB/wQEAwIFoDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFNlzR3iP4/+2qTG0zDhg67FLxE4gMB0GA1UdDgQWBBTZc0d4j+P/tqkxtMw4YOuxS8ROIDANBgkqhkiG9w0BAQsFAAOCAQEAQ03NWMsIKXA3RjoZig264CJejb9dKG59lTbWFzD8PkHXXrRRKlrg2EDUaiwMjadd5N1NnQSvFeXwc3ZuBQKPZ+UyTzVuMNOkuaAhJbF0Mm+ZaebUdgD0IZAAONGXDhw1CdrkqiYkLCpRwK3DREKmGyDRQ61wf5rWt8HNB9r/bcgyNqeoGAVSnTvB/k3bPpJjzllvJtVy1jhcJyU53iRYQFo0zaQ+Pjrsx8vYKthp3LCY2OAHubvHLc7Y+N7faMrn9sTGNJne17CmYKSnumJr/MZZv4YapzP25mKx1s1ijbI4yhuKnbt+PUOK1WogPC+wzqR8D+nLG2FUHz0D7I5GwA==\",\"attributes\":{\"enabled\":true,\"nbf\":1636058209,\"exp\":1667594809,\"created\":1636058809,\"updated\":1636058809,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90},\"tags\":{},\"policy\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/policy\",\"key_props\":{\"exportable\":true,\"kty\":\"RSA\",\"key_size\":2048,\"reuse_key\":false},\"secret_props\":{\"contentType\":\"application/x-pkcs12\"},\"x509_props\":{\"subject\":\"CN=xyz\",\"ekus\":[],\"key_usage\":[\"digitalSignature\",\"keyEncipherment\"],\"validity_months\":12,\"basic_constraints\":{\"ca\":false}},\"lifetime_actions\":[{\"trigger\":{\"lifetime_percentage\":80},\"action\":{\"action_type\":\"AutoRenew\"}}],\"issuer\":{\"name\":\"Self\"},\"attributes\":{\"enabled\":true,\"created\":1636058808,\"updated\":1636058808}},\"pending\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending\"}}", + "BODY": "{\"recoveryId\":\"https://REDACTED.vault.azure.net/deletedcertificates/CreateCertificate\",\"deletedDate\":1663696549,\"scheduledPurgeDate\":1671472549,\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/8838738fd6b14e2196728afba1f0b904\",\"kid\":\"https://REDACTED.vault.azure.net/keys/CreateCertificate/8838738fd6b14e2196728afba1f0b904\",\"sid\":\"https://REDACTED.vault.azure.net/secrets/CreateCertificate/8838738fd6b14e2196728afba1f0b904\",\"x5t\":\"1Nnwp-etSDsHqoeGYtba3V6Hm8w\",\"cer\":\"MIIDAzCCAeugAwIBAgIQZDJboT7CS/+/G4NOUl8FUzANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDEwN4eXowHhcNMjIwOTIwMTc0NTMwWhcNMjMwOTIwMTc1NTMwWjAOMQwwCgYDVQQDEwN4eXowggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCv+JUv6x1u47PvWWubv/f2HgII0RfG8E+1e9ftDqitXyJmxCLHikjLFov/u2FLMFnAGXPO0n8mCPFgVto31jAm/oJm8gaewlHeOO/4hiIN0+bt+uTs7flH5NaxvRMaSOZiUyqG87TThBNsVytgBysVEAuuqNkTNyfP91H+kF3fnnI2X8gxoTgF3UHay05jHqrVyaf9fLgpc+LAAUwCug3di7KU89vpTMCbFP7gv4q/akc0TSflprsPntAOH9GSTS0kMyYksjw2ybNeofaH5ef9MoO3BgIfXewkn3yGwtild254hsneZ3ol2LNxMZg9Z9WtCfzJuQROZoTuKe6sRdEhAgMBAAGjXTBbMA4GA1UdDwEB/wQEAwIFoDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFCo7fntN0lkRqlXZAO6zhkNvmp81MB0GA1UdDgQWBBQqO357TdJZEapV2QDus4ZDb5qfNTANBgkqhkiG9w0BAQsFAAOCAQEAGZ8TCEGSzaBIQN1zf6lhcDio1i2eL5N9xZ3IKFX1+MXMnDN0D1eCXjJm+3bQ4/qTc9QNWT1hBxDQob5+mIWZdHpRXetwD95CS5/OoGN6vVKjJm8oDGJdPsX5GQOCe2Ytpmd0NJJ/XHeW2UIFC2GU5MVVvMZONmx5lymrq0RKNpLi4h+BGtqwwfKsjmIBUkoydtTtU3rxud9PTi1Ih+ubw6OS9yNaawQ01NVo1yn28PQNkw28WdmZjt845PI14dmXU7gFtvRYqAc/jnKNmdn7tE+v0xpHhY4ZT2BDsqNRhd3UJCC6+B5CNkOYk3nDyf3KjMrQsQrUu7nxlTge5LurrA==\",\"attributes\":{\"enabled\":true,\"nbf\":1663695930,\"exp\":1695232530,\"created\":1663696530,\"updated\":1663696530,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90},\"tags\":{},\"policy\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/policy\",\"key_props\":{\"exportable\":true,\"kty\":\"RSA\",\"key_size\":2048,\"reuse_key\":false},\"secret_props\":{\"contentType\":\"application/x-pkcs12\"},\"x509_props\":{\"subject\":\"CN=xyz\",\"ekus\":[],\"key_usage\":[\"digitalSignature\",\"keyEncipherment\"],\"validity_months\":12,\"basic_constraints\":{\"ca\":false}},\"lifetime_actions\":[{\"trigger\":{\"lifetime_percentage\":80},\"action\":{\"action_type\":\"AutoRenew\"}}],\"issuer\":{\"name\":\"Self\"},\"attributes\":{\"enabled\":true,\"created\":1663696529,\"updated\":1663696529}},\"pending\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending\"}}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "2388", + "content-length": "2370", "content-type": "application/json; charset=utf-8", - "date": "Thu, 04 Nov 2021 20:47:28 GMT", + "date": "Tue, 20 Sep 2022 17:56:10 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "6992f9ca-7d1a-4f60-5e6d-36b6abf740b4", + "x-ms-client-request-id": "d5cf6029-d3a6-4a39-66e8-1083c6cf4525", "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "westus2", - "x-ms-keyvault-service-version": "1.9.150.1", - "x-ms-request-id": "663d7a7a-ff04-4529-ba9f-4013a8904547", - "x-powered-by": "ASP.NET" + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "a5b24c7d-18c7-4ae1-acba-98b7a7de8d28" }, "Url": "https://REDACTED.vault.azure.net/deletedcertificates/CreateCertificate?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-certificates/4.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", - "x-ms-client-request-id": "52935bda-fdf1-4055-5140-afeeccbdb2ab" + "user-agent": "azsdk-cpp-keyvault-certificates/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "d89201cb-eda0-4c11-4a15-1140b7a5983b" + }, + "Method": "GET", + "Response": { + "BODY": "{\"recoveryId\":\"https://REDACTED.vault.azure.net/deletedcertificates/CreateCertificate\",\"deletedDate\":1663696549,\"scheduledPurgeDate\":1671472549,\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/8838738fd6b14e2196728afba1f0b904\",\"kid\":\"https://REDACTED.vault.azure.net/keys/CreateCertificate/8838738fd6b14e2196728afba1f0b904\",\"sid\":\"https://REDACTED.vault.azure.net/secrets/CreateCertificate/8838738fd6b14e2196728afba1f0b904\",\"x5t\":\"1Nnwp-etSDsHqoeGYtba3V6Hm8w\",\"cer\":\"MIIDAzCCAeugAwIBAgIQZDJboT7CS/+/G4NOUl8FUzANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDEwN4eXowHhcNMjIwOTIwMTc0NTMwWhcNMjMwOTIwMTc1NTMwWjAOMQwwCgYDVQQDEwN4eXowggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCv+JUv6x1u47PvWWubv/f2HgII0RfG8E+1e9ftDqitXyJmxCLHikjLFov/u2FLMFnAGXPO0n8mCPFgVto31jAm/oJm8gaewlHeOO/4hiIN0+bt+uTs7flH5NaxvRMaSOZiUyqG87TThBNsVytgBysVEAuuqNkTNyfP91H+kF3fnnI2X8gxoTgF3UHay05jHqrVyaf9fLgpc+LAAUwCug3di7KU89vpTMCbFP7gv4q/akc0TSflprsPntAOH9GSTS0kMyYksjw2ybNeofaH5ef9MoO3BgIfXewkn3yGwtild254hsneZ3ol2LNxMZg9Z9WtCfzJuQROZoTuKe6sRdEhAgMBAAGjXTBbMA4GA1UdDwEB/wQEAwIFoDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFCo7fntN0lkRqlXZAO6zhkNvmp81MB0GA1UdDgQWBBQqO357TdJZEapV2QDus4ZDb5qfNTANBgkqhkiG9w0BAQsFAAOCAQEAGZ8TCEGSzaBIQN1zf6lhcDio1i2eL5N9xZ3IKFX1+MXMnDN0D1eCXjJm+3bQ4/qTc9QNWT1hBxDQob5+mIWZdHpRXetwD95CS5/OoGN6vVKjJm8oDGJdPsX5GQOCe2Ytpmd0NJJ/XHeW2UIFC2GU5MVVvMZONmx5lymrq0RKNpLi4h+BGtqwwfKsjmIBUkoydtTtU3rxud9PTi1Ih+ubw6OS9yNaawQ01NVo1yn28PQNkw28WdmZjt845PI14dmXU7gFtvRYqAc/jnKNmdn7tE+v0xpHhY4ZT2BDsqNRhd3UJCC6+B5CNkOYk3nDyf3KjMrQsQrUu7nxlTge5LurrA==\",\"attributes\":{\"enabled\":true,\"nbf\":1663695930,\"exp\":1695232530,\"created\":1663696530,\"updated\":1663696530,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90},\"tags\":{},\"policy\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/policy\",\"key_props\":{\"exportable\":true,\"kty\":\"RSA\",\"key_size\":2048,\"reuse_key\":false},\"secret_props\":{\"contentType\":\"application/x-pkcs12\"},\"x509_props\":{\"subject\":\"CN=xyz\",\"ekus\":[],\"key_usage\":[\"digitalSignature\",\"keyEncipherment\"],\"validity_months\":12,\"basic_constraints\":{\"ca\":false}},\"lifetime_actions\":[{\"trigger\":{\"lifetime_percentage\":80},\"action\":{\"action_type\":\"AutoRenew\"}}],\"issuer\":{\"name\":\"Self\"},\"attributes\":{\"enabled\":true,\"created\":1663696529,\"updated\":1663696529}},\"pending\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificate/pending\"}}", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "cache-control": "no-cache", + "content-length": "2370", + "content-type": "application/json; charset=utf-8", + "date": "Tue, 20 Sep 2022 17:56:10 GMT", + "expires": "-1", + "pragma": "no-cache", + "strict-transport-security": "max-age=31536000;includeSubDomains", + "x-content-type-options": "nosniff", + "x-ms-client-request-id": "d89201cb-eda0-4c11-4a15-1140b7a5983b", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "503da419-fe4e-4d9a-8eb2-a52f50274dba" + }, + "Url": "https://REDACTED.vault.azure.net/deletedcertificates/CreateCertificate?api-version=7.3" + }, + { + "Headers": { + "content-type": "application/json", + "user-agent": "azsdk-cpp-keyvault-certificates/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "9e2286d8-fab9-431a-6de6-e439d32c13ca" }, "Method": "DELETE", "Response": { "BODY": "", + "REASON_PHRASE": "No Content", "STATUS_CODE": "204", "cache-control": "no-cache", - "date": "Thu, 04 Nov 2021 20:47:28 GMT", + "date": "Tue, 20 Sep 2022 17:56:10 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "52935bda-fdf1-4055-5140-afeeccbdb2ab", + "x-ms-client-request-id": "9e2286d8-fab9-431a-6de6-e439d32c13ca", "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "westus2", - "x-ms-keyvault-service-version": "1.9.150.1", - "x-ms-request-id": "72825a77-02d9-4d19-987c-6ced23609548", - "x-powered-by": "ASP.NET" + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "1e524b07-bd20-4cc8-9f72-c48e19f6990b" }, "Url": "https://REDACTED.vault.azure.net/deletedcertificates/CreateCertificate?api-version=7.3" } diff --git a/sdk/keyvault/azure-security-keyvault-certificates/test/ut/recordings/KeyVaultCertificateClientTest.CreateCertificateResumeToken.json b/sdk/keyvault/azure-security-keyvault-certificates/test/ut/recordings/KeyVaultCertificateClientTest.CreateCertificateResumeToken.json index 425f79ab79..603e52db36 100644 --- a/sdk/keyvault/azure-security-keyvault-certificates/test/ut/recordings/KeyVaultCertificateClientTest.CreateCertificateResumeToken.json +++ b/sdk/keyvault/azure-security-keyvault-certificates/test/ut/recordings/KeyVaultCertificateClientTest.CreateCertificateResumeToken.json @@ -3,166 +3,166 @@ { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-certificates/4.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", - "x-ms-client-request-id": "e9daf49a-f322-4d0c-51a6-028f2c4df54b" + "user-agent": "azsdk-cpp-keyvault-certificates/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "b4e25f20-1f86-4f89-4fcd-5a94a6c225ad" }, "Method": "POST", "Response": { - "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending\",\"issuer\":{\"name\":\"Self\"},\"csr\":\"MIICfzCCAWcCAQAwDjEMMAoGA1UEAxMDeHl6MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApcnvhdQkPvgLYc/WMEjnWmS9ulEiW8ol6jhEU1LojTd+vyD8D3LwDZCBfXaTkvjQW9y4+WKBhgsPD6dzb4Ux/6QJOEYo0YvGgHIO17fC3rfSRLGsEOUxRr9XkuypCXZbphmAvGteIgNa7+zJIcNVOAH4T6Sf1A2klprFy4wv7FQkddE9hgDGuI1CiajJxz81bbmPm2gSsXdFGpP5DZdAd7U5QZX/+TyX746+IitwKT3CQWGSnoAs9NPBs7WJILEu8QB7gnAU9UZBzcNUsIF9byCRkH90SEwrhvQOg/6GOozY3Epp7NZDJAS3D+lY6kzkMDIbLxoLSTB7DW5NCR81bQIDAQABoCwwKgYJKoZIhvcNAQkOMR0wGzAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAPXHYD4T4KE8UkwkP5HwgCRwwJ4WF8yKC8OnEDwPyykOB3Ms5lbMrP/jpuSTOq2q8mb4vRWNzH/xDq43FfI7vmnrpY2ulgrdKsuZOgW1mZU1LUaZ5q8oBCBL+2ZCzPz22Gc+M0ietda23NRuobE5cmuLScDrpJUL7sKRjeHc1xZc7ifGfn2zvu9XvGKNxlv/T2bE+HvmZrYnbY0ZAMicZo2eoPDpAasaiVRiO+cbS+6c3gv8M0lJ2wVGXrPRCHlLTE0FR0KujWu4GzsSj0lL7YS833Lu888FaGZsESVZN9xi0Xv4FI20YChB6839nAFpiG+FCUagS0UAnBw09OhxpGA==\",\"cancellation_requested\":false,\"status\":\"inProgress\",\"status_details\":\"Pending certificate created. Certificate request is in progress. This may take some time based on the issuer provider. Please check again later.\",\"request_id\":\"f268325b6f394e6a9ec36ffa1f374e0c\"}", + "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending\",\"issuer\":{\"name\":\"Self\"},\"csr\":\"MIICfzCCAWcCAQAwDjEMMAoGA1UEAxMDeHl6MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmdFrCtEikRMjll4Hbz1xP47Za1xDbd8FOsqoO+QIsSDBlYdKurMyPno3S2CVBGnni0lbC1d8bkvWNz8f8GywFnVa41hglskH1rLd80eBDVUN91oqnkyA8KzDokfYoBaFKQGOgNqAqC2FZMHUeFkjLNPcpDIy9r9cJ48cEY5vXsyY/fYalSZS1hnNHD9bowH9244Vcqh3FxYL60fpIPjMhRiJrvfDhTRkcVIQtsCG3iJ9Q3EGy5lrtJ8+IX/+n8wyzL9LT7Hc1liKTJPzBFPd0+n6vwU7ccZmh9vg80bhyA1JsVBOrcXQdreUlQju/xdjHSM082HZqnAmY8FsrXCCOQIDAQABoCwwKgYJKoZIhvcNAQkOMR0wGzAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAg8c/M+umH17alC1JTR78YPLwODzT6waO3H/nt+AX/GEP/yglQw/oTx8//K9r/Lg79KAoIqbPDnlXgxg5HBH8sk86Yk+DD+cISUUF2wk7RHFCpsUUKbWtydbrjZ/rZeOpz/DB4q30Wg/hI5krAmdMTvB7CUB157kF703gtW0J1VViScAPWEpQYDnaf/88DI0oozg6hirMnMZzYcnfdLb1fPCzf3b7P3tPq45FmgCw1rLIq1zkfOiGw+gjBhTR15L5WdQN9oNr2S92n0Bvklna4oHfRiJGh/NYdkWGVwDgvJQKrYazs1hbXw6TkuHtMfulSOK0HMbYM+OD00VaBfyS9A==\",\"cancellation_requested\":false,\"status\":\"inProgress\",\"status_details\":\"Pending certificate created. Certificate request is in progress. This may take some time based on the issuer provider. Please check again later.\",\"request_id\":\"1aceb91e04f9419c9957938fae4ae2f5\"}", + "REASON_PHRASE": "Accepted", "STATUS_CODE": "202", "cache-control": "no-cache", - "content-length": "1255", + "content-length": "1252", "content-type": "application/json; charset=utf-8", - "date": "Thu, 04 Nov 2021 20:47:30 GMT", + "date": "Tue, 20 Sep 2022 17:56:11 GMT", "expires": "-1", - "location": "https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending?api-version=7.3&request_id=f268325b6f394e6a9ec36ffa1f374e0c", + "location": "https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending?api-version=7.3&request_id=1aceb91e04f9419c9957938fae4ae2f5", "pragma": "no-cache", "retry-after": "10", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "e9daf49a-f322-4d0c-51a6-028f2c4df54b", + "x-ms-client-request-id": "b4e25f20-1f86-4f89-4fcd-5a94a6c225ad", "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "westus2", - "x-ms-keyvault-service-version": "1.9.150.1", - "x-ms-request-id": "1bf93c6a-fde7-437e-82f1-beb734c99b2f", - "x-powered-by": "ASP.NET" + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "19e4bc42-e73c-4eb1-a5c6-e5297e6e3405" }, "Url": "https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/create?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-certificates/4.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", - "x-ms-client-request-id": "0c7736a8-f5b7-4044-51bc-0de3f33df0ef" + "user-agent": "azsdk-cpp-keyvault-certificates/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "debe9c9f-f79d-406e-76a7-2562c723513d" }, "Method": "GET", "Response": { - "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending\",\"issuer\":{\"name\":\"Self\"},\"csr\":\"MIICfzCCAWcCAQAwDjEMMAoGA1UEAxMDeHl6MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApcnvhdQkPvgLYc/WMEjnWmS9ulEiW8ol6jhEU1LojTd+vyD8D3LwDZCBfXaTkvjQW9y4+WKBhgsPD6dzb4Ux/6QJOEYo0YvGgHIO17fC3rfSRLGsEOUxRr9XkuypCXZbphmAvGteIgNa7+zJIcNVOAH4T6Sf1A2klprFy4wv7FQkddE9hgDGuI1CiajJxz81bbmPm2gSsXdFGpP5DZdAd7U5QZX/+TyX746+IitwKT3CQWGSnoAs9NPBs7WJILEu8QB7gnAU9UZBzcNUsIF9byCRkH90SEwrhvQOg/6GOozY3Epp7NZDJAS3D+lY6kzkMDIbLxoLSTB7DW5NCR81bQIDAQABoCwwKgYJKoZIhvcNAQkOMR0wGzAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAPXHYD4T4KE8UkwkP5HwgCRwwJ4WF8yKC8OnEDwPyykOB3Ms5lbMrP/jpuSTOq2q8mb4vRWNzH/xDq43FfI7vmnrpY2ulgrdKsuZOgW1mZU1LUaZ5q8oBCBL+2ZCzPz22Gc+M0ietda23NRuobE5cmuLScDrpJUL7sKRjeHc1xZc7ifGfn2zvu9XvGKNxlv/T2bE+HvmZrYnbY0ZAMicZo2eoPDpAasaiVRiO+cbS+6c3gv8M0lJ2wVGXrPRCHlLTE0FR0KujWu4GzsSj0lL7YS833Lu888FaGZsESVZN9xi0Xv4FI20YChB6839nAFpiG+FCUagS0UAnBw09OhxpGA==\",\"cancellation_requested\":false,\"status\":\"inProgress\",\"status_details\":\"Pending certificate created. Certificate request is in progress. This may take some time based on the issuer provider. Please check again later.\",\"request_id\":\"f268325b6f394e6a9ec36ffa1f374e0c\"}", + "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending\",\"issuer\":{\"name\":\"Self\"},\"csr\":\"MIICfzCCAWcCAQAwDjEMMAoGA1UEAxMDeHl6MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmdFrCtEikRMjll4Hbz1xP47Za1xDbd8FOsqoO+QIsSDBlYdKurMyPno3S2CVBGnni0lbC1d8bkvWNz8f8GywFnVa41hglskH1rLd80eBDVUN91oqnkyA8KzDokfYoBaFKQGOgNqAqC2FZMHUeFkjLNPcpDIy9r9cJ48cEY5vXsyY/fYalSZS1hnNHD9bowH9244Vcqh3FxYL60fpIPjMhRiJrvfDhTRkcVIQtsCG3iJ9Q3EGy5lrtJ8+IX/+n8wyzL9LT7Hc1liKTJPzBFPd0+n6vwU7ccZmh9vg80bhyA1JsVBOrcXQdreUlQju/xdjHSM082HZqnAmY8FsrXCCOQIDAQABoCwwKgYJKoZIhvcNAQkOMR0wGzAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAg8c/M+umH17alC1JTR78YPLwODzT6waO3H/nt+AX/GEP/yglQw/oTx8//K9r/Lg79KAoIqbPDnlXgxg5HBH8sk86Yk+DD+cISUUF2wk7RHFCpsUUKbWtydbrjZ/rZeOpz/DB4q30Wg/hI5krAmdMTvB7CUB157kF703gtW0J1VViScAPWEpQYDnaf/88DI0oozg6hirMnMZzYcnfdLb1fPCzf3b7P3tPq45FmgCw1rLIq1zkfOiGw+gjBhTR15L5WdQN9oNr2S92n0Bvklna4oHfRiJGh/NYdkWGVwDgvJQKrYazs1hbXw6TkuHtMfulSOK0HMbYM+OD00VaBfyS9A==\",\"cancellation_requested\":false,\"status\":\"inProgress\",\"status_details\":\"Pending certificate created. Certificate request is in progress. This may take some time based on the issuer provider. Please check again later.\",\"request_id\":\"1aceb91e04f9419c9957938fae4ae2f5\"}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "1255", + "content-length": "1252", "content-type": "application/json; charset=utf-8", - "date": "Thu, 04 Nov 2021 20:47:30 GMT", + "date": "Tue, 20 Sep 2022 17:56:11 GMT", "expires": "-1", "pragma": "no-cache", "retry-after": "10", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "0c7736a8-f5b7-4044-51bc-0de3f33df0ef", + "x-ms-client-request-id": "debe9c9f-f79d-406e-76a7-2562c723513d", "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "westus2", - "x-ms-keyvault-service-version": "1.9.150.1", - "x-ms-request-id": "da161c1a-da59-4baf-ad9a-926ab1853062", - "x-powered-by": "ASP.NET" + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "d0d216dd-8b43-4362-9920-3635bd3ff5f1" }, "Url": "https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-certificates/4.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", - "x-ms-client-request-id": "69866686-3b4c-4291-565a-596d6057b354" + "user-agent": "azsdk-cpp-keyvault-certificates/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "51e7cb2c-6116-4996-7163-b452071ccb54" }, "Method": "GET", "Response": { - "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending\",\"issuer\":{\"name\":\"Self\"},\"csr\":\"MIICfzCCAWcCAQAwDjEMMAoGA1UEAxMDeHl6MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApcnvhdQkPvgLYc/WMEjnWmS9ulEiW8ol6jhEU1LojTd+vyD8D3LwDZCBfXaTkvjQW9y4+WKBhgsPD6dzb4Ux/6QJOEYo0YvGgHIO17fC3rfSRLGsEOUxRr9XkuypCXZbphmAvGteIgNa7+zJIcNVOAH4T6Sf1A2klprFy4wv7FQkddE9hgDGuI1CiajJxz81bbmPm2gSsXdFGpP5DZdAd7U5QZX/+TyX746+IitwKT3CQWGSnoAs9NPBs7WJILEu8QB7gnAU9UZBzcNUsIF9byCRkH90SEwrhvQOg/6GOozY3Epp7NZDJAS3D+lY6kzkMDIbLxoLSTB7DW5NCR81bQIDAQABoCwwKgYJKoZIhvcNAQkOMR0wGzAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAPXHYD4T4KE8UkwkP5HwgCRwwJ4WF8yKC8OnEDwPyykOB3Ms5lbMrP/jpuSTOq2q8mb4vRWNzH/xDq43FfI7vmnrpY2ulgrdKsuZOgW1mZU1LUaZ5q8oBCBL+2ZCzPz22Gc+M0ietda23NRuobE5cmuLScDrpJUL7sKRjeHc1xZc7ifGfn2zvu9XvGKNxlv/T2bE+HvmZrYnbY0ZAMicZo2eoPDpAasaiVRiO+cbS+6c3gv8M0lJ2wVGXrPRCHlLTE0FR0KujWu4GzsSj0lL7YS833Lu888FaGZsESVZN9xi0Xv4FI20YChB6839nAFpiG+FCUagS0UAnBw09OhxpGA==\",\"cancellation_requested\":false,\"status\":\"inProgress\",\"status_details\":\"Pending certificate created. Certificate request is in progress. This may take some time based on the issuer provider. Please check again later.\",\"request_id\":\"f268325b6f394e6a9ec36ffa1f374e0c\"}", + "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending\",\"issuer\":{\"name\":\"Self\"},\"csr\":\"MIICfzCCAWcCAQAwDjEMMAoGA1UEAxMDeHl6MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmdFrCtEikRMjll4Hbz1xP47Za1xDbd8FOsqoO+QIsSDBlYdKurMyPno3S2CVBGnni0lbC1d8bkvWNz8f8GywFnVa41hglskH1rLd80eBDVUN91oqnkyA8KzDokfYoBaFKQGOgNqAqC2FZMHUeFkjLNPcpDIy9r9cJ48cEY5vXsyY/fYalSZS1hnNHD9bowH9244Vcqh3FxYL60fpIPjMhRiJrvfDhTRkcVIQtsCG3iJ9Q3EGy5lrtJ8+IX/+n8wyzL9LT7Hc1liKTJPzBFPd0+n6vwU7ccZmh9vg80bhyA1JsVBOrcXQdreUlQju/xdjHSM082HZqnAmY8FsrXCCOQIDAQABoCwwKgYJKoZIhvcNAQkOMR0wGzAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAg8c/M+umH17alC1JTR78YPLwODzT6waO3H/nt+AX/GEP/yglQw/oTx8//K9r/Lg79KAoIqbPDnlXgxg5HBH8sk86Yk+DD+cISUUF2wk7RHFCpsUUKbWtydbrjZ/rZeOpz/DB4q30Wg/hI5krAmdMTvB7CUB157kF703gtW0J1VViScAPWEpQYDnaf/88DI0oozg6hirMnMZzYcnfdLb1fPCzf3b7P3tPq45FmgCw1rLIq1zkfOiGw+gjBhTR15L5WdQN9oNr2S92n0Bvklna4oHfRiJGh/NYdkWGVwDgvJQKrYazs1hbXw6TkuHtMfulSOK0HMbYM+OD00VaBfyS9A==\",\"cancellation_requested\":false,\"status\":\"inProgress\",\"status_details\":\"Pending certificate created. Certificate request is in progress. This may take some time based on the issuer provider. Please check again later.\",\"request_id\":\"1aceb91e04f9419c9957938fae4ae2f5\"}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "1255", + "content-length": "1252", "content-type": "application/json; charset=utf-8", - "date": "Thu, 04 Nov 2021 20:47:30 GMT", + "date": "Tue, 20 Sep 2022 17:56:11 GMT", "expires": "-1", "pragma": "no-cache", "retry-after": "10", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "69866686-3b4c-4291-565a-596d6057b354", + "x-ms-client-request-id": "51e7cb2c-6116-4996-7163-b452071ccb54", "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "westus2", - "x-ms-keyvault-service-version": "1.9.150.1", - "x-ms-request-id": "b5b73d6f-eb47-4696-9761-0ef8f0dc6540", - "x-powered-by": "ASP.NET" + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "3067d12f-bcde-4e0d-ae93-2cde2656ea0d" }, "Url": "https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-certificates/4.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", - "x-ms-client-request-id": "bac481c6-0f9c-474f-419a-9b359b7d69c9" + "user-agent": "azsdk-cpp-keyvault-certificates/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "95267c84-0b6d-49ba-7183-a99326932d8e" }, "Method": "GET", "Response": { - "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending\",\"issuer\":{\"name\":\"Self\"},\"csr\":\"MIICfzCCAWcCAQAwDjEMMAoGA1UEAxMDeHl6MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApcnvhdQkPvgLYc/WMEjnWmS9ulEiW8ol6jhEU1LojTd+vyD8D3LwDZCBfXaTkvjQW9y4+WKBhgsPD6dzb4Ux/6QJOEYo0YvGgHIO17fC3rfSRLGsEOUxRr9XkuypCXZbphmAvGteIgNa7+zJIcNVOAH4T6Sf1A2klprFy4wv7FQkddE9hgDGuI1CiajJxz81bbmPm2gSsXdFGpP5DZdAd7U5QZX/+TyX746+IitwKT3CQWGSnoAs9NPBs7WJILEu8QB7gnAU9UZBzcNUsIF9byCRkH90SEwrhvQOg/6GOozY3Epp7NZDJAS3D+lY6kzkMDIbLxoLSTB7DW5NCR81bQIDAQABoCwwKgYJKoZIhvcNAQkOMR0wGzAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAPXHYD4T4KE8UkwkP5HwgCRwwJ4WF8yKC8OnEDwPyykOB3Ms5lbMrP/jpuSTOq2q8mb4vRWNzH/xDq43FfI7vmnrpY2ulgrdKsuZOgW1mZU1LUaZ5q8oBCBL+2ZCzPz22Gc+M0ietda23NRuobE5cmuLScDrpJUL7sKRjeHc1xZc7ifGfn2zvu9XvGKNxlv/T2bE+HvmZrYnbY0ZAMicZo2eoPDpAasaiVRiO+cbS+6c3gv8M0lJ2wVGXrPRCHlLTE0FR0KujWu4GzsSj0lL7YS833Lu888FaGZsESVZN9xi0Xv4FI20YChB6839nAFpiG+FCUagS0UAnBw09OhxpGA==\",\"cancellation_requested\":false,\"status\":\"completed\",\"target\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken\",\"request_id\":\"f268325b6f394e6a9ec36ffa1f374e0c\"}", + "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending\",\"issuer\":{\"name\":\"Self\"},\"csr\":\"MIICfzCCAWcCAQAwDjEMMAoGA1UEAxMDeHl6MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmdFrCtEikRMjll4Hbz1xP47Za1xDbd8FOsqoO+QIsSDBlYdKurMyPno3S2CVBGnni0lbC1d8bkvWNz8f8GywFnVa41hglskH1rLd80eBDVUN91oqnkyA8KzDokfYoBaFKQGOgNqAqC2FZMHUeFkjLNPcpDIy9r9cJ48cEY5vXsyY/fYalSZS1hnNHD9bowH9244Vcqh3FxYL60fpIPjMhRiJrvfDhTRkcVIQtsCG3iJ9Q3EGy5lrtJ8+IX/+n8wyzL9LT7Hc1liKTJPzBFPd0+n6vwU7ccZmh9vg80bhyA1JsVBOrcXQdreUlQju/xdjHSM082HZqnAmY8FsrXCCOQIDAQABoCwwKgYJKoZIhvcNAQkOMR0wGzAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAg8c/M+umH17alC1JTR78YPLwODzT6waO3H/nt+AX/GEP/yglQw/oTx8//K9r/Lg79KAoIqbPDnlXgxg5HBH8sk86Yk+DD+cISUUF2wk7RHFCpsUUKbWtydbrjZ/rZeOpz/DB4q30Wg/hI5krAmdMTvB7CUB157kF703gtW0J1VViScAPWEpQYDnaf/88DI0oozg6hirMnMZzYcnfdLb1fPCzf3b7P3tPq45FmgCw1rLIq1zkfOiGw+gjBhTR15L5WdQN9oNr2S92n0Bvklna4oHfRiJGh/NYdkWGVwDgvJQKrYazs1hbXw6TkuHtMfulSOK0HMbYM+OD00VaBfyS9A==\",\"cancellation_requested\":false,\"status\":\"completed\",\"target\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken\",\"request_id\":\"1aceb91e04f9419c9957938fae4ae2f5\"}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "1181", + "content-length": "1175", "content-type": "application/json; charset=utf-8", - "date": "Thu, 04 Nov 2021 20:47:50 GMT", + "date": "Tue, 20 Sep 2022 17:56:30 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "bac481c6-0f9c-474f-419a-9b359b7d69c9", + "x-ms-client-request-id": "95267c84-0b6d-49ba-7183-a99326932d8e", "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "westus2", - "x-ms-keyvault-service-version": "1.9.150.1", - "x-ms-request-id": "43e5c2bd-68e1-4f21-85e0-0c1efb02a501", - "x-powered-by": "ASP.NET" + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "b05f350a-cd57-4a56-9abf-95f92384aade" }, "Url": "https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-certificates/4.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", - "x-ms-client-request-id": "f490c7c3-a8f6-4a6b-511b-e6e38eb1fb24" + "user-agent": "azsdk-cpp-keyvault-certificates/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "6c531179-0364-4687-47d7-75d00c4b98c5" }, "Method": "GET", "Response": { - "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/4596c5ee66ab49e096a41f526376eaec\",\"kid\":\"https://REDACTED.vault.azure.net/keys/CreateCertificateResumeToken/4596c5ee66ab49e096a41f526376eaec\",\"sid\":\"https://REDACTED.vault.azure.net/secrets/CreateCertificateResumeToken/4596c5ee66ab49e096a41f526376eaec\",\"x5t\":\"KFnMBpRVJt5GdOXRWmbkrlA-nFQ\",\"cer\":\"MIIDAzCCAeugAwIBAgIQFtS9aioiSRClPTXAubEOMzANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDEwN4eXowHhcNMjExMTA0MjAzNzQzWhcNMjIxMTA0MjA0NzQzWjAOMQwwCgYDVQQDEwN4eXowggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQClye+F1CQ++Athz9YwSOdaZL26USJbyiXqOERTUuiNN36/IPwPcvANkIF9dpOS+NBb3Lj5YoGGCw8Pp3NvhTH/pAk4RijRi8aAcg7Xt8Let9JEsawQ5TFGv1eS7KkJdlumGYC8a14iA1rv7Mkhw1U4AfhPpJ/UDaSWmsXLjC/sVCR10T2GAMa4jUKJqMnHPzVtuY+baBKxd0Uak/kNl0B3tTlBlf/5PJfvjr4iK3ApPcJBYZKegCz008GztYkgsS7xAHuCcBT1RkHNw1SwgX1vIJGQf3RITCuG9A6D/oY6jNjcSmns1kMkBLcP6VjqTOQwMhsvGgtJMHsNbk0JHzVtAgMBAAGjXTBbMA4GA1UdDwEB/wQEAwIFoDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFGAAZBLdsFyoTmrXwiBx3kAcjCpvMB0GA1UdDgQWBBRgAGQS3bBcqE5q18Igcd5AHIwqbzANBgkqhkiG9w0BAQsFAAOCAQEAEVe1LRtiZIKR0ivdmHBwLuJg5/SxPEB8ffGgSspEWPBta0BPE5s5+hhLROfx6C4FTY3zmfjxxJK2bfqcQJe2x+NauLXIrUxgP/5Le6UhDbQgFys9zktEAfEkJ+eNk96VgTKsanClniE62UqXcEqWVxogQkpPWYJ2VWc2MRgVwwGwIweP/Ve6uR1sdw5FmSGYikc7lNmx/MXZW0mgzDUo4n7tB/d1EiIqguQzIC7aXoGqmZ49b5FVn1ZkjloJVH9/S0rh6Gu+iuZ+U8bFrXD7q8EWN01Bvj7le273enKDO3B7znZLInoinQZ5U48svlGKKwtxQIcfZI1Bz9XlrYXJMQ==\",\"attributes\":{\"enabled\":true,\"nbf\":1636058263,\"exp\":1667594863,\"created\":1636058863,\"updated\":1636058863,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90},\"tags\":{},\"policy\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/policy\",\"key_props\":{\"exportable\":true,\"kty\":\"RSA\",\"key_size\":2048,\"reuse_key\":false},\"secret_props\":{\"contentType\":\"application/x-pkcs12\"},\"x509_props\":{\"subject\":\"CN=xyz\",\"ekus\":[],\"key_usage\":[\"digitalSignature\",\"keyEncipherment\"],\"validity_months\":12,\"basic_constraints\":{\"ca\":false}},\"lifetime_actions\":[{\"trigger\":{\"lifetime_percentage\":80},\"action\":{\"action_type\":\"AutoRenew\"}}],\"issuer\":{\"name\":\"Self\"},\"attributes\":{\"enabled\":true,\"created\":1636058849,\"updated\":1636058849}},\"pending\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending\"}}", + "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending\",\"issuer\":{\"name\":\"Self\"},\"csr\":\"MIICfzCCAWcCAQAwDjEMMAoGA1UEAxMDeHl6MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmdFrCtEikRMjll4Hbz1xP47Za1xDbd8FOsqoO+QIsSDBlYdKurMyPno3S2CVBGnni0lbC1d8bkvWNz8f8GywFnVa41hglskH1rLd80eBDVUN91oqnkyA8KzDokfYoBaFKQGOgNqAqC2FZMHUeFkjLNPcpDIy9r9cJ48cEY5vXsyY/fYalSZS1hnNHD9bowH9244Vcqh3FxYL60fpIPjMhRiJrvfDhTRkcVIQtsCG3iJ9Q3EGy5lrtJ8+IX/+n8wyzL9LT7Hc1liKTJPzBFPd0+n6vwU7ccZmh9vg80bhyA1JsVBOrcXQdreUlQju/xdjHSM082HZqnAmY8FsrXCCOQIDAQABoCwwKgYJKoZIhvcNAQkOMR0wGzAOBgNVHQ8BAf8EBAMCBaAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAg8c/M+umH17alC1JTR78YPLwODzT6waO3H/nt+AX/GEP/yglQw/oTx8//K9r/Lg79KAoIqbPDnlXgxg5HBH8sk86Yk+DD+cISUUF2wk7RHFCpsUUKbWtydbrjZ/rZeOpz/DB4q30Wg/hI5krAmdMTvB7CUB157kF703gtW0J1VViScAPWEpQYDnaf/88DI0oozg6hirMnMZzYcnfdLb1fPCzf3b7P3tPq45FmgCw1rLIq1zkfOiGw+gjBhTR15L5WdQN9oNr2S92n0Bvklna4oHfRiJGh/NYdkWGVwDgvJQKrYazs1hbXw6TkuHtMfulSOK0HMbYM+OD00VaBfyS9A==\",\"cancellation_requested\":false,\"status\":\"completed\",\"target\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken\",\"request_id\":\"1aceb91e04f9419c9957938fae4ae2f5\"}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "2295", + "content-length": "1175", "content-type": "application/json; charset=utf-8", - "date": "Thu, 04 Nov 2021 20:47:50 GMT", + "date": "Tue, 20 Sep 2022 17:56:30 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "f490c7c3-a8f6-4a6b-511b-e6e38eb1fb24", + "x-ms-client-request-id": "6c531179-0364-4687-47d7-75d00c4b98c5", "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "westus2", - "x-ms-keyvault-service-version": "1.9.150.1", - "x-ms-request-id": "d5b862b0-6985-4294-8e2d-903e41206204", - "x-powered-by": "ASP.NET" + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "541ad662-004a-4b39-ae3e-07c329e65530" }, - "Url": "https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken?api-version=7.3" + "Url": "https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-certificates/4.0.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", - "x-ms-client-request-id": "9853e696-93ee-4d64-76bd-0b77b2ba1c15" + "user-agent": "azsdk-cpp-keyvault-certificates/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "6412760a-b600-4c0d-5bbb-34d903b8d525" }, "Method": "GET", "Response": { - "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/4596c5ee66ab49e096a41f526376eaec\",\"kid\":\"https://REDACTED.vault.azure.net/keys/CreateCertificateResumeToken/4596c5ee66ab49e096a41f526376eaec\",\"sid\":\"https://REDACTED.vault.azure.net/secrets/CreateCertificateResumeToken/4596c5ee66ab49e096a41f526376eaec\",\"x5t\":\"KFnMBpRVJt5GdOXRWmbkrlA-nFQ\",\"cer\":\"MIIDAzCCAeugAwIBAgIQFtS9aioiSRClPTXAubEOMzANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDEwN4eXowHhcNMjExMTA0MjAzNzQzWhcNMjIxMTA0MjA0NzQzWjAOMQwwCgYDVQQDEwN4eXowggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQClye+F1CQ++Athz9YwSOdaZL26USJbyiXqOERTUuiNN36/IPwPcvANkIF9dpOS+NBb3Lj5YoGGCw8Pp3NvhTH/pAk4RijRi8aAcg7Xt8Let9JEsawQ5TFGv1eS7KkJdlumGYC8a14iA1rv7Mkhw1U4AfhPpJ/UDaSWmsXLjC/sVCR10T2GAMa4jUKJqMnHPzVtuY+baBKxd0Uak/kNl0B3tTlBlf/5PJfvjr4iK3ApPcJBYZKegCz008GztYkgsS7xAHuCcBT1RkHNw1SwgX1vIJGQf3RITCuG9A6D/oY6jNjcSmns1kMkBLcP6VjqTOQwMhsvGgtJMHsNbk0JHzVtAgMBAAGjXTBbMA4GA1UdDwEB/wQEAwIFoDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFGAAZBLdsFyoTmrXwiBx3kAcjCpvMB0GA1UdDgQWBBRgAGQS3bBcqE5q18Igcd5AHIwqbzANBgkqhkiG9w0BAQsFAAOCAQEAEVe1LRtiZIKR0ivdmHBwLuJg5/SxPEB8ffGgSspEWPBta0BPE5s5+hhLROfx6C4FTY3zmfjxxJK2bfqcQJe2x+NauLXIrUxgP/5Le6UhDbQgFys9zktEAfEkJ+eNk96VgTKsanClniE62UqXcEqWVxogQkpPWYJ2VWc2MRgVwwGwIweP/Ve6uR1sdw5FmSGYikc7lNmx/MXZW0mgzDUo4n7tB/d1EiIqguQzIC7aXoGqmZ49b5FVn1ZkjloJVH9/S0rh6Gu+iuZ+U8bFrXD7q8EWN01Bvj7le273enKDO3B7znZLInoinQZ5U48svlGKKwtxQIcfZI1Bz9XlrYXJMQ==\",\"attributes\":{\"enabled\":true,\"nbf\":1636058263,\"exp\":1667594863,\"created\":1636058863,\"updated\":1636058863,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90},\"tags\":{},\"policy\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/policy\",\"key_props\":{\"exportable\":true,\"kty\":\"RSA\",\"key_size\":2048,\"reuse_key\":false},\"secret_props\":{\"contentType\":\"application/x-pkcs12\"},\"x509_props\":{\"subject\":\"CN=xyz\",\"ekus\":[],\"key_usage\":[\"digitalSignature\",\"keyEncipherment\"],\"validity_months\":12,\"basic_constraints\":{\"ca\":false}},\"lifetime_actions\":[{\"trigger\":{\"lifetime_percentage\":80},\"action\":{\"action_type\":\"AutoRenew\"}}],\"issuer\":{\"name\":\"Self\"},\"attributes\":{\"enabled\":true,\"created\":1636058849,\"updated\":1636058849}},\"pending\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending\"}}", + "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/ca87ef1679d34732ac4c8e6c59c5d8f0\",\"kid\":\"https://REDACTED.vault.azure.net/keys/CreateCertificateResumeToken/ca87ef1679d34732ac4c8e6c59c5d8f0\",\"sid\":\"https://REDACTED.vault.azure.net/secrets/CreateCertificateResumeToken/ca87ef1679d34732ac4c8e6c59c5d8f0\",\"x5t\":\"U2KaSnWYWgsoAw5CcY-lb6bJpGw\",\"cer\":\"MIIDAzCCAeugAwIBAgIQPh59ZGswQ7KrJjTMSfRLtzANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDEwN4eXowHhcNMjIwOTIwMTc0NjExWhcNMjMwOTIwMTc1NjExWjAOMQwwCgYDVQQDEwN4eXowggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCZ0WsK0SKREyOWXgdvPXE/jtlrXENt3wU6yqg75AixIMGVh0q6szI+ejdLYJUEaeeLSVsLV3xuS9Y3Px/wbLAWdVrjWGCWyQfWst3zR4ENVQ33WiqeTIDwrMOiR9igFoUpAY6A2oCoLYVkwdR4WSMs09ykMjL2v1wnjxwRjm9ezJj99hqVJlLWGc0cP1ujAf3bjhVyqHcXFgvrR+kg+MyFGImu98OFNGRxUhC2wIbeIn1DcQbLmWu0nz4hf/6fzDLMv0tPsdzWWIpMk/MEU93T6fq/BTtxxmaH2+DzRuHIDUmxUE6txdB2t5SVCO7/F2MdIzTzYdmqcCZjwWytcII5AgMBAAGjXTBbMA4GA1UdDwEB/wQEAwIFoDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFKzNPtqJqAqiKutcdv9Y/yqwfUfTMB0GA1UdDgQWBBSszT7aiagKoirrXHb/WP8qsH1H0zANBgkqhkiG9w0BAQsFAAOCAQEAiP4IBnovihjyUQXNJnVneOjAdX3TR32GxNddEy37ZtdGogN+cmSeXgb0IKEAZXUgSWs4GkahS9tZnrvS743EA8uIlmAvy7/95pNfEgpzgpVuER5AhQ0R2SyM4nSRKxzMfG1J5Qk2jfSRSEK5FPHNoav1qfHml9+aYpWXcq9Pk7Pbfd7C61SyZI3RjuQrsiRXv4GwUjjwdyI0R4EOLgFAg0twBBgqqY0NOkfuLGjs9Bbf27207D+cumRvrodVrn4MnStSLauuOtg8Y9yLjnj0uQ/uTRulaLfAxVH90Mi40vbDcej+FvDyuiNXI2xQKIIe9s5E9zXgIznjQoIhQ2QtKQ==\",\"attributes\":{\"enabled\":true,\"nbf\":1663695971,\"exp\":1695232571,\"created\":1663696572,\"updated\":1663696572,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90},\"tags\":{},\"policy\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/policy\",\"key_props\":{\"exportable\":true,\"kty\":\"RSA\",\"key_size\":2048,\"reuse_key\":false},\"secret_props\":{\"contentType\":\"application/x-pkcs12\"},\"x509_props\":{\"subject\":\"CN=xyz\",\"ekus\":[],\"key_usage\":[\"digitalSignature\",\"keyEncipherment\"],\"validity_months\":12,\"basic_constraints\":{\"ca\":false}},\"lifetime_actions\":[{\"trigger\":{\"lifetime_percentage\":80},\"action\":{\"action_type\":\"AutoRenew\"}}],\"issuer\":{\"name\":\"Self\"},\"attributes\":{\"enabled\":true,\"created\":1663696431,\"updated\":1663696571}},\"pending\":{\"id\":\"https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken/pending\"}}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "2295", + "content-length": "2280", "content-type": "application/json; charset=utf-8", - "date": "Thu, 04 Nov 2021 20:47:50 GMT", + "date": "Tue, 20 Sep 2022 17:56:30 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "9853e696-93ee-4d64-76bd-0b77b2ba1c15", + "x-ms-client-request-id": "6412760a-b600-4c0d-5bbb-34d903b8d525", "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "westus2", - "x-ms-keyvault-service-version": "1.9.150.1", - "x-ms-request-id": "634ff698-b579-4835-8fad-77f8a076b502", - "x-powered-by": "ASP.NET" + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "7ea02920-4b5d-44dd-be90-dca8e335c874" }, "Url": "https://REDACTED.vault.azure.net/certificates/CreateCertificateResumeToken?api-version=7.3" } diff --git a/sdk/keyvault/azure-security-keyvault-keys/src/delete_key_operation.cpp b/sdk/keyvault/azure-security-keyvault-keys/src/delete_key_operation.cpp index e5f51b64c5..eebce6b742 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/src/delete_key_operation.cpp +++ b/sdk/keyvault/azure-security-keyvault-keys/src/delete_key_operation.cpp @@ -18,38 +18,36 @@ Azure::Security::KeyVault::Keys::DeleteKeyOperation::PollInternal( Azure::Core::Context const& context) { std::unique_ptr rawResponse; - if (!IsDone()) + + try { - try - { - rawResponse = m_keyClient->GetDeletedKey(m_value.Name(), context).RawResponse; - } - catch (Azure::Core::RequestFailedException& error) - { - rawResponse = std::move(error.RawResponse); - } + rawResponse = m_keyClient->GetDeletedKey(m_value.Name(), context).RawResponse; + } + catch (Azure::Core::RequestFailedException& error) + { + rawResponse = std::move(error.RawResponse); + } - switch (rawResponse->GetStatusCode()) + switch (rawResponse->GetStatusCode()) + { + case Azure::Core::Http::HttpStatusCode::Ok: + case Azure::Core::Http::HttpStatusCode::Forbidden: // Access denied but proof the key was + // deleted. { - case Azure::Core::Http::HttpStatusCode::Ok: - case Azure::Core::Http::HttpStatusCode::Forbidden: // Access denied but proof the key was - // deleted. - { - m_status = Azure::Core::OperationStatus::Succeeded; - break; - } - case Azure::Core::Http::HttpStatusCode::NotFound: { - m_status = Azure::Core::OperationStatus::Running; - break; - } - default: - throw Azure::Core::RequestFailedException(rawResponse); + m_status = Azure::Core::OperationStatus::Succeeded; + break; } - - if (m_status == Azure::Core::OperationStatus::Succeeded) - { - m_value = _detail::DeletedKeySerializer::DeletedKeyDeserialize(m_value.Name(), *rawResponse); + case Azure::Core::Http::HttpStatusCode::NotFound: { + m_status = Azure::Core::OperationStatus::Running; + break; } + default: + throw Azure::Core::RequestFailedException(rawResponse); + } + + if (m_status == Azure::Core::OperationStatus::Succeeded) + { + m_value = _detail::DeletedKeySerializer::DeletedKeyDeserialize(m_value.Name(), *rawResponse); } // To ensure the success of calling Poll multiple times, even after operation is completed, a diff --git a/sdk/keyvault/azure-security-keyvault-keys/src/recover_deleted_key_operation.cpp b/sdk/keyvault/azure-security-keyvault-keys/src/recover_deleted_key_operation.cpp index 29c26044cf..f16d0ee959 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/src/recover_deleted_key_operation.cpp +++ b/sdk/keyvault/azure-security-keyvault-keys/src/recover_deleted_key_operation.cpp @@ -16,37 +16,34 @@ Azure::Security::KeyVault::Keys::RecoverDeletedKeyOperation::PollInternal( Azure::Core::Context const& context) { std::unique_ptr rawResponse; - if (!IsDone()) + + try { - try - { - rawResponse = m_keyClient->GetKey(m_value.Name(), {}, context).RawResponse; - } - catch (Azure::Core::RequestFailedException& error) - { - rawResponse = std::move(error.RawResponse); - } + rawResponse = m_keyClient->GetKey(m_value.Name(), {}, context).RawResponse; + } + catch (Azure::Core::RequestFailedException& error) + { + rawResponse = std::move(error.RawResponse); + } - switch (rawResponse->GetStatusCode()) - { - case Azure::Core::Http::HttpStatusCode::Ok: - // Access denied but proof the key was deleted. - case Azure::Core::Http::HttpStatusCode::Forbidden: { - m_status = Azure::Core::OperationStatus::Succeeded; - break; - } - case Azure::Core::Http::HttpStatusCode::NotFound: { - m_status = Azure::Core::OperationStatus::Running; - break; - } - default: - throw Azure::Core::RequestFailedException(rawResponse); + switch (rawResponse->GetStatusCode()) + { + case Azure::Core::Http::HttpStatusCode::Ok: + // Access denied but proof the key was deleted. + case Azure::Core::Http::HttpStatusCode::Forbidden: { + m_status = Azure::Core::OperationStatus::Succeeded; + break; } - if (m_status == Azure::Core::OperationStatus::Succeeded) - { - m_value - = _detail::KeyVaultKeySerializer::KeyVaultKeyDeserialize(m_value.Name(), *rawResponse); + case Azure::Core::Http::HttpStatusCode::NotFound: { + m_status = Azure::Core::OperationStatus::Running; + break; } + default: + throw Azure::Core::RequestFailedException(rawResponse); + } + if (m_status == Azure::Core::OperationStatus::Succeeded) + { + m_value = _detail::KeyVaultKeySerializer::KeyVaultKeyDeserialize(m_value.Name(), *rawResponse); } // To ensure the success of calling Poll multiple times, even after operation is completed, a diff --git a/sdk/keyvault/azure-security-keyvault-keys/test/ut/key_client_delete_test_live.cpp b/sdk/keyvault/azure-security-keyvault-keys/test/ut/key_client_delete_test_live.cpp index bf13777b2f..6ba642333b 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/test/ut/key_client_delete_test_live.cpp +++ b/sdk/keyvault/azure-security-keyvault-keys/test/ut/key_client_delete_test_live.cpp @@ -64,7 +64,9 @@ TEST_F(KeyVaultKeyClient, DeleteKey) EXPECT_EQ(keyResponseLRO.GetResumeToken(), expectedStatusToken); // poll each second until key is soft-deleted // Will throw and fail test if test takes more than 3 minutes (token cancelled) + // double polling should not interfere with the outcome auto keyResponse = keyResponseLRO.PollUntilDone(m_testPollingIntervalMs, cancelToken); + keyResponse = keyResponseLRO.PollUntilDone(m_testPollingIntervalMs, cancelToken); } } @@ -353,6 +355,8 @@ TEST_F(KeyVaultKeyClient, RecoverOperationResumeToken) auto resumeOperation = Azure::Security::KeyVault::Keys::DeleteKeyOperation::CreateFromResumeToken( resumeToken, client); + // double polling should have no impact on the result + resumeOperation.PollUntilDone(m_testPollingIntervalMs); resumeOperation.PollUntilDone(m_testPollingIntervalMs); } { @@ -365,7 +369,9 @@ TEST_F(KeyVaultKeyClient, RecoverOperationResumeToken) auto resumeRecoveryOp = Azure::Security::KeyVault::Keys::RecoverDeletedKeyOperation::CreateFromResumeToken( resumeToken, client); + // double polling should have no impact on the result auto keyResponse = resumeRecoveryOp.PollUntilDone(m_testPollingIntervalMs); + keyResponse = resumeRecoveryOp.PollUntilDone(m_testPollingIntervalMs); auto key = keyResponse.Value; } } diff --git a/sdk/keyvault/azure-security-keyvault-keys/test/ut/recordings/KeyVaultKeyClient.RecoverOperationResumeToken.json b/sdk/keyvault/azure-security-keyvault-keys/test/ut/recordings/KeyVaultKeyClient.RecoverOperationResumeToken.json index f517578ff0..7897935e74 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/test/ut/recordings/KeyVaultKeyClient.RecoverOperationResumeToken.json +++ b/sdk/keyvault/azure-security-keyvault-keys/test/ut/recordings/KeyVaultKeyClient.RecoverOperationResumeToken.json @@ -3,235 +3,235 @@ { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "1aad802a-4697-4046-4a49-1737149e31a8" + "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "7008943c-7818-4231-5daa-00cd5a705c08" }, "Method": "POST", "Response": { - "BODY": "{\"key\":{\"kid\":\"https://cpp-recordings.vault.azure.net/keys/RecoverOperationResumeToken/3221e32d5c7849d3bcf6f9ec3eefee72\",\"kty\":\"EC\",\"key_ops\":[\"sign\",\"verify\"],\"crv\":\"P-256\",\"x\":\"zcSKSmCxVecNVriYLG3DA3rv2T38PuPhBI2DwE9dk1E\",\"y\":\"cRyswPDlIXKNcw9xKv87jeYQ-ln2QP7VbYOxIKtETM0\"},\"attributes\":{\"enabled\":true,\"created\":1638401719,\"updated\":1638401719,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "BODY": "{\"key\":{\"kid\":\"https://gearamakv1.vault.azure.net/keys/RecoverOperationResumeToken/c84e0042769b4ff19e8135236bc79cf7\",\"kty\":\"EC\",\"key_ops\":[\"sign\",\"verify\"],\"crv\":\"P-256\",\"x\":\"6MQqHLBRpkDRcPwmimj--MXu0ZM76EaGU3_fys-FOik\",\"y\":\"rn6SBgwrHvW7wohlg2t59kyA_g_lWmUmblJo7l7hgU8\"},\"attributes\":{\"enabled\":true,\"created\":1664233384,\"updated\":1664233384,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90,\"exportable\":false}}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "408", + "content-length": "423", "content-type": "application/json; charset=utf-8", - "date": "Wed, 01 Dec 2021 23:35:18 GMT", + "date": "Mon, 26 Sep 2022 23:03:03 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "1aad802a-4697-4046-4a49-1737149e31a8", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "bc39e5e8-3f85-46fa-94b9-2e971190c2c2", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "7008943c-7818-4231-5daa-00cd5a705c08", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "f2fb939c-c076-4666-88cb-e3fc312c242f" }, "Url": "https://REDACTED.vault.azure.net/keys/RecoverOperationResumeToken/create?api-version=7.3" }, { "Headers": { - "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "61004528-6371-433d-5092-99d6c186f08a" + "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "3eec62e3-2828-4c76-783e-ef2aa12bb58e" }, "Method": "DELETE", "Response": { - "BODY": "{\"recoveryId\":\"https://cpp-recordings.vault.azure.net/deletedkeys/RecoverOperationResumeToken\",\"deletedDate\":1638401719,\"scheduledPurgeDate\":1646177719,\"key\":{\"kid\":\"https://cpp-recordings.vault.azure.net/keys/RecoverOperationResumeToken/3221e32d5c7849d3bcf6f9ec3eefee72\",\"kty\":\"EC\",\"key_ops\":[\"sign\",\"verify\"],\"crv\":\"P-256\",\"x\":\"zcSKSmCxVecNVriYLG3DA3rv2T38PuPhBI2DwE9dk1E\",\"y\":\"cRyswPDlIXKNcw9xKv87jeYQ-ln2QP7VbYOxIKtETM0\"},\"attributes\":{\"enabled\":true,\"created\":1638401719,\"updated\":1638401719,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "BODY": "{\"recoveryId\":\"https://gearamakv1.vault.azure.net/deletedkeys/RecoverOperationResumeToken\",\"deletedDate\":1664233389,\"scheduledPurgeDate\":1672009389,\"key\":{\"kid\":\"https://gearamakv1.vault.azure.net/keys/RecoverOperationResumeToken/c84e0042769b4ff19e8135236bc79cf7\",\"kty\":\"EC\",\"key_ops\":[\"sign\",\"verify\"],\"crv\":\"P-256\",\"x\":\"6MQqHLBRpkDRcPwmimj--MXu0ZM76EaGU3_fys-FOik\",\"y\":\"rn6SBgwrHvW7wohlg2t59kyA_g_lWmUmblJo7l7hgU8\"},\"attributes\":{\"enabled\":true,\"created\":1664233384,\"updated\":1664233384,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90,\"exportable\":false}}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "559", + "content-length": "570", "content-type": "application/json; charset=utf-8", - "date": "Wed, 01 Dec 2021 23:35:18 GMT", + "date": "Mon, 26 Sep 2022 23:03:09 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "61004528-6371-433d-5092-99d6c186f08a", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "3d0391ba-ac85-4f29-88e9-bcd03c587d65", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "3eec62e3-2828-4c76-783e-ef2aa12bb58e", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "41e48a28-1528-4bb0-929a-2332111be272" }, "Url": "https://REDACTED.vault.azure.net/keys/RecoverOperationResumeToken?api-version=7.3" }, { "Headers": { - "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "e1cb097a-2efe-4067-4343-5e3aeafc7160" + "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "4b79e87a-264d-4f4f-4693-b4615b9fcc7a" }, "Method": "GET", "Response": { - "BODY": "{\"error\":{\"code\":\"KeyNotFound\",\"message\":\"Deleted Key not found: RecoverOperationResumeToken\"}}", - "STATUS_CODE": "404", + "BODY": "{\"recoveryId\":\"https://gearamakv1.vault.azure.net/deletedkeys/RecoverOperationResumeToken\",\"deletedDate\":1664233389,\"scheduledPurgeDate\":1672009389,\"key\":{\"kid\":\"https://gearamakv1.vault.azure.net/keys/RecoverOperationResumeToken/c84e0042769b4ff19e8135236bc79cf7\",\"kty\":\"EC\",\"key_ops\":[\"sign\",\"verify\"],\"crv\":\"P-256\",\"x\":\"6MQqHLBRpkDRcPwmimj--MXu0ZM76EaGU3_fys-FOik\",\"y\":\"rn6SBgwrHvW7wohlg2t59kyA_g_lWmUmblJo7l7hgU8\"},\"attributes\":{\"enabled\":true,\"created\":1664233384,\"updated\":1664233384,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90,\"exportable\":false}}", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "95", + "content-length": "570", "content-type": "application/json; charset=utf-8", - "date": "Wed, 01 Dec 2021 23:35:18 GMT", + "date": "Mon, 26 Sep 2022 23:03:12 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "e1cb097a-2efe-4067-4343-5e3aeafc7160", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "16bd72c8-aee1-4f5f-8895-0e7f66ce0213", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "4b79e87a-264d-4f4f-4693-b4615b9fcc7a", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "c70ed905-ec06-4025-817b-eb2f9f9f0abf" }, "Url": "https://REDACTED.vault.azure.net/deletedkeys/RecoverOperationResumeToken?api-version=7.3" }, { "Headers": { - "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "b25b01cb-bfae-4a75-43ef-9b083f2ffc20" + "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "1f63474e-9c81-4cdb-5c7c-c5a843996ae9" }, "Method": "GET", "Response": { - "BODY": "{\"error\":{\"code\":\"KeyNotFound\",\"message\":\"Deleted Key not found: RecoverOperationResumeToken\"}}", - "STATUS_CODE": "404", + "BODY": "{\"recoveryId\":\"https://gearamakv1.vault.azure.net/deletedkeys/RecoverOperationResumeToken\",\"deletedDate\":1664233389,\"scheduledPurgeDate\":1672009389,\"key\":{\"kid\":\"https://gearamakv1.vault.azure.net/keys/RecoverOperationResumeToken/c84e0042769b4ff19e8135236bc79cf7\",\"kty\":\"EC\",\"key_ops\":[\"sign\",\"verify\"],\"crv\":\"P-256\",\"x\":\"6MQqHLBRpkDRcPwmimj--MXu0ZM76EaGU3_fys-FOik\",\"y\":\"rn6SBgwrHvW7wohlg2t59kyA_g_lWmUmblJo7l7hgU8\"},\"attributes\":{\"enabled\":true,\"created\":1664233384,\"updated\":1664233384,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90,\"exportable\":false}}", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "95", + "content-length": "570", "content-type": "application/json; charset=utf-8", - "date": "Wed, 01 Dec 2021 23:35:19 GMT", + "date": "Mon, 26 Sep 2022 23:03:14 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "b25b01cb-bfae-4a75-43ef-9b083f2ffc20", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "ef06577b-42cb-431e-b2ed-6521e15cc2da", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "1f63474e-9c81-4cdb-5c7c-c5a843996ae9", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "22f5da56-e43a-469b-a4ba-19016b28886a" }, "Url": "https://REDACTED.vault.azure.net/deletedkeys/RecoverOperationResumeToken?api-version=7.3" }, { "Headers": { - "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "ca514e0a-4f95-44ce-4347-8c59fc7273fb" + "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "14b39ce9-f22c-4c3a-6cd8-07c56560e254" }, "Method": "GET", "Response": { - "BODY": "{\"recoveryId\":\"https://cpp-recordings.vault.azure.net/deletedkeys/RecoverOperationResumeToken\",\"deletedDate\":1638401719,\"scheduledPurgeDate\":1646177719,\"key\":{\"kid\":\"https://cpp-recordings.vault.azure.net/keys/RecoverOperationResumeToken/3221e32d5c7849d3bcf6f9ec3eefee72\",\"kty\":\"EC\",\"key_ops\":[\"sign\",\"verify\"],\"crv\":\"P-256\",\"x\":\"zcSKSmCxVecNVriYLG3DA3rv2T38PuPhBI2DwE9dk1E\",\"y\":\"cRyswPDlIXKNcw9xKv87jeYQ-ln2QP7VbYOxIKtETM0\"},\"attributes\":{\"enabled\":true,\"created\":1638401719,\"updated\":1638401719,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "BODY": "{\"recoveryId\":\"https://gearamakv1.vault.azure.net/deletedkeys/RecoverOperationResumeToken\",\"deletedDate\":1664233389,\"scheduledPurgeDate\":1672009389,\"key\":{\"kid\":\"https://gearamakv1.vault.azure.net/keys/RecoverOperationResumeToken/c84e0042769b4ff19e8135236bc79cf7\",\"kty\":\"EC\",\"key_ops\":[\"sign\",\"verify\"],\"crv\":\"P-256\",\"x\":\"6MQqHLBRpkDRcPwmimj--MXu0ZM76EaGU3_fys-FOik\",\"y\":\"rn6SBgwrHvW7wohlg2t59kyA_g_lWmUmblJo7l7hgU8\"},\"attributes\":{\"enabled\":true,\"created\":1664233384,\"updated\":1664233384,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90,\"exportable\":false}}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "559", + "content-length": "570", "content-type": "application/json; charset=utf-8", - "date": "Wed, 01 Dec 2021 23:36:19 GMT", + "date": "Mon, 26 Sep 2022 23:03:19 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "ca514e0a-4f95-44ce-4347-8c59fc7273fb", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "a3397bc8-ded5-4710-a77a-23d518b3d688", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "14b39ce9-f22c-4c3a-6cd8-07c56560e254", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "a796e84b-0d34-4a31-a036-46b8b0af2b1b" }, "Url": "https://REDACTED.vault.azure.net/deletedkeys/RecoverOperationResumeToken?api-version=7.3" }, { "Headers": { - "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "9ad7367f-ea95-4ae1-40c2-73c23bc2f763" + "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "98360ba3-ae67-4994-7d22-be5fc266b588" }, "Method": "POST", "Response": { - "BODY": "{\"key\":{\"kid\":\"https://cpp-recordings.vault.azure.net/keys/RecoverOperationResumeToken/3221e32d5c7849d3bcf6f9ec3eefee72\",\"kty\":\"EC\",\"key_ops\":[\"sign\",\"verify\"],\"crv\":\"P-256\",\"x\":\"zcSKSmCxVecNVriYLG3DA3rv2T38PuPhBI2DwE9dk1E\",\"y\":\"cRyswPDlIXKNcw9xKv87jeYQ-ln2QP7VbYOxIKtETM0\"},\"attributes\":{\"enabled\":true,\"created\":1638401719,\"updated\":1638401719,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "BODY": "{\"key\":{\"kid\":\"https://gearamakv1.vault.azure.net/keys/RecoverOperationResumeToken/c84e0042769b4ff19e8135236bc79cf7\",\"kty\":\"EC\",\"key_ops\":[\"sign\",\"verify\"],\"crv\":\"P-256\",\"x\":\"6MQqHLBRpkDRcPwmimj--MXu0ZM76EaGU3_fys-FOik\",\"y\":\"rn6SBgwrHvW7wohlg2t59kyA_g_lWmUmblJo7l7hgU8\"},\"attributes\":{\"enabled\":true,\"created\":1664233384,\"updated\":1664233384,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90,\"exportable\":false}}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "408", + "content-length": "423", "content-type": "application/json; charset=utf-8", - "date": "Wed, 01 Dec 2021 23:36:20 GMT", + "date": "Mon, 26 Sep 2022 23:03:21 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "9ad7367f-ea95-4ae1-40c2-73c23bc2f763", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "d9cf6d76-644f-476d-9507-34a1d30e7255", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "98360ba3-ae67-4994-7d22-be5fc266b588", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "cf2c77f5-3a6d-4eea-a53c-c02e6156743f" }, "Url": "https://REDACTED.vault.azure.net/deletedkeys/RecoverOperationResumeToken/recover?api-version=7.3" }, { "Headers": { - "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "53b0eea2-012e-4b10-40ce-1219e59bba03" + "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "00296b3f-e2a9-4709-4b8f-17fbae0eb0ba" }, "Method": "GET", "Response": { - "BODY": "{\"error\":{\"code\":\"KeyNotFound\",\"message\":\"A key with (name/id) RecoverOperationResumeToken was not found in this key vault. If you recently deleted this key you may be able to recover it using the correct recovery command. For help resolving this issue, please see https://go.microsoft.com/fwlink/?linkid=2125182\"}}", - "STATUS_CODE": "404", + "BODY": "{\"key\":{\"kid\":\"https://gearamakv1.vault.azure.net/keys/RecoverOperationResumeToken/c84e0042769b4ff19e8135236bc79cf7\",\"kty\":\"EC\",\"key_ops\":[\"sign\",\"verify\"],\"crv\":\"P-256\",\"x\":\"6MQqHLBRpkDRcPwmimj--MXu0ZM76EaGU3_fys-FOik\",\"y\":\"rn6SBgwrHvW7wohlg2t59kyA_g_lWmUmblJo7l7hgU8\"},\"attributes\":{\"enabled\":true,\"created\":1664233384,\"updated\":1664233384,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90,\"exportable\":false}}", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "315", + "content-length": "423", "content-type": "application/json; charset=utf-8", - "date": "Wed, 01 Dec 2021 23:36:20 GMT", + "date": "Mon, 26 Sep 2022 23:03:24 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "53b0eea2-012e-4b10-40ce-1219e59bba03", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "5782eb7c-1f65-4b53-be70-2871aeb24839", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "00296b3f-e2a9-4709-4b8f-17fbae0eb0ba", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "e4582463-192a-4caa-82ea-2ea87bcf2483" }, "Url": "https://REDACTED.vault.azure.net/keys/RecoverOperationResumeToken?api-version=7.3" }, { "Headers": { - "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "d7eb5d21-7f14-4fd3-51ea-d9978a3ff31c" + "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "60217f43-7d7d-404d-4a58-9110f6216c64" }, "Method": "GET", "Response": { - "BODY": "{\"error\":{\"code\":\"KeyNotFound\",\"message\":\"A key with (name/id) RecoverOperationResumeToken was not found in this key vault. If you recently deleted this key you may be able to recover it using the correct recovery command. For help resolving this issue, please see https://go.microsoft.com/fwlink/?linkid=2125182\"}}", - "STATUS_CODE": "404", + "BODY": "{\"key\":{\"kid\":\"https://gearamakv1.vault.azure.net/keys/RecoverOperationResumeToken/c84e0042769b4ff19e8135236bc79cf7\",\"kty\":\"EC\",\"key_ops\":[\"sign\",\"verify\"],\"crv\":\"P-256\",\"x\":\"6MQqHLBRpkDRcPwmimj--MXu0ZM76EaGU3_fys-FOik\",\"y\":\"rn6SBgwrHvW7wohlg2t59kyA_g_lWmUmblJo7l7hgU8\"},\"attributes\":{\"enabled\":true,\"created\":1664233384,\"updated\":1664233384,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90,\"exportable\":false}}", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "315", + "content-length": "423", "content-type": "application/json; charset=utf-8", - "date": "Wed, 01 Dec 2021 23:36:19 GMT", + "date": "Mon, 26 Sep 2022 23:03:26 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "d7eb5d21-7f14-4fd3-51ea-d9978a3ff31c", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "e189cf9f-4b40-4b05-925f-89d12cbbe428", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "60217f43-7d7d-404d-4a58-9110f6216c64", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "108d855a-8b11-4a2c-ad52-06569d6d9ffa" }, "Url": "https://REDACTED.vault.azure.net/keys/RecoverOperationResumeToken?api-version=7.3" }, { "Headers": { - "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "184d55ba-d360-4887-6612-742e7def21fa" + "user-agent": "azsdk-cpp-keyvault-keys/4.3.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "d7e0d514-c8b5-4a92-43d4-68a816e09f04" }, "Method": "GET", "Response": { - "BODY": "{\"key\":{\"kid\":\"https://cpp-recordings.vault.azure.net/keys/RecoverOperationResumeToken/3221e32d5c7849d3bcf6f9ec3eefee72\",\"kty\":\"EC\",\"key_ops\":[\"sign\",\"verify\"],\"crv\":\"P-256\",\"x\":\"zcSKSmCxVecNVriYLG3DA3rv2T38PuPhBI2DwE9dk1E\",\"y\":\"cRyswPDlIXKNcw9xKv87jeYQ-ln2QP7VbYOxIKtETM0\"},\"attributes\":{\"enabled\":true,\"created\":1638401719,\"updated\":1638401719,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "BODY": "{\"key\":{\"kid\":\"https://gearamakv1.vault.azure.net/keys/RecoverOperationResumeToken/c84e0042769b4ff19e8135236bc79cf7\",\"kty\":\"EC\",\"key_ops\":[\"sign\",\"verify\"],\"crv\":\"P-256\",\"x\":\"6MQqHLBRpkDRcPwmimj--MXu0ZM76EaGU3_fys-FOik\",\"y\":\"rn6SBgwrHvW7wohlg2t59kyA_g_lWmUmblJo7l7hgU8\"},\"attributes\":{\"enabled\":true,\"created\":1664233384,\"updated\":1664233384,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90,\"exportable\":false}}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "408", + "content-length": "423", "content-type": "application/json; charset=utf-8", - "date": "Wed, 01 Dec 2021 23:37:19 GMT", + "date": "Mon, 26 Sep 2022 23:03:48 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "184d55ba-d360-4887-6612-742e7def21fa", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "7ec69d73-dc5d-4213-8212-b253fbcda75e", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "d7e0d514-c8b5-4a92-43d4-68a816e09f04", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "2a331b44-d295-4cd5-a993-5ccc37e4f6b8" }, "Url": "https://REDACTED.vault.azure.net/keys/RecoverOperationResumeToken?api-version=7.3" } diff --git a/sdk/keyvault/azure-security-keyvault-secrets/test/ut/recordings/KeyVaultSecretClientTest.RecoverSecret.json b/sdk/keyvault/azure-security-keyvault-secrets/test/ut/recordings/KeyVaultSecretClientTest.RecoverSecret.json index 1b22ed2c35..e555905f53 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/test/ut/recordings/KeyVaultSecretClientTest.RecoverSecret.json +++ b/sdk/keyvault/azure-security-keyvault-secrets/test/ut/recordings/KeyVaultSecretClientTest.RecoverSecret.json @@ -3,243 +3,297 @@ { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-secrets/4.0.0-beta.2 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "b315f13d-18c7-4506-4a4e-2d425887206a" + "user-agent": "azsdk-cpp-keyvault-secrets/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "7a890d41-2fde-4caf-6399-a9367492166f" }, "Method": "PUT", "Response": { - "BODY": "{\"value\":\"secretValue\",\"id\":\"https://cpp-recordings.vault.azure.net/secrets/RecoverSecret/02c7cf853d624ae9943c9261d04e8fff\",\"attributes\":{\"enabled\":true,\"created\":1638430494,\"updated\":1638430494,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "BODY": "{\"value\":\"secretValue\",\"id\":\"https://REDACTED.vault.azure.net/secrets/RecoverSecret/33b68cc2fd1b4e188a82d4620671626c\",\"attributes\":{\"enabled\":true,\"created\":1663696630,\"updated\":1663696630,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "257", + "content-length": "253", "content-type": "application/json; charset=utf-8", - "date": "Thu, 02 Dec 2021 07:34:53 GMT", + "date": "Tue, 20 Sep 2022 17:57:10 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "b315f13d-18c7-4506-4a4e-2d425887206a", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "f6eccd3a-84d5-4f33-827f-18615606d9cf", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "7a890d41-2fde-4caf-6399-a9367492166f", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "583108e0-f174-4186-a9a6-063c659bf3b3" }, "Url": "https://REDACTED.vault.azure.net/secrets/RecoverSecret?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-secrets/4.0.0-beta.2 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "8f3b4359-3493-4bd4-7e50-05a90ea939a0" + "user-agent": "azsdk-cpp-keyvault-secrets/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "99123f57-e08b-49af-4723-a31c5897b59f" }, "Method": "DELETE", "Response": { - "BODY": "{\"recoveryId\":\"https://cpp-recordings.vault.azure.net/deletedsecrets/RecoverSecret\",\"deletedDate\":1638430494,\"scheduledPurgeDate\":1646206494,\"id\":\"https://cpp-recordings.vault.azure.net/secrets/RecoverSecret/02c7cf853d624ae9943c9261d04e8fff\",\"attributes\":{\"enabled\":true,\"created\":1638430494,\"updated\":1638430494,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "BODY": "{\"recoveryId\":\"https://REDACTED.vault.azure.net/deletedsecrets/RecoverSecret\",\"deletedDate\":1663696630,\"scheduledPurgeDate\":1671472630,\"id\":\"https://REDACTED.vault.azure.net/secrets/RecoverSecret/33b68cc2fd1b4e188a82d4620671626c\",\"attributes\":{\"enabled\":true,\"created\":1663696630,\"updated\":1663696630,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "375", + "content-length": "367", "content-type": "application/json; charset=utf-8", - "date": "Thu, 02 Dec 2021 07:34:53 GMT", + "date": "Tue, 20 Sep 2022 17:57:10 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "8f3b4359-3493-4bd4-7e50-05a90ea939a0", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "cb173625-922a-469a-8ac4-a3cbdd3c8398", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "99123f57-e08b-49af-4723-a31c5897b59f", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "48779582-6203-4f30-9f5b-fbb1803750e1" }, "Url": "https://REDACTED.vault.azure.net/secrets/RecoverSecret?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-secrets/4.0.0-beta.2 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "970dcf7a-8b59-4f6d-6970-9ed86c8254e8" + "user-agent": "azsdk-cpp-keyvault-secrets/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "855bb681-89fd-46d1-4280-c0794d0fd331" }, "Method": "GET", "Response": { "BODY": "{\"error\":{\"code\":\"SecretNotFound\",\"message\":\"Deleted Secret not found: RecoverSecret\"}}", + "REASON_PHRASE": "Not Found", "STATUS_CODE": "404", "cache-control": "no-cache", "content-length": "87", "content-type": "application/json; charset=utf-8", - "date": "Thu, 02 Dec 2021 07:34:53 GMT", + "date": "Tue, 20 Sep 2022 17:57:10 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "970dcf7a-8b59-4f6d-6970-9ed86c8254e8", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "a19282a6-f411-49b2-97c4-8a77d5407781", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "855bb681-89fd-46d1-4280-c0794d0fd331", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "1e1ccb5b-df88-4626-baf8-2657aa4304c1" }, "Url": "https://REDACTED.vault.azure.net/deletedsecrets/RecoverSecret?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-secrets/4.0.0-beta.2 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "364b91c8-f085-40e1-4cbd-71c6a049f9d3" + "user-agent": "azsdk-cpp-keyvault-secrets/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "4023b866-2c0d-460e-4856-170e6c02073e" }, "Method": "GET", "Response": { - "BODY": "{\"recoveryId\":\"https://cpp-recordings.vault.azure.net/deletedsecrets/RecoverSecret\",\"deletedDate\":1638430494,\"scheduledPurgeDate\":1646206494,\"id\":\"https://cpp-recordings.vault.azure.net/secrets/RecoverSecret/02c7cf853d624ae9943c9261d04e8fff\",\"attributes\":{\"enabled\":true,\"created\":1638430494,\"updated\":1638430494,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "BODY": "{\"recoveryId\":\"https://REDACTED.vault.azure.net/deletedsecrets/RecoverSecret\",\"deletedDate\":1663696630,\"scheduledPurgeDate\":1671472630,\"id\":\"https://REDACTED.vault.azure.net/secrets/RecoverSecret/33b68cc2fd1b4e188a82d4620671626c\",\"attributes\":{\"enabled\":true,\"created\":1663696630,\"updated\":1663696630,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "375", + "content-length": "367", "content-type": "application/json; charset=utf-8", - "date": "Thu, 02 Dec 2021 07:35:54 GMT", + "date": "Tue, 20 Sep 2022 17:58:10 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "364b91c8-f085-40e1-4cbd-71c6a049f9d3", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "8305a020-8939-42d2-b285-51b8b99ac542", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "4023b866-2c0d-460e-4856-170e6c02073e", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "40417cbf-60ca-40e2-ae23-81142d88384d" }, "Url": "https://REDACTED.vault.azure.net/deletedsecrets/RecoverSecret?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-secrets/4.0.0-beta.2 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "4b6f434b-857a-4c2c-5d7c-1a9b4d0e2798" + "user-agent": "azsdk-cpp-keyvault-secrets/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "ffc85f1d-6c09-4c50-40f5-66545c0a7c2e" }, "Method": "GET", "Response": { - "BODY": "{\"recoveryId\":\"https://cpp-recordings.vault.azure.net/deletedsecrets/RecoverSecret\",\"deletedDate\":1638430494,\"scheduledPurgeDate\":1646206494,\"id\":\"https://cpp-recordings.vault.azure.net/secrets/RecoverSecret/02c7cf853d624ae9943c9261d04e8fff\",\"attributes\":{\"enabled\":true,\"created\":1638430494,\"updated\":1638430494,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "BODY": "{\"recoveryId\":\"https://REDACTED.vault.azure.net/deletedsecrets/RecoverSecret\",\"deletedDate\":1663696630,\"scheduledPurgeDate\":1671472630,\"id\":\"https://REDACTED.vault.azure.net/secrets/RecoverSecret/33b68cc2fd1b4e188a82d4620671626c\",\"attributes\":{\"enabled\":true,\"created\":1663696630,\"updated\":1663696630,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "375", + "content-length": "367", "content-type": "application/json; charset=utf-8", - "date": "Thu, 02 Dec 2021 07:35:54 GMT", + "date": "Tue, 20 Sep 2022 17:58:10 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "4b6f434b-857a-4c2c-5d7c-1a9b4d0e2798", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "e1d578b3-ef3c-4e7f-a6c8-2cbc02d01612", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "ffc85f1d-6c09-4c50-40f5-66545c0a7c2e", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "28e02a7c-7a4f-483c-8a2b-e138b1988165" }, "Url": "https://REDACTED.vault.azure.net/deletedsecrets/RecoverSecret?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-secrets/4.0.0-beta.2 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "48c39290-20bb-494c-77bd-279297be85a4" + "user-agent": "azsdk-cpp-keyvault-secrets/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "1d5820a0-6de1-40de-4b29-ac400e4dcc06" + }, + "Method": "GET", + "Response": { + "BODY": "{\"recoveryId\":\"https://REDACTED.vault.azure.net/deletedsecrets/RecoverSecret\",\"deletedDate\":1663696630,\"scheduledPurgeDate\":1671472630,\"id\":\"https://REDACTED.vault.azure.net/secrets/RecoverSecret/33b68cc2fd1b4e188a82d4620671626c\",\"attributes\":{\"enabled\":true,\"created\":1663696630,\"updated\":1663696630,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "cache-control": "no-cache", + "content-length": "367", + "content-type": "application/json; charset=utf-8", + "date": "Tue, 20 Sep 2022 17:58:10 GMT", + "expires": "-1", + "pragma": "no-cache", + "strict-transport-security": "max-age=31536000;includeSubDomains", + "x-content-type-options": "nosniff", + "x-ms-client-request-id": "1d5820a0-6de1-40de-4b29-ac400e4dcc06", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "393a94b0-5b82-4779-b815-a0d578fb0d24" + }, + "Url": "https://REDACTED.vault.azure.net/deletedsecrets/RecoverSecret?api-version=7.3" + }, + { + "Headers": { + "content-type": "application/json", + "user-agent": "azsdk-cpp-keyvault-secrets/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "17e82636-6b07-4036-6154-f5b1656528a5" }, "Method": "POST", "Response": { - "BODY": "{\"id\":\"https://cpp-recordings.vault.azure.net/secrets/RecoverSecret/02c7cf853d624ae9943c9261d04e8fff\",\"attributes\":{\"enabled\":true,\"created\":1638430494,\"updated\":1638430494,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "BODY": "{\"id\":\"https://REDACTED.vault.azure.net/secrets/RecoverSecret/33b68cc2fd1b4e188a82d4620671626c\",\"attributes\":{\"enabled\":true,\"created\":1663696630,\"updated\":1663696630,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "235", + "content-length": "231", "content-type": "application/json; charset=utf-8", - "date": "Thu, 02 Dec 2021 07:35:54 GMT", + "date": "Tue, 20 Sep 2022 17:58:11 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "48c39290-20bb-494c-77bd-279297be85a4", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "296514bd-7374-4a3b-ba49-9c10929eda90", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "17e82636-6b07-4036-6154-f5b1656528a5", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "d7600e19-bb7d-4002-80a7-8be8db15fb0c" }, "Url": "https://REDACTED.vault.azure.net/deletedsecrets/RecoverSecret/recover?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-secrets/4.0.0-beta.2 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "3a9ee037-2ce5-4a45-5c5e-241d13af687a" + "user-agent": "azsdk-cpp-keyvault-secrets/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "1db99a8a-09af-4b59-49bb-a570771a4607" }, "Method": "GET", "Response": { "BODY": "{\"error\":{\"code\":\"SecretNotFound\",\"message\":\"A secret with (name/id) RecoverSecret was not found in this key vault. If you recently deleted this secret you may be able to recover it using the correct recovery command. For help resolving this issue, please see https://go.microsoft.com/fwlink/?linkid=2125182\"}}", + "REASON_PHRASE": "Not Found", "STATUS_CODE": "404", "cache-control": "no-cache", "content-length": "310", "content-type": "application/json; charset=utf-8", - "date": "Thu, 02 Dec 2021 07:35:54 GMT", + "date": "Tue, 20 Sep 2022 17:58:11 GMT", + "expires": "-1", + "pragma": "no-cache", + "strict-transport-security": "max-age=31536000;includeSubDomains", + "x-content-type-options": "nosniff", + "x-ms-client-request-id": "1db99a8a-09af-4b59-49bb-a570771a4607", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "546bc186-b706-482d-8138-48a880e4c7ed" + }, + "Url": "https://REDACTED.vault.azure.net/secrets/RecoverSecret?api-version=7.3" + }, + { + "Headers": { + "content-type": "application/json", + "user-agent": "azsdk-cpp-keyvault-secrets/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "76b99b98-5c0b-4cd3-51ea-939357396bbd" + }, + "Method": "GET", + "Response": { + "BODY": "{\"value\":\"secretValue\",\"id\":\"https://REDACTED.vault.azure.net/secrets/RecoverSecret/33b68cc2fd1b4e188a82d4620671626c\",\"attributes\":{\"enabled\":true,\"created\":1663696630,\"updated\":1663696630,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "cache-control": "no-cache", + "content-length": "253", + "content-type": "application/json; charset=utf-8", + "date": "Tue, 20 Sep 2022 17:59:11 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "3a9ee037-2ce5-4a45-5c5e-241d13af687a", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "0823c12e-e987-45cf-a2a9-b24dca87b851", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "76b99b98-5c0b-4cd3-51ea-939357396bbd", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "13006264-42d9-402e-aae4-97966c5fe234" }, "Url": "https://REDACTED.vault.azure.net/secrets/RecoverSecret?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-secrets/4.0.0-beta.2 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "b268a665-cf40-426c-4a88-1e88d1254605" + "user-agent": "azsdk-cpp-keyvault-secrets/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "38a6839e-c0cb-41c7-7517-d7999da59e88" }, "Method": "GET", "Response": { - "BODY": "{\"value\":\"secretValue\",\"id\":\"https://cpp-recordings.vault.azure.net/secrets/RecoverSecret/02c7cf853d624ae9943c9261d04e8fff\",\"attributes\":{\"enabled\":true,\"created\":1638430494,\"updated\":1638430494,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "BODY": "{\"value\":\"secretValue\",\"id\":\"https://REDACTED.vault.azure.net/secrets/RecoverSecret/33b68cc2fd1b4e188a82d4620671626c\",\"attributes\":{\"enabled\":true,\"created\":1663696630,\"updated\":1663696630,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "257", + "content-length": "253", "content-type": "application/json; charset=utf-8", - "date": "Thu, 02 Dec 2021 07:36:54 GMT", + "date": "Tue, 20 Sep 2022 17:59:11 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "b268a665-cf40-426c-4a88-1e88d1254605", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "91a75a73-7f6b-48b4-a40b-9e841562b8c5", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "38a6839e-c0cb-41c7-7517-d7999da59e88", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "ef98e29c-43ff-432a-823c-e74b37f1584a" }, "Url": "https://REDACTED.vault.azure.net/secrets/RecoverSecret?api-version=7.3" }, { "Headers": { "content-type": "application/json", - "user-agent": "azsdk-cpp-keyvault-secrets/4.0.0-beta.2 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "c3c46e29-655c-4129-5cd8-514817bd8d91" + "user-agent": "azsdk-cpp-keyvault-secrets/4.1.0-beta.2 (Windows 10 Enterprise 6.3 22621 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "9ec29260-3b8d-4b78-6312-165bdfd96603" }, "Method": "GET", "Response": { - "BODY": "{\"value\":\"secretValue\",\"id\":\"https://cpp-recordings.vault.azure.net/secrets/RecoverSecret/02c7cf853d624ae9943c9261d04e8fff\",\"attributes\":{\"enabled\":true,\"created\":1638430494,\"updated\":1638430494,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "BODY": "{\"value\":\"secretValue\",\"id\":\"https://REDACTED.vault.azure.net/secrets/RecoverSecret/33b68cc2fd1b4e188a82d4620671626c\",\"attributes\":{\"enabled\":true,\"created\":1663696630,\"updated\":1663696630,\"recoveryLevel\":\"Recoverable+Purgeable\",\"recoverableDays\":90}}", + "REASON_PHRASE": "OK", "STATUS_CODE": "200", "cache-control": "no-cache", - "content-length": "257", + "content-length": "253", "content-type": "application/json; charset=utf-8", - "date": "Thu, 02 Dec 2021 07:36:54 GMT", + "date": "Tue, 20 Sep 2022 17:59:11 GMT", "expires": "-1", "pragma": "no-cache", "strict-transport-security": "max-age=31536000;includeSubDomains", "x-content-type-options": "nosniff", - "x-ms-client-request-id": "c3c46e29-655c-4129-5cd8-514817bd8d91", - "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=20.49.4.206;act_addr_fam=InterNetwork;", - "x-ms-keyvault-region": "eastus", - "x-ms-keyvault-service-version": "1.9.195.1", - "x-ms-request-id": "48f14859-e237-4099-a744-02104caa90d3", - "x-powered-by": "ASP.NET" + "x-ms-client-request-id": "9ec29260-3b8d-4b78-6312-165bdfd96603", + "x-ms-keyvault-network-info": "conn_type=Ipv4;addr=24.22.157.72;act_addr_fam=InterNetwork;", + "x-ms-keyvault-region": "westus3", + "x-ms-keyvault-service-version": "1.9.538.1", + "x-ms-request-id": "6b44334d-f941-4a0a-8994-c95fefb780f7" }, "Url": "https://REDACTED.vault.azure.net/secrets/RecoverSecret?api-version=7.3" } diff --git a/sdk/keyvault/azure-security-keyvault-secrets/test/ut/secret_client_test.cpp b/sdk/keyvault/azure-security-keyvault-secrets/test/ut/secret_client_test.cpp index 0a2d425ce4..4327f910a7 100644 --- a/sdk/keyvault/azure-security-keyvault-secrets/test/ut/secret_client_test.cpp +++ b/sdk/keyvault/azure-security-keyvault-secrets/test/ut/secret_client_test.cpp @@ -203,6 +203,8 @@ TEST_F(KeyVaultSecretClientTest, RecoverSecret) } { auto operation = client.StartDeleteSecret(secretName); + // double polling should not have an impact on the result + operation.PollUntilDone(m_defaultWait); operation.PollUntilDone(m_defaultWait); EXPECT_EQ(operation.GetResumeToken(), secretName); EXPECT_EQ(operation.HasValue(), true); @@ -216,6 +218,8 @@ TEST_F(KeyVaultSecretClientTest, RecoverSecret) } { auto operation = client.StartRecoverDeletedSecret(secretName); + // double polling should not have an impact on the result + operation.PollUntilDone(m_defaultWait); operation.PollUntilDone(m_defaultWait); EXPECT_EQ(operation.GetResumeToken(), secretName); EXPECT_EQ(operation.HasValue(), true); diff --git a/sdk/storage/azure-storage-blobs/inc/azure/storage/blobs/blob_container_client.hpp b/sdk/storage/azure-storage-blobs/inc/azure/storage/blobs/blob_container_client.hpp index 74a4de2dc5..f77b34b94c 100644 --- a/sdk/storage/azure-storage-blobs/inc/azure/storage/blobs/blob_container_client.hpp +++ b/sdk/storage/azure-storage-blobs/inc/azure/storage/blobs/blob_container_client.hpp @@ -338,6 +338,7 @@ namespace Azure { namespace Storage { namespace Blobs { friend class BlobServiceClient; friend class BlobLeaseClient; friend class BlobContainerBatch; + friend class Files::DataLake::DataLakeFileSystemClient; }; }}} // namespace Azure::Storage::Blobs diff --git a/sdk/storage/azure-storage-blobs/inc/azure/storage/blobs/rest_client.hpp b/sdk/storage/azure-storage-blobs/inc/azure/storage/blobs/rest_client.hpp index 2cb58be985..1619af2717 100644 --- a/sdk/storage/azure-storage-blobs/inc/azure/storage/blobs/rest_client.hpp +++ b/sdk/storage/azure-storage-blobs/inc/azure/storage/blobs/rest_client.hpp @@ -1365,6 +1365,10 @@ namespace Azure { namespace Storage { namespace Blobs { * Type of the blob. */ Models::BlobType BlobType; + /** + * The deletion ID associated with the deleted path. + */ + Nullable DeletionId; }; } // namespace _detail /** @@ -3447,6 +3451,7 @@ namespace Azure { namespace Storage { namespace Blobs { Nullable Marker; Nullable MaxResults; Nullable Include; + Nullable ShowOnly; }; static Response ListBlobsByHierarchy( Core::Http::_internal::HttpPipeline& pipeline, diff --git a/sdk/storage/azure-storage-blobs/src/rest_client.cpp b/sdk/storage/azure-storage-blobs/src/rest_client.cpp index 22277f0397..f49fb800c5 100644 --- a/sdk/storage/azure-storage-blobs/src/rest_client.cpp +++ b/sdk/storage/azure-storage-blobs/src/rest_client.cpp @@ -2310,6 +2310,7 @@ namespace Azure { namespace Storage { namespace Blobs { kHasVersionsOnly, kContentLength, kBlobType, + kDeletionId, }; const std::unordered_map XmlTagEnumMap{ {"EnumerationResults", XmlTagEnum::kEnumerationResults}, @@ -2370,6 +2371,7 @@ namespace Azure { namespace Storage { namespace Blobs { {"HasVersionsOnly", XmlTagEnum::kHasVersionsOnly}, {"Content-Length", XmlTagEnum::kContentLength}, {"BlobType", XmlTagEnum::kBlobType}, + {"DeletionId", XmlTagEnum::kDeletionId}, }; std::vector xmlPath; Models::_detail::BlobItem vectorElement1; @@ -2807,6 +2809,13 @@ namespace Azure { namespace Storage { namespace Blobs { { vectorElement1.BlobType = Models::BlobType(node.Value); } + else if ( + xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kBlobs && xmlPath[2] == XmlTagEnum::kBlob + && xmlPath[3] == XmlTagEnum::kDeletionId) + { + vectorElement1.DeletionId = node.Value; + } } else if (node.Type == _internal::XmlNodeType::Attribute) { @@ -2908,6 +2917,11 @@ namespace Azure { namespace Storage { namespace Blobs { ListBlobsIncludeFlagsToString(options.Include.Value()))); } request.SetHeader("x-ms-version", "2021-04-10"); + if (options.ShowOnly.HasValue() && !options.ShowOnly.Value().empty()) + { + request.GetUrl().AppendQueryParameter( + "showonly", _internal::UrlEncodeQueryParameter(options.ShowOnly.Value())); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -2981,6 +2995,7 @@ namespace Azure { namespace Storage { namespace Blobs { kHasVersionsOnly, kContentLength, kBlobType, + kDeletionId, kBlobPrefix, }; const std::unordered_map XmlTagEnumMap{ @@ -3043,6 +3058,7 @@ namespace Azure { namespace Storage { namespace Blobs { {"HasVersionsOnly", XmlTagEnum::kHasVersionsOnly}, {"Content-Length", XmlTagEnum::kContentLength}, {"BlobType", XmlTagEnum::kBlobType}, + {"DeletionId", XmlTagEnum::kDeletionId}, {"BlobPrefix", XmlTagEnum::kBlobPrefix}, }; std::vector xmlPath; @@ -3488,6 +3504,13 @@ namespace Azure { namespace Storage { namespace Blobs { { vectorElement1.BlobType = Models::BlobType(node.Value); } + else if ( + xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kBlobs && xmlPath[2] == XmlTagEnum::kBlob + && xmlPath[3] == XmlTagEnum::kDeletionId) + { + vectorElement1.DeletionId = node.Value; + } else if ( xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults && xmlPath[1] == XmlTagEnum::kBlobs && xmlPath[2] == XmlTagEnum::kBlobPrefix @@ -5573,9 +5596,15 @@ namespace Azure { namespace Storage { namespace Blobs { response.LeaseDuration = Models::LeaseDurationType(pRawResponse->GetHeaders().at("x-ms-lease-duration")); } - response.LeaseState = Models::LeaseState(pRawResponse->GetHeaders().at("x-ms-lease-state")); - response.LeaseStatus - = Models::LeaseStatus(pRawResponse->GetHeaders().at("x-ms-lease-status")); + if (pRawResponse->GetHeaders().count("x-ms-lease-state") != 0) + { + response.LeaseState = Models::LeaseState(pRawResponse->GetHeaders().at("x-ms-lease-state")); + } + if (pRawResponse->GetHeaders().count("x-ms-lease-status") != 0) + { + response.LeaseStatus + = Models::LeaseStatus(pRawResponse->GetHeaders().at("x-ms-lease-status")); + } response.IsServerEncrypted = pRawResponse->GetHeaders().at("x-ms-server-encrypted") == std::string("true"); return Response(std::move(response), std::move(pRawResponse)); diff --git a/sdk/storage/azure-storage-blobs/swagger/README.md b/sdk/storage/azure-storage-blobs/swagger/README.md index 66b8270fd4..efb40c7ee0 100644 --- a/sdk/storage/azure-storage-blobs/swagger/README.md +++ b/sdk/storage/azure-storage-blobs/swagger/README.md @@ -273,6 +273,15 @@ directive: {"value": "legalhold", "name": "LegalHold"}, {"value": "deletedwithversions", "name": "DeletedWithVersions"} ]; + $["ListBlobsShowOnly"]= { + "name": "showonly", + "x-ms-client-name": "ShowOnly", + "in": "query", + "required": false, + "type": "string", + "x-ms-parameter-location": "method", + "description": "Include this parameter to specify one or more datasets to include in the response." + }; $.DeleteSnapshots["x-ms-enum"]["name"] = "DeleteSnapshotsOption"; $.DeleteSnapshots["x-ms-enum"]["values"] = [{"value": "include", "name": "IncludeSnapshots"},{"value":"only", "name": "OnlySnapshots"}]; $.BlobExpiryOptions["x-ms-enum"]["name"] = "ScheduleBlobExpiryOriginType"; @@ -829,6 +838,7 @@ directive: $.BlobItemInternal.properties["BlobType"] = $.BlobPropertiesInternal.properties["BlobType"]; $.BlobItemInternal.properties["BlobType"]["x-ms-xml"] = {"name": "Properties/BlobType"}; delete $.BlobPropertiesInternal.properties["BlobType"]; + $.BlobItemInternal.properties["DeletionId"] = {"type": "string"}; $.BlobItemInternal.required.push("BlobType", "BlobSize"); $.BlobItemInternal.properties["Name"].description = "Blob name."; $.BlobItemInternal.properties["Deleted"].description = "Indicates whether this blob was deleted."; @@ -837,6 +847,7 @@ directive: $.BlobItemInternal.properties["IsCurrentVersion"].description = "Indicates if this is the current version of the blob."; $.BlobItemInternal.properties["BlobType"].description = "Type of the blob."; $.BlobItemInternal.properties["HasVersionsOnly"].description = "Indicates that this root blob has been deleted, but it has versions that are active."; + $.BlobItemInternal.properties["DeletionId"].description = "The deletion ID associated with the deleted path."; $.BlobPropertiesInternal.properties["Etag"]["x-ms-client-name"] = "ETag"; $.BlobPropertiesInternal["x-ms-client-name"] = "BlobItemDetails"; @@ -916,6 +927,10 @@ directive: delete $.ListBlobsHierarchySegmentResponse.properties["Segment"]; delete $.ListBlobsHierarchySegmentResponse.required; $.ListBlobsHierarchySegmentResponse.properties["NextMarker"]["x-nullable"] = true; + - from: swagger-document + where: $["x-ms-paths"]["/{containerName}?restype=container&comp=list&hierarchy"].get.parameters + transform: > + $.push({"$ref": "#/parameters/ListBlobsShowOnly"}); ``` ### DownloadBlob @@ -1312,6 +1327,10 @@ directive: delete $[status_code].headers["x-ms-blob-content-md5"]; delete $[status_code].headers["x-ms-content-crc64"]; $[status_code].headers["x-ms-lease-duration"]["x-nullable"] = true; + $[status_code].headers["x-ms-lease-state"]["x-ms-client-default"] = ""; + $[status_code].headers["x-ms-lease-state"]["x-nullable"] = true; + $[status_code].headers["x-ms-lease-status"]["x-ms-client-default"] = ""; + $[status_code].headers["x-ms-lease-status"]["x-nullable"] = true; } ``` diff --git a/sdk/storage/azure-storage-blobs/test/ut/blob_batch_client_test.cpp b/sdk/storage/azure-storage-blobs/test/ut/blob_batch_client_test.cpp index 85953ecb72..74aebf5b9f 100644 --- a/sdk/storage/azure-storage-blobs/test/ut/blob_batch_client_test.cpp +++ b/sdk/storage/azure-storage-blobs/test/ut/blob_batch_client_test.cpp @@ -74,6 +74,49 @@ namespace Azure { namespace Storage { namespace Test { container2Client.Delete(); } + TEST_F(BlobBatchClientTest, SnapshotVersion) + { + const std::string testName = GetTestNameLowerCase(); + + const std::string containerName1 = testName + "1"; + const std::string blob1Name = "blockblob1"; + auto serviceClient = GetClientForTest(testName); + auto container1Client = serviceClient.GetBlobContainerClient(containerName1); + container1Client.CreateIfNotExists(); + auto blob1Client = container1Client.GetBlockBlobClient(blob1Name); + auto versionId = blob1Client.UploadFrom(nullptr, 0).Value.VersionId.Value(); + auto snapshotId = blob1Client.CreateSnapshot().Value.Snapshot; + + EXPECT_NO_THROW(blob1Client.WithVersionId(versionId).GetProperties()); + EXPECT_NO_THROW(blob1Client.WithSnapshot(snapshotId).GetProperties()); + + auto batch = serviceClient.CreateBatch(); + auto r1 = batch.SetBlobAccessTierUrl( + blob1Client.WithVersionId(versionId).GetUrl(), Blobs::Models::AccessTier::Cool); + auto r2 = batch.SetBlobAccessTierUrl( + blob1Client.WithSnapshot(snapshotId).GetUrl(), Blobs::Models::AccessTier::Cool); + EXPECT_NO_THROW(serviceClient.SubmitBatch(batch)); + EXPECT_NO_THROW(r1.GetResponse()); + EXPECT_NO_THROW(r2.GetResponse()); + EXPECT_EQ( + blob1Client.WithVersionId(versionId).GetProperties().Value.AccessTier.Value(), + Blobs::Models::AccessTier::Cool); + EXPECT_EQ( + blob1Client.WithSnapshot(snapshotId).GetProperties().Value.AccessTier.Value(), + Blobs::Models::AccessTier::Cool); + + batch = serviceClient.CreateBatch(); + auto r3 = batch.DeleteBlobUrl(blob1Client.WithVersionId(versionId).GetUrl()); + auto r4 = batch.DeleteBlobUrl(blob1Client.WithSnapshot(snapshotId).GetUrl()); + EXPECT_NO_THROW(serviceClient.SubmitBatch(batch)); + EXPECT_NO_THROW(r3.GetResponse()); + EXPECT_NO_THROW(r4.GetResponse()); + EXPECT_THROW(blob1Client.WithVersionId(versionId).GetProperties(), StorageException); + EXPECT_THROW(blob1Client.WithSnapshot(snapshotId).GetProperties(), StorageException); + + container1Client.DeleteIfExists(); + } + TEST_F(BlobBatchClientTest, SubmitSetTierBatch_LIVEONLY_) { const std::string testName = GetTestNameLowerCase(); diff --git a/sdk/storage/azure-storage-blobs/test/ut/blob_query_test.cpp b/sdk/storage/azure-storage-blobs/test/ut/blob_query_test.cpp index 7a139f8093..cab73b98ef 100644 --- a/sdk/storage/azure-storage-blobs/test/ut/blob_query_test.cpp +++ b/sdk/storage/azure-storage-blobs/test/ut/blob_query_test.cpp @@ -130,7 +130,7 @@ id,name,price R"json({"id":"103","name":"apples","price":"99"}|{"id":"106","name":"lemons","price":"69"}|{"id":"110","name":"bananas","price":"39"}|{"id":"112","name":"sapote,mamey","price":"50"}|)json"); } - TEST_F(BlockBlobClientTest, DISABLED_QueryCsvInputArrowOutput_LIVEONLY_) + TEST_F(BlockBlobClientTest, QueryCsvInputArrowOutput_LIVEONLY_) { auto const testName(GetTestName()); auto client = GetBlockBlobClient(testName); diff --git a/sdk/storage/azure-storage-blobs/test/ut/recordings/BlobBatchClientTest.snapshotversion.json b/sdk/storage/azure-storage-blobs/test/ut/recordings/BlobBatchClientTest.snapshotversion.json new file mode 100644 index 0000000000..ebe1c99d23 --- /dev/null +++ b/sdk/storage/azure-storage-blobs/test/ut/recordings/BlobBatchClientTest.snapshotversion.json @@ -0,0 +1,441 @@ +{ + "networkCallRecords": [ + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "28fa5b34-9354-433d-7c40-83a54c6a596e", + "x-ms-version": "2021-04-10" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Thu, 29 Sep 2022 05:35:33 GMT", + "etag": "\"0x8DAA1DC6E905B2E\"", + "last-modified": "Thu, 29 Sep 2022 05:35:34 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "28fa5b34-9354-433d-7c40-83a54c6a596e", + "x-ms-request-id": "13fcb1fc-701e-0087-42c5-d349a7000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1?restype=container" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "2ed13889-279c-4aca-4c62-db4d7931f318", + "x-ms-version": "2021-04-10" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "content-md5": "1B2M2Y8AsgTpgAmY7PhCfg==", + "date": "Thu, 29 Sep 2022 05:35:34 GMT", + "etag": "\"0x8DAA1DC6EB9DF3D\"", + "last-modified": "Thu, 29 Sep 2022 05:35:34 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "2ed13889-279c-4aca-4c62-db4d7931f318", + "x-ms-content-crc64": "AAAAAAAAAAA=", + "x-ms-request-id": "13fcb31a-701e-0087-3ac5-d349a7000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-04-10", + "x-ms-version-id": "2022-09-29T05:35:34.8898621Z" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1/blockblob1" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "594bb2f0-c7df-4242-434a-0b376b05a156", + "x-ms-version": "2021-04-10" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Thu, 29 Sep 2022 05:35:34 GMT", + "etag": "\"0x8DAA1DC6EB9DF3D\"", + "last-modified": "Thu, 29 Sep 2022 05:35:34 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "594bb2f0-c7df-4242-434a-0b376b05a156", + "x-ms-request-id": "13fcb439-701e-0087-2fc5-d349a7000000", + "x-ms-request-server-encrypted": "false", + "x-ms-snapshot": "2022-09-29T05:35:35.1876922Z", + "x-ms-version": "2021-04-10", + "x-ms-version-id": "2022-09-29T05:35:35.1886922Z" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1/blockblob1?comp=snapshot" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "b94f9407-62f4-4e54-667d-bfb139a408ce", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "0", + "content-md5": "1B2M2Y8AsgTpgAmY7PhCfg==", + "content-type": "application/octet-stream", + "date": "Thu, 29 Sep 2022 05:35:34 GMT", + "etag": "\"0x8DAA1DC6EB9DF3D\"", + "last-modified": "Thu, 29 Sep 2022 05:35:34 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "vary": "Origin", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "b94f9407-62f4-4e54-667d-bfb139a408ce", + "x-ms-creation-time": "Thu, 29 Sep 2022 05:35:34 GMT", + "x-ms-request-id": "13fcb536-701e-0087-08c5-d349a7000000", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10", + "x-ms-version-id": "2022-09-29T05:35:34.8898621Z" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1/blockblob1?versionid=2022-09-29T05:35:34.8898621Z" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "e6ed2d49-05d1-4752-4c60-b4a119c874ad", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "0", + "content-md5": "1B2M2Y8AsgTpgAmY7PhCfg==", + "content-type": "application/octet-stream", + "date": "Thu, 29 Sep 2022 05:35:34 GMT", + "etag": "\"0x8DAA1DC6EB9DF3D\"", + "last-modified": "Thu, 29 Sep 2022 05:35:34 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "vary": "Origin", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "e6ed2d49-05d1-4752-4c60-b4a119c874ad", + "x-ms-creation-time": "Thu, 29 Sep 2022 05:35:34 GMT", + "x-ms-request-id": "13fcb621-701e-0087-4ac5-d349a7000000", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1/blockblob1?snapshot=2022-09-29T05:35:35.1876922Z" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "a3c63c49-4f68-4262-6ef5-ddfa5eba98b5", + "x-ms-version": "2021-04-10" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1/blockblob1?comp=tier&versionid=2022-09-29T05:35:34.8898621Z" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "e6860115-9b32-4875-686d-d07d839b038a", + "x-ms-version": "2021-04-10" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1/blockblob1?comp=tier&snapshot=2022-09-29T05:35:35.1876922Z" + }, + { + "Headers": { + "content-type": "multipart/mixed; boundary=batch_ce0d5cce-7902-4158-6a57-d86270cba9d0", + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "0bc63974-f7dd-40a3-7d50-2deeb786e3b3", + "x-ms-version": "2021-04-10" + }, + "Method": "POST", + "Response": { + "BODY": "--batchresponse_00dc6021-c4ca-4eed-b7b3-fd0afed844a6\r\nContent-Type: application/http\r\nContent-ID: 0\r\n\r\nHTTP/1.1 200 OK\r\nx-ms-request-id: 13fcb705-701e-0087-0dc5-d349a71eccb8\r\nx-ms-version: 2021-04-10\r\nx-ms-client-request-id: a3c63c49-4f68-4262-6ef5-ddfa5eba98b5\r\nServer: Windows-Azure-Blob/1.0\r\n\r\n--batchresponse_00dc6021-c4ca-4eed-b7b3-fd0afed844a6\r\nContent-Type: application/http\r\nContent-ID: 1\r\n\r\nHTTP/1.1 200 OK\r\nx-ms-request-id: 13fcb705-701e-0087-0dc5-d349a71eccc2\r\nx-ms-version: 2021-04-10\r\nx-ms-client-request-id: e6860115-9b32-4875-686d-d07d839b038a\r\nServer: Windows-Azure-Blob/1.0\r\n\r\n--batchresponse_00dc6021-c4ca-4eed-b7b3-fd0afed844a6--", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202", + "content-type": "multipart/mixed; boundary=batchresponse_00dc6021-c4ca-4eed-b7b3-fd0afed844a6", + "date": "Thu, 29 Sep 2022 05:35:36 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "0bc63974-f7dd-40a3-7d50-2deeb786e3b3", + "x-ms-request-id": "13fcb705-701e-0087-0dc5-d349a7000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net?comp=batch" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "e9e9e582-4805-4982-714e-b76f3f42e413", + "x-ms-version": "2021-04-10" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "Server": "Windows-Azure-Blob/1.0", + "x-ms-client-request-id": "a3c63c49-4f68-4262-6ef5-ddfa5eba98b5", + "x-ms-request-id": "13fcb705-701e-0087-0dc5-d349a71eccb8", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1/blockblob1?comp=tier&versionid=2022-09-29T05:35:34.8898621Z" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "c1577751-42fa-4684-6ad3-eedb175a7257", + "x-ms-version": "2021-04-10" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "Server": "Windows-Azure-Blob/1.0", + "x-ms-client-request-id": "e6860115-9b32-4875-686d-d07d839b038a", + "x-ms-request-id": "13fcb705-701e-0087-0dc5-d349a71eccc2", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1/blockblob1?comp=tier&snapshot=2022-09-29T05:35:35.1876922Z" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "bf160e75-878a-4204-7e19-34551ef98515", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "0", + "content-md5": "1B2M2Y8AsgTpgAmY7PhCfg==", + "content-type": "application/octet-stream", + "date": "Thu, 29 Sep 2022 05:35:37 GMT", + "etag": "\"0x8DAA1DC6EB9DF3D\"", + "last-modified": "Thu, 29 Sep 2022 05:35:34 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "vary": "Origin", + "x-ms-access-tier": "Cool", + "x-ms-access-tier-change-time": "Thu, 29 Sep 2022 05:35:37 GMT", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "bf160e75-878a-4204-7e19-34551ef98515", + "x-ms-creation-time": "Thu, 29 Sep 2022 05:35:34 GMT", + "x-ms-request-id": "13fcbe30-701e-0087-60c5-d349a7000000", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10", + "x-ms-version-id": "2022-09-29T05:35:34.8898621Z" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1/blockblob1?versionid=2022-09-29T05:35:34.8898621Z" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "fe479533-bfac-4990-420f-586ea80b4642", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "0", + "content-md5": "1B2M2Y8AsgTpgAmY7PhCfg==", + "content-type": "application/octet-stream", + "date": "Thu, 29 Sep 2022 05:35:37 GMT", + "etag": "\"0x8DAA1DC6EB9DF3D\"", + "last-modified": "Thu, 29 Sep 2022 05:35:34 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "vary": "Origin", + "x-ms-access-tier": "Cool", + "x-ms-access-tier-change-time": "Thu, 29 Sep 2022 05:35:36 GMT", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "fe479533-bfac-4990-420f-586ea80b4642", + "x-ms-creation-time": "Thu, 29 Sep 2022 05:35:34 GMT", + "x-ms-request-id": "13fcbf19-701e-0087-15c5-d349a7000000", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1/blockblob1?snapshot=2022-09-29T05:35:35.1876922Z" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "49162703-3f89-407f-4316-ba4dc5761ce2", + "x-ms-version": "2021-04-10" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1/blockblob1?versionid=2022-09-29T05:35:34.8898621Z" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "be815ff7-305f-4d31-6a34-5316ef5333cf", + "x-ms-version": "2021-04-10" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1/blockblob1?snapshot=2022-09-29T05:35:35.1876922Z" + }, + { + "Headers": { + "content-type": "multipart/mixed; boundary=batch_f4879f2e-8b0e-490c-6314-d14a3112d1f9", + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "873ecb93-8623-4bf2-7df7-168241db548b", + "x-ms-version": "2021-04-10" + }, + "Method": "POST", + "Response": { + "BODY": "--batchresponse_b54afdbc-442c-44ac-8511-f7d6ed97440d\r\nContent-Type: application/http\r\nContent-ID: 0\r\n\r\nHTTP/1.1 202 Accepted\r\nx-ms-delete-type-permanent: true\r\nx-ms-request-id: 13fcc029-701e-0087-74c5-d349a71ecd28\r\nx-ms-version: 2021-04-10\r\nx-ms-client-request-id: 49162703-3f89-407f-4316-ba4dc5761ce2\r\nServer: Windows-Azure-Blob/1.0\r\n\r\n--batchresponse_b54afdbc-442c-44ac-8511-f7d6ed97440d\r\nContent-Type: application/http\r\nContent-ID: 1\r\n\r\nHTTP/1.1 202 Accepted\r\nx-ms-delete-type-permanent: true\r\nx-ms-request-id: 13fcc029-701e-0087-74c5-d349a71ecd29\r\nx-ms-version: 2021-04-10\r\nx-ms-client-request-id: be815ff7-305f-4d31-6a34-5316ef5333cf\r\nServer: Windows-Azure-Blob/1.0\r\n\r\n--batchresponse_b54afdbc-442c-44ac-8511-f7d6ed97440d--", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202", + "content-type": "multipart/mixed; boundary=batchresponse_b54afdbc-442c-44ac-8511-f7d6ed97440d", + "date": "Thu, 29 Sep 2022 05:35:37 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "873ecb93-8623-4bf2-7df7-168241db548b", + "x-ms-request-id": "13fcc029-701e-0087-74c5-d349a7000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net?comp=batch" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "fef4a05e-f35d-4d63-637b-efb0709f0556", + "x-ms-version": "2021-04-10" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202", + "Server": "Windows-Azure-Blob/1.0", + "x-ms-client-request-id": "49162703-3f89-407f-4316-ba4dc5761ce2", + "x-ms-delete-type-permanent": "true", + "x-ms-request-id": "13fcc029-701e-0087-74c5-d349a71ecd28", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1/blockblob1?versionid=2022-09-29T05:35:34.8898621Z" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "e3b3613f-d5de-4fe0-5a41-f47f737e2011", + "x-ms-version": "2021-04-10" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202", + "Server": "Windows-Azure-Blob/1.0", + "x-ms-client-request-id": "be815ff7-305f-4d31-6a34-5316ef5333cf", + "x-ms-delete-type-permanent": "true", + "x-ms-request-id": "13fcc029-701e-0087-74c5-d349a71ecd29", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1/blockblob1?snapshot=2022-09-29T05:35:35.1876922Z" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "f491ef50-2dc3-464f-72fc-d78515fcaffa", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "The specified blob does not exist.", + "STATUS_CODE": "404", + "date": "Thu, 29 Sep 2022 05:35:38 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "vary": "Origin", + "x-ms-client-request-id": "f491ef50-2dc3-464f-72fc-d78515fcaffa", + "x-ms-error-code": "BlobNotFound", + "x-ms-request-id": "13fcc10d-701e-0087-2ec5-d349a7000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1/blockblob1?versionid=2022-09-29T05:35:34.8898621Z" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "3c9050ba-effc-4d77-6907-ca70c02a3271", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "The specified blob does not exist.", + "STATUS_CODE": "404", + "date": "Thu, 29 Sep 2022 05:35:38 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "vary": "Origin", + "x-ms-client-request-id": "3c9050ba-effc-4d77-6907-ca70c02a3271", + "x-ms-error-code": "BlobNotFound", + "x-ms-request-id": "13fcc1d8-701e-0087-48c5-d349a7000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1/blockblob1?snapshot=2022-09-29T05:35:35.1876922Z" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Pro 6.3 19044 19041.1.amd64fre.vb_release.191206-1406)", + "x-ms-client-request-id": "07a26bab-bdee-479e-6aa6-b7debef02091", + "x-ms-version": "2021-04-10" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202", + "content-length": "0", + "date": "Thu, 29 Sep 2022 05:35:38 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "07a26bab-bdee-479e-6aa6-b7debef02091", + "x-ms-request-id": "13fcc2ba-701e-0087-07c5-d349a7000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/snapshotversion1?restype=container" + } + ] +} diff --git a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_directory_client.hpp b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_directory_client.hpp index 05aaf8de74..d8d2f4defd 100644 --- a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_directory_client.hpp +++ b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_directory_client.hpp @@ -234,8 +234,13 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { explicit DataLakeDirectoryClient( Azure::Core::Url directoryUrl, Blobs::BlobClient blobClient, - std::shared_ptr pipeline) - : DataLakePathClient(std::move(directoryUrl), std::move(blobClient), pipeline) + std::shared_ptr pipeline, + Azure::Nullable customerProvidedKey = Azure::Nullable()) + : DataLakePathClient( + std::move(directoryUrl), + std::move(blobClient), + pipeline, + std::move(customerProvidedKey)) { } diff --git a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_file_client.hpp b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_file_client.hpp index 9a4e7c851c..40dc3856b8 100644 --- a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_file_client.hpp +++ b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_file_client.hpp @@ -265,12 +265,30 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { const ScheduleFileDeletionOptions& options = ScheduleFileDeletionOptions(), const Azure::Core::Context& context = Azure::Core::Context()) const; + /** + * @brief Returns the result of a query against the file. + * + * @param querySqlExpression The query expression in SQL. + * @param options Optional parameters to execute this function. + * @param context Context for cancelling long running operations. + * @return A QueryFileResult describing the query result. + */ + Azure::Response Query( + const std::string& querySqlExpression, + const QueryFileOptions& options = QueryFileOptions(), + const Azure::Core::Context& context = Azure::Core::Context()) const; + private: explicit DataLakeFileClient( Azure::Core::Url fileUrl, Blobs::BlobClient blobClient, - std::shared_ptr pipeline) - : DataLakePathClient(std::move(fileUrl), std::move(blobClient), pipeline) + std::shared_ptr pipeline, + Azure::Nullable customerProvidedKey = Azure::Nullable()) + : DataLakePathClient( + std::move(fileUrl), + std::move(blobClient), + pipeline, + std::move(customerProvidedKey)) { } diff --git a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_file_system_client.hpp b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_file_system_client.hpp index a1caa22248..4e390b13b5 100644 --- a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_file_system_client.hpp +++ b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_file_system_client.hpp @@ -239,17 +239,46 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { const RenameDirectoryOptions& options = RenameDirectoryOptions(), const Azure::Core::Context& context = Azure::Core::Context()) const; + /** + * @brief Gets the paths that have recently been soft deleted in this file system. + * @param options Optional parameters to list deleted paths. + * @param context Context for cancelling long running operations. + * @return Azure::Response The client targets the restored path. + * @remark This request is sent to Blob endpoint. + */ + ListDeletedPathsPagedResponse ListDeletedPaths( + const ListDeletedPathsOptions& options = ListDeletedPathsOptions(), + const Azure::Core::Context& context = Azure::Core::Context()) const; + + /** + * @brief Restores a soft deleted path. + * @param deletedPath The path of the deleted path. + * @param deletionId The deletion ID associated with the soft deleted path. You can get soft + * deleted paths and their associated deletion IDs with ListDeletedPaths. + * @param context Context for cancelling long running operations. + * @return Azure::Response The client targets the restored path. + * @remark This request is sent to Blob endpoint. + */ + Azure::Response UndeletePath( + const std::string& deletedPath, + const std::string& deletionId, + const UndeletePathOptions& options = UndeletePathOptions(), + const Azure::Core::Context& context = Azure::Core::Context()) const; + private: Azure::Core::Url m_fileSystemUrl; Blobs::BlobContainerClient m_blobContainerClient; std::shared_ptr m_pipeline; + Azure::Nullable m_customerProvidedKey; explicit DataLakeFileSystemClient( Azure::Core::Url fileSystemUrl, Blobs::BlobContainerClient blobContainerClient, - std::shared_ptr pipeline) + std::shared_ptr pipeline, + Azure::Nullable customerProvidedKey = Azure::Nullable()) : m_fileSystemUrl(std::move(fileSystemUrl)), - m_blobContainerClient(std::move(blobContainerClient)), m_pipeline(std::move(pipeline)) + m_blobContainerClient(std::move(blobContainerClient)), m_pipeline(std::move(pipeline)), + m_customerProvidedKey(std::move(customerProvidedKey)) { } friend class DataLakeLeaseClient; diff --git a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_options.hpp b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_options.hpp index b0796cefde..591269bb05 100644 --- a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_options.hpp +++ b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_options.hpp @@ -21,10 +21,70 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { using PathHttpHeaders = Blobs::Models::BlobHttpHeaders; using ListFileSystemsIncludeFlags = Blobs::Models::ListBlobContainersIncludeFlags; using SignedIdentifier = Blobs::Models::SignedIdentifier; + using FileQueryArrowField = Blobs::Models::BlobQueryArrowField; + using FileQueryArrowFieldType = Blobs::Models::BlobQueryArrowFieldType; + using EncryptionAlgorithmType = Blobs::Models::EncryptionAlgorithmType; + + /** + * @brief An access control object. + */ + struct Acl final + { + /** + * The scope of the ACL. + */ + std::string Scope; + + /** + * The type of the ACL. + */ + std::string Type; + + /** + * The ID of the ACL. + */ + std::string Id; + + /** + * The permissions of the ACL. + */ + std::string Permissions; + + /** + * @brief Creates an Acl based on acl input string. + * @param aclString the string to be parsed to Acl. + * @return Acl + */ + static Acl FromString(const std::string& aclString); + + /** + * @brief Creates a string from an Acl. + * @param acl the acl object to be serialized to a string. + * @return std::string + */ + static std::string ToString(const Acl& acl); + + /** + * @brief Creates a vector of Acl from a string that indicates multiple acls. + * @param aclsString the string that contains multiple acls. + * @return std::vector + */ + static std::vector DeserializeAcls(const std::string& aclsString); + + /** + * @brief Creates a string that contains several Acls. + * @param aclsArray the acls to be serialized into a string. + * @return std::string + */ + static std::string SerializeAcls(const std::vector& aclsArray); + }; } // namespace Models using DownloadFileToOptions = Blobs::DownloadBlobToOptions; using GetUserDelegationKeyOptions = Blobs::GetUserDelegationKeyOptions; + using GetServicePropertiesOptions = Blobs::GetServicePropertiesOptions; + using SetServicePropertiesOptions = Blobs::SetServicePropertiesOptions; + using EncryptionKey = Blobs::EncryptionKey; /** * @brief Client options used to initialize all DataLake clients. @@ -44,6 +104,11 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { * API version used by this client. */ std::string ApiVersion; + + /** + * @brief Holds the customer provided key used when making requests. + */ + Azure::Nullable CustomerProvidedKey; }; /** @@ -182,6 +247,39 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Azure::Nullable PageSizeHint; }; + /** + * @brief Optional parameters for #Azure::Storage::Files::DataLake::FileSystemClient::ListPaths. + */ + struct ListDeletedPathsOptions final + { + /** + * Gets the paths that have recently been soft deleted in this file system. + */ + Azure::Nullable Prefix; + + /** + * The number of paths returned with each invocation is limited. If the number of paths to be + * returned exceeds this limit, a continuation token is returned in the response header + * x-ms-continuation. When a continuation token is returned in the response, it must be + * specified in a subsequent invocation of the list operation to continue listing the paths. + */ + Azure::Nullable ContinuationToken; + + /** + * An optional value that specifies the maximum number of items to return. If omitted or greater + * than 5,000, the response will include up to 5,000 items. + */ + Azure::Nullable PageSizeHint; + }; + + /** + * @brief Optional parameters for + * #Azure::Storage::Files::DataLake::FileSystemClient::UndeletePath. + */ + struct UndeletePathOptions final + { + }; + /** * @brief Optional parameters for * #Azure::Storage::Files::DataLake::FileSystemClient::GetAccessPolicy. @@ -257,6 +355,11 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { * Specify the lease access conditions. */ LeaseAccessConditions AccessConditions; + + /** + * If true, the file will be flushed after the append. + */ + Azure::Nullable Flush; }; /** @@ -371,6 +474,33 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { PathAccessConditions AccessConditions; }; + using ScheduleFileExpiryOriginType = Blobs::Models::ScheduleBlobExpiryOriginType; + + /** + * @brief Options for scheduling the deletion of a path. + */ + struct ScheduleFileDeletionOptions final + { + /** + * The expiry time from the specified origin. Only work if ExpiryOrigin is + * ScheduleFileExpiryOriginType::RelativeToCreation or + * ScheduleFileExpiryOriginType::RelativeToNow. + * Does not apply to directories. + * TimeToExpire and ExpiresOn cannot both be set. + */ + Azure::Nullable TimeToExpire; + + /** + * The expiry time in RFC1123 format. Only works if ExpiryOrigin is + * ScheduleFileExpiryOriginType::Absolute. + * Does not apply to directories. + * ExpiresOn and TimeToExpire cannot both be set. + */ + Azure::Nullable ExpiresOn; + }; + + using SchedulePathDeletionOptions = ScheduleFileDeletionOptions; + /** * @brief Optional parameters for #Azure::Storage::Files::DataLake::PathClient::Create. * @remark Some optional parameter is mandatory in certain combination. @@ -412,6 +542,39 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { */ Azure::Nullable Permissions; + /** + * The owner of the file or directory. + */ + Azure::Nullable Owner; + + /** + * The owning group of the file or directory. + */ + Azure::Nullable Group; + + /** + * Sets POSIX access control rights on files and directories. Each access control entry (ACE) + * consists of a scope, a type, a user or group identifier, and permissions. + */ + Azure::Nullable> Acls; + + /** + * Proposed LeaseId. + */ + Azure::Nullable LeaseId; + + /** + * Specifies the duration of the lease, in seconds, or InfiniteLeaseDuration for a lease that + * never expires. A non-infinite lease can be between 15 and 60 seconds. A lease duration cannot + * be changed using renew or change. Does not apply to directories. + */ + Azure::Nullable LeaseDuration; + + /** + * Optional parameters to schedule the file for deletion. + */ + SchedulePathDeletionOptions ScheduleDeletionOptions; + /** * Specify the access condition for the path. */ @@ -611,31 +774,41 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { } TransferOptions; }; - using ScheduleFileExpiryOriginType = Blobs::Models::ScheduleBlobExpiryOriginType; + using AcquireLeaseOptions = Blobs::AcquireLeaseOptions; + using BreakLeaseOptions = Blobs::BreakLeaseOptions; + using RenewLeaseOptions = Blobs::RenewLeaseOptions; + using ReleaseLeaseOptions = Blobs::ReleaseLeaseOptions; + using ChangeLeaseOptions = Blobs::ChangeLeaseOptions; + + using FileQueryInputTextOptions = Blobs::BlobQueryInputTextOptions; + using FileQueryOutputTextOptions = Blobs::BlobQueryOutputTextOptions; + using FileQueryError = Blobs::BlobQueryError; /** - * @brief Optional parameters for #Azure::Storage::Files::DataLake::FileClient::UploadFrom. + * @brief Optional parameters for #Azure::Storage::Files::DataLake::DataLakeFileClient::Query. */ - struct ScheduleFileDeletionOptions final + struct QueryFileOptions final { /** - * The expiry time from the specified origin. Only work if ExpiryOrigin is - * ScheduleFileExpiryOriginType::RelativeToCreation or - * ScheduleFileExpiryOriginType::RelativeToNow. + * @brief Input text configuration. */ - Azure::Nullable TimeToExpire; - + FileQueryInputTextOptions InputTextConfiguration; /** - * The expiry time in RFC1123 format. Only work if ExpiryOrigin is - * ScheduleFileExpiryOriginType::Absolute. + * @brief Output text configuration. */ - Azure::Nullable ExpiresOn; + FileQueryOutputTextOptions OutputTextConfiguration; + /** + * @brief Optional conditions that must be met to perform this operation. + */ + PathAccessConditions AccessConditions; + /** + * @brief Callback for progress handling. + */ + std::function ProgressHandler; + /** + * @brief Callback for error handling. If you don't specify one, the default will be used, which + * will ignore all non-fatal errors and throw for fatal errors. + */ + std::function ErrorHandler; }; - - using AcquireLeaseOptions = Blobs::AcquireLeaseOptions; - using BreakLeaseOptions = Blobs::BreakLeaseOptions; - using RenewLeaseOptions = Blobs::RenewLeaseOptions; - using ReleaseLeaseOptions = Blobs::ReleaseLeaseOptions; - using ChangeLeaseOptions = Blobs::ChangeLeaseOptions; - }}}} // namespace Azure::Storage::Files::DataLake diff --git a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_path_client.hpp b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_path_client.hpp index f6183a3e70..497b36ac0a 100644 --- a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_path_client.hpp +++ b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_path_client.hpp @@ -295,13 +295,15 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Azure::Core::Url m_pathUrl; Blobs::BlobClient m_blobClient; std::shared_ptr m_pipeline; + Azure::Nullable m_customerProvidedKey; explicit DataLakePathClient( Azure::Core::Url pathUrl, Blobs::BlobClient blobClient, - std::shared_ptr pipeline) + std::shared_ptr pipeline, + Azure::Nullable customerProvidedKey = Azure::Nullable()) : m_pathUrl(std::move(pathUrl)), m_blobClient(std::move(blobClient)), - m_pipeline(std::move(pipeline)) + m_pipeline(std::move(pipeline)), m_customerProvidedKey(std::move(customerProvidedKey)) { } diff --git a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_responses.hpp b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_responses.hpp index e8b9b90ce8..1b0e3d804a 100644 --- a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_responses.hpp +++ b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_responses.hpp @@ -14,6 +14,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { class DataLakeServiceClient; + class DataLakeFileSystemClient; class DataLakePathClient; namespace Models { @@ -26,6 +27,13 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { // ServiceClient models: using UserDelegationKey = Blobs::Models::UserDelegationKey; + using RetentionPolicy = Blobs::Models::RetentionPolicy; + using AnalyticsLogging = Blobs::Models::AnalyticsLogging; + using Metrics = Blobs::Models::Metrics; + using CorsRule = Blobs::Models::CorsRule; + using StaticWebsite = Blobs::Models::StaticWebsite; + using DataLakeServiceProperties = Blobs::Models::BlobServiceProperties; + using SetServicePropertiesResult = Blobs::Models::SetServicePropertiesResult; /** * @brief The detailed information of a file system. @@ -194,57 +202,64 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { using ArchiveStatus = Blobs::Models::ArchiveStatus; /** - * @brief An access control object. + * @brief The path item returned when listing the paths. */ - struct Acl final + struct PathItem final { /** - * The scope of the ACL. + * The name of the path. */ - std::string Scope; + std::string Name; + + /** + * Indicates whether this path is a directory. + */ + bool IsDirectory = false; /** - * The type of the ACL. + * The data and time the path was last modified. */ - std::string Type; + DateTime LastModified; /** - * The ID of the ACL. + * The size of the file. */ - std::string Id; + int64_t FileSize = int64_t(); /** - * The permissions of the ACL. + * The owner of the path. + */ + std::string Owner; + + /** + * The group of the path. + */ + std::string Group; + + /** + * The permission of the path. */ std::string Permissions; /** - * @brief Creates an Acl based on acl input string. - * @param aclString the string to be parsed to Acl. - * @return Acl + * The name of the encryption scope under which the blob is encrypted. */ - static Acl FromString(const std::string& aclString); + Nullable EncryptionScope; /** - * @brief Creates a string from an Acl. - * @param acl the acl object to be serialized to a string. - * @return std::string + * The creation time of the path. */ - static std::string ToString(const Acl& acl); + Nullable CreatedOn; /** - * @brief Creates a vector of Acl from a string that indicates multiple acls. - * @param aclsString the string that contains multiple acls. - * @return std::vector + * The expiry time of the path. */ - static std::vector DeserializeAcls(const std::string& aclsString); + Nullable ExpiresOn; /** - * @brief Creates a string that contains several Acls. - * @param aclsArray the acls to be serialized into a string. - * @return std::string + * An HTTP entity tag associated with the path. */ - static std::string SerializeAcls(const std::vector& aclsArray); + std::string ETag; }; /** @@ -443,12 +458,76 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { using SetPathPermissionsResult = SetPathAccessControlListResult; + /** + * @brief A path that has been soft deleted. + */ + struct PathDeletedItem final + { + /** + * The name of the path. + */ + std::string Name; + + /** + * The deletion ID associated with the deleted path. + */ + std::string DeletionId; + + /** + * When the path was deleted. + */ + DateTime DeletedOn; + + /** + * The number of days left before the soft deleted path will be permanently deleted. + */ + int64_t RemainingRetentionDays = int64_t(); + }; + // FileClient models: using UploadFileFromResult = Blobs::Models::UploadBlockBlobResult; using ScheduleFileDeletionResult = Blobs::Models::SetBlobExpiryResult; using CopyStatus = Blobs::Models::CopyStatus; + /** + * @brief Response type for #Azure::Storage::Files::DataLake::FileClient::Query. + */ + struct QueryFileResult final + { + std::unique_ptr BodyStream; + /** + * Returns the date and time the container was last modified. Any operation that modifies the + * file, including an update of the file's metadata or properties, changes the last-modified + * time of the file. + */ + DateTime LastModified; + /** + * The ETag contains a value that you can use to perform operations conditionally. If the + * request version is 2011-08-18 or newer, the ETag value will be in quotes. + */ + Azure::ETag ETag; + /** + * When a file is leased, specifies whether the lease is of infinite or fixed duration. + */ + Nullable LeaseDuration; + /** + * Lease state of the file. + */ + Models::LeaseState LeaseState; + /** + * The current lease status of the file. + */ + Models::LeaseStatus LeaseStatus; + /** + * The value of this header is set to true if the file data and application metadata are + * completely encrypted using the specified algorithm. Otherwise, the value is set to false + * (when the file is unencrypted, or if only parts of the file/application metadata are + * encrypted). + */ + bool IsServerEncrypted = bool(); + }; + /** * @brief The detailed information returned when downloading a file. */ @@ -674,6 +753,28 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { friend class Azure::Core::PagedResponse; }; + /** + * @brief Response type for + * #Azure::Storage::Files::DataLake::DataLakeFileSystemClient::ListDeletedPaths. + */ + class ListDeletedPathsPagedResponse final + : public Azure::Core::PagedResponse { + public: + /** + * Deleted path items. + */ + std::vector DeletedPaths; + + private: + void OnNextPage(const Azure::Core::Context& context); + + std::shared_ptr m_fileSystemClient; + ListDeletedPathsOptions m_operationOptions; + + friend class DataLakeFileSystemClient; + friend class Azure::Core::PagedResponse; + }; + /** * @brief Response type for * #Azure::Storage::Files::DataLake::DataLakePathClient::SetAccessControlListRecursive. diff --git a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_sas_builder.hpp b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_sas_builder.hpp index 85c85100ac..dba43e533e 100644 --- a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_sas_builder.hpp +++ b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_sas_builder.hpp @@ -293,6 +293,11 @@ namespace Azure { namespace Storage { namespace Sas { */ std::string CorrelationId; + /** + * @brief Optional encryption scope to use when sending requests authorized with this SAS url. + */ + std::string EncryptionScope; + /** * @brief Sets the permissions for the filesystem SAS. * diff --git a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_service_client.hpp b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_service_client.hpp index 633ddf57cc..1cb927ff3f 100644 --- a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_service_client.hpp +++ b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_service_client.hpp @@ -109,9 +109,44 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { return m_blobServiceClient.GetUserDelegationKey(expiresOn, options, context); } + /** + * @brief Sets properties for a storage account's Blob service endpoint, including + * properties for Storage Analytics, CORS (Cross-Origin Resource Sharing) rules and soft delete + * settings. You can also use this operation to set the default request version for all incoming + * requests to the DataLake service that do not have a version specified. + * + * @param properties The DataLake service properties. + * @param options Optional parameters to execute this function. + * @param context Context for cancelling long running operations. + * @return A SetServicePropertiesResult on successfully setting the properties. + */ + Azure::Response SetProperties( + Models::DataLakeServiceProperties properties, + const SetServicePropertiesOptions& options = SetServicePropertiesOptions(), + const Azure::Core::Context& context = Azure::Core::Context()) const + { + return m_blobServiceClient.SetProperties(properties, options, context); + } + + /** + * @brief Gets the properties of a storage account's datalake service, including properties + * for Storage Analytics and CORS (Cross-Origin Resource Sharing) rules. + * + * @param options Optional parameters to execute this function. + * @param context Context for cancelling long running operations. + * @return A DataLakeServiceProperties describing the service properties. + */ + Azure::Response GetProperties( + const GetServicePropertiesOptions& options = GetServicePropertiesOptions(), + const Azure::Core::Context& context = Azure::Core::Context()) const + { + return m_blobServiceClient.GetProperties(options, context); + } + private: Azure::Core::Url m_serviceUrl; Blobs::BlobServiceClient m_blobServiceClient; std::shared_ptr m_pipeline; + Azure::Nullable m_customerProvidedKey; }; }}}} // namespace Azure::Storage::Files::DataLake diff --git a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp index 9118b085cd..a2d73be699 100644 --- a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp +++ b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp @@ -26,7 +26,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { /** * The version used for the operations to Azure storage services. */ - constexpr static const char* ApiVersion = "2020-02-10"; + constexpr static const char* ApiVersion = "2021-06-08"; } // namespace _detail namespace Models { namespace _detail { @@ -83,18 +83,24 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { private: std::string m_value; }; - struct PathItem final - { - std::string Name; - bool IsDirectory = false; - DateTime LastModified; - int64_t FileSize = int64_t(); - std::string Owner; - std::string Group; - std::string Permissions; - std::string ETag; - }; namespace _detail { + struct PathItem final + { + std::string Name; + bool IsDirectory = false; + DateTime LastModified; + int64_t FileSize = int64_t(); + std::string Owner; + std::string Group; + std::string Permissions; + /** + * The name of the encryption scope under which the blob is encrypted. + */ + Nullable EncryptionScope; + Nullable CreatedOn; + Nullable ExpiresOn; + std::string ETag; + }; /** * @brief Response type for #Azure::Storage::Files::DataLake::FileSystemClient::ListPaths. */ @@ -152,6 +158,16 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { * The size of the resource in bytes. */ Nullable FileSize; + /** + * The value of this header is set to true if the contents of the request are successfully + * encrypted using the specified algorithm, and false otherwise. + */ + Nullable IsServerEncrypted; + /** + * The SHA-256 hash of the encryption key used to encrypt the blob. This header is only + * returned when the blob was encrypted with a customer-provided key. + */ + Nullable> EncryptionKeySha256; }; /** * @brief Response type for #Azure::Storage::Files::DataLake::PathClient::Delete. @@ -220,6 +236,17 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { */ Nullable ContinuationToken; }; + /** + * @brief Response type for #Azure::Storage::Files::DataLake::PathClient::Undelete. + */ + struct UndeletePathResult final + { + /** + * The type of the resource. The value may be "file" or "directory". If not set, the value + * is "file". + */ + Nullable ResourceType; + }; /** * @brief Response type for * #Azure::Storage::Files::DataLake::PathClient::GetAccessControlList. @@ -267,6 +294,16 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { * The size of the resource in bytes. */ int64_t FileSize = int64_t(); + /** + * The value of this header is set to true if the contents of the request are successfully + * encrypted using the specified algorithm, and false otherwise. + */ + Nullable IsServerEncrypted; + /** + * The SHA-256 hash of the encryption key used to encrypt the blob. This header is only + * returned when the blob was encrypted with a customer-provided key. + */ + Nullable> EncryptionKeySha256; }; /** * @brief Response type for #Azure::Storage::Files::DataLake::FileClient::Append. @@ -282,7 +319,12 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { * The value of this header is set to true if the contents of the request are successfully * encrypted using the specified algorithm, and false otherwise. */ - bool IsServerEncrypted = bool(); + Nullable IsServerEncrypted; + /** + * The SHA-256 hash of the encryption key used to encrypt the blob. This header is only + * returned when the blob was encrypted with a customer-provided key. + */ + Nullable> EncryptionKeySha256; }; } // namespace Models namespace _detail { @@ -332,6 +374,16 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { ETag SourceIfNoneMatch; Nullable SourceIfModifiedSince; Nullable SourceIfUnmodifiedSince; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable Owner; + Nullable Group; + Nullable Acl; + Nullable ProposedLeaseId; + Nullable LeaseDuration; + Nullable ExpiryOptions; + Nullable ExpiresOn; }; static Response Create( Core::Http::_internal::HttpPipeline& pipeline, @@ -386,6 +438,15 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { const Core::Url& url, const SetPathAccessControlListRecursiveOptions& options, const Core::Context& context); + struct UndeletePathOptions final + { + Nullable UndeleteSource; + }; + static Response Undelete( + Core::Http::_internal::HttpPipeline& pipeline, + const Core::Url& url, + const UndeletePathOptions& options, + const Core::Context& context); struct GetPathAccessControlListOptions final { Nullable Upn; @@ -419,6 +480,9 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { ETag IfNoneMatch; Nullable IfModifiedSince; Nullable IfUnmodifiedSince; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; }; static Response Flush( Core::Http::_internal::HttpPipeline& pipeline, @@ -431,6 +495,10 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Nullable> TransactionalContentHash; Nullable> TransactionalContentCrc64; Nullable LeaseId; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable EncryptionAlgorithm; + Nullable Flush; }; static Response Append( Core::Http::_internal::HttpPipeline& pipeline, diff --git a/sdk/storage/azure-storage-files-datalake/src/datalake_directory_client.cpp b/sdk/storage/azure-storage-files-datalake/src/datalake_directory_client.cpp index 1ac31d8f52..ec704e1513 100644 --- a/sdk/storage/azure-storage-files-datalake/src/datalake_directory_client.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/datalake_directory_client.cpp @@ -66,7 +66,8 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { builder.AppendPath(_internal::UrlEncodePath(fileName)); auto blobClient = m_blobClient; blobClient.m_blobUrl.AppendPath(_internal::UrlEncodePath(fileName)); - return DataLakeFileClient(std::move(builder), std::move(blobClient), m_pipeline); + return DataLakeFileClient( + std::move(builder), std::move(blobClient), m_pipeline, m_customerProvidedKey); } DataLakeDirectoryClient DataLakeDirectoryClient::GetSubdirectoryClient( @@ -76,7 +77,8 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { builder.AppendPath(_internal::UrlEncodePath(subdirectoryName)); auto blobClient = m_blobClient; blobClient.m_blobUrl.AppendPath(_internal::UrlEncodePath(subdirectoryName)); - return DataLakeDirectoryClient(std::move(builder), std::move(blobClient), m_pipeline); + return DataLakeDirectoryClient( + std::move(builder), std::move(blobClient), m_pipeline, m_customerProvidedKey); } Azure::Response DataLakeDirectoryClient::RenameFile( @@ -119,10 +121,13 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { auto response = _detail::PathClient::Create( *m_pipeline, destinationDfsUrl, protocolLayerOptions, context); - auto renamedBlobClient - = Blobs::BlobClient(_detail::GetBlobUrlFromUrl(destinationDfsUrl), m_pipeline); + auto renamedBlobClient = Blobs::BlobClient( + _detail::GetBlobUrlFromUrl(destinationDfsUrl), m_pipeline, m_customerProvidedKey); auto renamedFileClient = DataLakeFileClient( - std::move(destinationDfsUrl), std::move(renamedBlobClient), m_pipeline); + std::move(destinationDfsUrl), + std::move(renamedBlobClient), + m_pipeline, + m_customerProvidedKey); return Azure::Response( std::move(renamedFileClient), std::move(response.RawResponse)); } @@ -167,10 +172,13 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { auto response = _detail::PathClient::Create( *m_pipeline, destinationDfsUrl, protocolLayerOptions, context); - auto renamedBlobClient - = Blobs::BlobClient(_detail::GetBlobUrlFromUrl(destinationDfsUrl), m_pipeline); + auto renamedBlobClient = Blobs::BlobClient( + _detail::GetBlobUrlFromUrl(destinationDfsUrl), m_pipeline, m_customerProvidedKey); auto renamedDirectoryClient = DataLakeDirectoryClient( - std::move(destinationDfsUrl), std::move(renamedBlobClient), m_pipeline); + std::move(destinationDfsUrl), + std::move(renamedBlobClient), + m_pipeline, + m_customerProvidedKey); return Azure::Response( std::move(renamedDirectoryClient), std::move(response.RawResponse)); } @@ -239,8 +247,30 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { _internal::WithReplicaStatus(context)); ListPathsPagedResponse pagedResponse; - - pagedResponse.Paths = std::move(response.Value.Paths); + for (auto& path : response.Value.Paths) + { + Models::PathItem item; + item.Name = std::move(path.Name); + item.IsDirectory = path.IsDirectory; + item.LastModified = std::move(path.LastModified); + item.FileSize = path.FileSize; + item.Owner = std::move(path.Owner); + item.Group = std::move(path.Group); + item.Permissions = std::move(path.Permissions); + item.EncryptionScope = std::move(path.EncryptionScope); + item.ETag = std::move(path.ETag); + if (path.CreatedOn.HasValue()) + { + item.CreatedOn = _detail::Win32FileTimeConverter::Win32FileTimeToDateTime( + std::stoll(path.CreatedOn.Value())); + } + if (path.ExpiresOn.HasValue() && path.ExpiresOn.Value() != "0") + { + item.ExpiresOn = _detail::Win32FileTimeConverter::Win32FileTimeToDateTime( + std::stoll(path.ExpiresOn.Value())); + } + pagedResponse.Paths.push_back(std::move(item)); + } pagedResponse.m_onNextPageFunc = func; pagedResponse.CurrentPageToken = continuationToken; pagedResponse.NextPageToken = response.Value.ContinuationToken; diff --git a/sdk/storage/azure-storage-files-datalake/src/datalake_file_client.cpp b/sdk/storage/azure-storage-files-datalake/src/datalake_file_client.cpp index ded67cb674..b40d4b6c05 100644 --- a/sdk/storage/azure-storage-files-datalake/src/datalake_file_client.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/datalake_file_client.cpp @@ -81,6 +81,13 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { } } protocolLayerOptions.LeaseId = options.AccessConditions.LeaseId; + protocolLayerOptions.Flush = options.Flush; + if (m_customerProvidedKey.HasValue()) + { + protocolLayerOptions.EncryptionKey = m_customerProvidedKey.Value().Key; + protocolLayerOptions.EncryptionKeySha256 = m_customerProvidedKey.Value().KeyHash; + protocolLayerOptions.EncryptionAlgorithm = m_customerProvidedKey.Value().Algorithm.ToString(); + } return _detail::FileClient::Append( *m_pipeline, m_pathUrl, content, protocolLayerOptions, context); } @@ -111,6 +118,12 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { protocolLayerOptions.IfNoneMatch = options.AccessConditions.IfNoneMatch; protocolLayerOptions.IfModifiedSince = options.AccessConditions.IfModifiedSince; protocolLayerOptions.IfUnmodifiedSince = options.AccessConditions.IfUnmodifiedSince; + if (m_customerProvidedKey.HasValue()) + { + protocolLayerOptions.EncryptionKey = m_customerProvidedKey.Value().Key; + protocolLayerOptions.EncryptionKeySha256 = m_customerProvidedKey.Value().KeyHash; + protocolLayerOptions.EncryptionAlgorithm = m_customerProvidedKey.Value().Algorithm.ToString(); + } return _detail::FileClient::Flush(*m_pipeline, m_pathUrl, protocolLayerOptions, context); } @@ -327,4 +340,33 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { *m_pipeline, m_blobClient.m_blobUrl, protocolLayerOptions, context); } + Azure::Response DataLakeFileClient::Query( + const std::string& querySqlExpression, + const QueryFileOptions& options, + const Azure::Core::Context& context) const + { + Blobs::QueryBlobOptions blobOptions; + blobOptions.InputTextConfiguration = options.InputTextConfiguration; + blobOptions.OutputTextConfiguration = options.OutputTextConfiguration; + blobOptions.ErrorHandler = options.ErrorHandler; + blobOptions.ProgressHandler = options.ProgressHandler; + blobOptions.AccessConditions.IfMatch = options.AccessConditions.IfMatch; + blobOptions.AccessConditions.IfNoneMatch = options.AccessConditions.IfNoneMatch; + blobOptions.AccessConditions.IfModifiedSince = options.AccessConditions.IfModifiedSince; + blobOptions.AccessConditions.IfUnmodifiedSince = options.AccessConditions.IfUnmodifiedSince; + blobOptions.AccessConditions.LeaseId = options.AccessConditions.LeaseId; + auto response + = m_blobClient.AsBlockBlobClient().Query(querySqlExpression, blobOptions, context); + Models::QueryFileResult ret; + ret.BodyStream = std::move(response.Value.BodyStream); + ret.ETag = std::move(response.Value.ETag); + ret.LastModified = std::move(response.Value.LastModified); + ret.LeaseDuration = std::move(response.Value.LeaseDuration); + ret.LeaseState = std::move(response.Value.LeaseState); + ret.LeaseStatus = std::move(response.Value.LeaseStatus); + ret.IsServerEncrypted = response.Value.IsServerEncrypted; + return Azure::Response( + std::move(ret), std::move(response.RawResponse)); + } + }}}} // namespace Azure::Storage::Files::DataLake diff --git a/sdk/storage/azure-storage-files-datalake/src/datalake_file_system_client.cpp b/sdk/storage/azure-storage-files-datalake/src/datalake_file_system_client.cpp index c478c0cf50..5f438953a6 100644 --- a/sdk/storage/azure-storage-files-datalake/src/datalake_file_system_client.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/datalake_file_system_client.cpp @@ -50,7 +50,8 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { : m_fileSystemUrl(fileSystemUrl), m_blobContainerClient( _detail::GetBlobUrlFromUrl(fileSystemUrl), credential, - _detail::GetBlobClientOptions(options)) + _detail::GetBlobClientOptions(options)), + m_customerProvidedKey(options.CustomerProvidedKey) { DataLakeClientOptions newOptions = options; newOptions.PerRetryPolicies.emplace_back( @@ -78,7 +79,8 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { : m_fileSystemUrl(fileSystemUrl), m_blobContainerClient( _detail::GetBlobUrlFromUrl(fileSystemUrl), credential, - _detail::GetBlobClientOptions(options)) + _detail::GetBlobClientOptions(options)), + m_customerProvidedKey(options.CustomerProvidedKey) { std::vector> perRetryPolicies; std::vector> perOperationPolicies; @@ -107,7 +109,8 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { const DataLakeClientOptions& options) : m_fileSystemUrl(fileSystemUrl), m_blobContainerClient( _detail::GetBlobUrlFromUrl(fileSystemUrl), - _detail::GetBlobClientOptions(options)) + _detail::GetBlobClientOptions(options)), + m_customerProvidedKey(options.CustomerProvidedKey) { std::vector> perRetryPolicies; std::vector> perOperationPolicies; @@ -129,7 +132,8 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { auto builder = m_fileSystemUrl; builder.AppendPath(_internal::UrlEncodePath(fileName)); auto blobClient = m_blobContainerClient.GetBlobClient(fileName); - return DataLakeFileClient(std::move(builder), std::move(blobClient), m_pipeline); + return DataLakeFileClient( + std::move(builder), std::move(blobClient), m_pipeline, m_customerProvidedKey); } DataLakeDirectoryClient DataLakeFileSystemClient::GetDirectoryClient( @@ -138,7 +142,10 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { auto builder = m_fileSystemUrl; builder.AppendPath(_internal::UrlEncodePath(directoryName)); return DataLakeDirectoryClient( - builder, m_blobContainerClient.GetBlobClient(directoryName), m_pipeline); + builder, + m_blobContainerClient.GetBlobClient(directoryName), + m_pipeline, + m_customerProvidedKey); } Azure::Response DataLakeFileSystemClient::Create( @@ -270,7 +277,30 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { _internal::WithReplicaStatus(context)); ListPathsPagedResponse pagedResponse; - pagedResponse.Paths = std::move(response.Value.Paths); + for (auto& path : response.Value.Paths) + { + Models::PathItem item; + item.Name = std::move(path.Name); + item.IsDirectory = path.IsDirectory; + item.LastModified = std::move(path.LastModified); + item.FileSize = path.FileSize; + item.Owner = std::move(path.Owner); + item.Group = std::move(path.Group); + item.Permissions = std::move(path.Permissions); + item.EncryptionScope = std::move(path.EncryptionScope); + item.ETag = std::move(path.ETag); + if (path.CreatedOn.HasValue()) + { + item.CreatedOn = _detail::Win32FileTimeConverter::Win32FileTimeToDateTime( + std::stoll(path.CreatedOn.Value())); + } + if (path.ExpiresOn.HasValue() && path.ExpiresOn.Value() != "0") + { + item.ExpiresOn = _detail::Win32FileTimeConverter::Win32FileTimeToDateTime( + std::stoll(path.ExpiresOn.Value())); + } + pagedResponse.Paths.push_back(std::move(item)); + } pagedResponse.m_onNextPageFunc = func; pagedResponse.CurrentPageToken = continuationToken; pagedResponse.NextPageToken = response.Value.ContinuationToken; @@ -356,10 +386,13 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { auto result = _detail::PathClient::Create( *m_pipeline, destinationDfsUrl, protocolLayerOptions, context); - auto renamedBlobClient - = Blobs::BlobClient(_detail::GetBlobUrlFromUrl(destinationDfsUrl), m_pipeline); + auto renamedBlobClient = Blobs::BlobClient( + _detail::GetBlobUrlFromUrl(destinationDfsUrl), m_pipeline, m_customerProvidedKey); auto renamedFileClient = DataLakeFileClient( - std::move(destinationDfsUrl), std::move(renamedBlobClient), m_pipeline); + std::move(destinationDfsUrl), + std::move(renamedBlobClient), + m_pipeline, + m_customerProvidedKey); return Azure::Response( std::move(renamedFileClient), std::move(result.RawResponse)); } @@ -404,12 +437,86 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { auto result = _detail::PathClient::Create( *m_pipeline, destinationDfsUrl, protocolLayerOptions, context); - auto renamedBlobClient - = Blobs::BlobClient(_detail::GetBlobUrlFromUrl(destinationDfsUrl), m_pipeline); + auto renamedBlobClient = Blobs::BlobClient( + _detail::GetBlobUrlFromUrl(destinationDfsUrl), m_pipeline, m_customerProvidedKey); auto renamedDirectoryClient = DataLakeDirectoryClient( - std::move(destinationDfsUrl), std::move(renamedBlobClient), m_pipeline); + std::move(destinationDfsUrl), + std::move(renamedBlobClient), + m_pipeline, + m_customerProvidedKey); return Azure::Response( std::move(renamedDirectoryClient), std::move(result.RawResponse)); } + ListDeletedPathsPagedResponse DataLakeFileSystemClient::ListDeletedPaths( + const ListDeletedPathsOptions& options, + const Azure::Core::Context& context) const + { + Blobs::_detail::BlobContainerClient::ListBlobContainerBlobsByHierarchyOptions + protocolLayerOptions; + protocolLayerOptions.Prefix = options.Prefix; + protocolLayerOptions.MaxResults = options.PageSizeHint; + protocolLayerOptions.Marker = options.ContinuationToken; + protocolLayerOptions.ShowOnly = "deleted"; + auto result = Blobs::_detail::BlobContainerClient::ListBlobsByHierarchy( + *m_pipeline, m_blobContainerClient.m_blobContainerUrl, protocolLayerOptions, context); + + ListDeletedPathsPagedResponse pagedResponse; + for (auto& item : result.Value.Items) + { + Models::PathDeletedItem pathDeletedItem; + if (item.Name.Encoded) + { + pathDeletedItem.Name = Core::Url::Decode(item.Name.Content); + } + else + { + pathDeletedItem.Name = std::move(item.Name.Content); + } + pathDeletedItem.DeletedOn = std::move(item.Details.DeletedOn.Value()); + pathDeletedItem.DeletionId = std::move(item.DeletionId.Value()); + pathDeletedItem.RemainingRetentionDays = item.Details.RemainingRetentionDays.Value(); + + pagedResponse.DeletedPaths.push_back(std::move(pathDeletedItem)); + } + pagedResponse.m_operationOptions = options; + pagedResponse.m_fileSystemClient = std::make_shared(*this); + pagedResponse.CurrentPageToken = options.ContinuationToken.ValueOr(std::string()); + pagedResponse.NextPageToken = std::move(result.Value.ContinuationToken); + pagedResponse.RawResponse = std::move(result.RawResponse); + + return pagedResponse; + } + + Azure::Response DataLakeFileSystemClient::UndeletePath( + const std::string& deletedPath, + const std::string& deletionId, + const UndeletePathOptions& options, + const Azure::Core::Context& context) const + { + (void)options; + /* cspell:disable-next-line */ + std::string undeleteSource = "?deletionid=" + deletionId; + + auto blobUrl = m_blobContainerClient.m_blobContainerUrl; + blobUrl.AppendPath(_internal::UrlEncodePath(deletedPath)); + + _detail::PathClient::UndeletePathOptions protocolLayerOptions; + protocolLayerOptions.UndeleteSource = undeleteSource; + auto result + = _detail::PathClient::Undelete(*m_pipeline, blobUrl, protocolLayerOptions, context); + + if (result.Value.ResourceType.HasValue() + && result.Value.ResourceType.Value() == Models::PathResourceType::Directory.ToString()) + { + return Azure::Response( + std::move(GetDirectoryClient(deletedPath)), std::move(result.RawResponse)); + } + else + { + return Azure::Response( + std::move(GetFileClient(deletedPath)), std::move(result.RawResponse)); + } + } + }}}} // namespace Azure::Storage::Files::DataLake diff --git a/sdk/storage/azure-storage-files-datalake/src/datalake_path_client.cpp b/sdk/storage/azure-storage-files-datalake/src/datalake_path_client.cpp index 0d6990d864..38084fc34d 100644 --- a/sdk/storage/azure-storage-files-datalake/src/datalake_path_client.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/datalake_path_client.cpp @@ -48,7 +48,8 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { : m_pathUrl(pathUrl), m_blobClient( _detail::GetBlobUrlFromUrl(pathUrl), credential, - _detail::GetBlobClientOptions(options)) + _detail::GetBlobClientOptions(options)), + m_customerProvidedKey(options.CustomerProvidedKey) { DataLakeClientOptions newOptions = options; newOptions.PerRetryPolicies.emplace_back( @@ -76,7 +77,8 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { : m_pathUrl(pathUrl), m_blobClient( _detail::GetBlobUrlFromUrl(pathUrl), credential, - _detail::GetBlobClientOptions(options)) + _detail::GetBlobClientOptions(options)), + m_customerProvidedKey(options.CustomerProvidedKey) { std::vector> perRetryPolicies; std::vector> perOperationPolicies; @@ -104,7 +106,8 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { const std::string& pathUrl, const DataLakeClientOptions& options) : m_pathUrl(pathUrl), - m_blobClient(_detail::GetBlobUrlFromUrl(pathUrl), _detail::GetBlobClientOptions(options)) + m_blobClient(_detail::GetBlobUrlFromUrl(pathUrl), _detail::GetBlobClientOptions(options)), + m_customerProvidedKey(options.CustomerProvidedKey) { std::vector> perRetryPolicies; std::vector> perOperationPolicies; @@ -202,6 +205,41 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { protocolLayerOptions.Properties = _detail::SerializeMetadata(options.Metadata); protocolLayerOptions.Umask = options.Umask; protocolLayerOptions.Permissions = options.Permissions; + protocolLayerOptions.Owner = options.Owner; + protocolLayerOptions.Group = options.Group; + protocolLayerOptions.ProposedLeaseId = options.LeaseId; + if (options.Acls.HasValue()) + { + protocolLayerOptions.Acl = Models::Acl::SerializeAcls(options.Acls.Value()); + } + if (options.LeaseDuration.HasValue()) + { + protocolLayerOptions.LeaseDuration = static_cast(options.LeaseDuration->count()); + } + AZURE_ASSERT_MSG( + !(options.ScheduleDeletionOptions.ExpiresOn.HasValue() + && options.ScheduleDeletionOptions.TimeToExpire.HasValue()), + "ExpiresOn and TimeToExpire are mutually exclusive."); + if (options.ScheduleDeletionOptions.ExpiresOn.HasValue()) + { + protocolLayerOptions.ExpiryOptions + = Files::DataLake::ScheduleFileExpiryOriginType::Absolute.ToString(); + protocolLayerOptions.ExpiresOn = options.ScheduleDeletionOptions.ExpiresOn.Value().ToString( + Azure::DateTime::DateFormat::Rfc1123); + } + else if (options.ScheduleDeletionOptions.TimeToExpire.HasValue()) + { + protocolLayerOptions.ExpiryOptions + = Files::DataLake::ScheduleFileExpiryOriginType::RelativeToNow.ToString(); + protocolLayerOptions.ExpiresOn + = std::to_string(options.ScheduleDeletionOptions.TimeToExpire.Value().count()); + } + if (m_customerProvidedKey.HasValue()) + { + protocolLayerOptions.EncryptionKey = m_customerProvidedKey.Value().Key; + protocolLayerOptions.EncryptionKeySha256 = m_customerProvidedKey.Value().KeyHash; + protocolLayerOptions.EncryptionAlgorithm = m_customerProvidedKey.Value().Algorithm.ToString(); + } return _detail::PathClient::Create(*m_pipeline, m_pathUrl, protocolLayerOptions, context); } diff --git a/sdk/storage/azure-storage-files-datalake/src/datalake_responses.cpp b/sdk/storage/azure-storage-files-datalake/src/datalake_responses.cpp index 7e3291beae..0ef5a9d612 100644 --- a/sdk/storage/azure-storage-files-datalake/src/datalake_responses.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/datalake_responses.cpp @@ -93,6 +93,12 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { *this = m_onNextPageFunc(NextPageToken.Value(), context); } + void ListDeletedPathsPagedResponse::OnNextPage(const Azure::Core::Context& context) + { + m_operationOptions.ContinuationToken = NextPageToken; + *this = m_fileSystemClient->ListDeletedPaths(m_operationOptions, context); + } + void SetPathAccessControlListRecursivePagedResponse::OnNextPage( const Azure::Core::Context& context) { diff --git a/sdk/storage/azure-storage-files-datalake/src/datalake_sas_builder.cpp b/sdk/storage/azure-storage-files-datalake/src/datalake_sas_builder.cpp index 53aadf9246..aecadd89da 100644 --- a/sdk/storage/azure-storage-files-datalake/src/datalake_sas_builder.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/datalake_sas_builder.cpp @@ -10,7 +10,7 @@ namespace Azure { namespace Storage { namespace Sas { namespace { - constexpr static const char* SasVersion = "2020-02-10"; + constexpr static const char* SasVersion = "2021-06-08"; std::string DataLakeSasResourceToString(DataLakeSasResource resource) { @@ -138,8 +138,9 @@ namespace Azure { namespace Storage { namespace Sas { std::string stringToSign = Permissions + "\n" + startsOnStr + "\n" + expiresOnStr + "\n" + canonicalName + "\n" + Identifier + "\n" + (IPRange.HasValue() ? IPRange.Value() : "") - + "\n" + protocol + "\n" + SasVersion + "\n" + resource + "\n" + "\n" + CacheControl + "\n" - + ContentDisposition + "\n" + ContentEncoding + "\n" + ContentLanguage + "\n" + ContentType; + + "\n" + protocol + "\n" + SasVersion + "\n" + resource + "\n" + "\n" + EncryptionScope + + "\n" + CacheControl + "\n" + ContentDisposition + "\n" + ContentEncoding + "\n" + + ContentLanguage + "\n" + ContentType; std::string signature = Azure::Core::Convert::Base64Encode(_internal::HmacSha256( std::vector(stringToSign.begin(), stringToSign.end()), @@ -190,6 +191,10 @@ namespace Azure { namespace Storage { namespace Sas { { builder.AppendQueryParameter("rsct", _internal::UrlEncodeQueryParameter(ContentType)); } + if (!EncryptionScope.empty()) + { + builder.AppendQueryParameter("ses", _internal::UrlEncodeQueryParameter(EncryptionScope)); + } return builder.GetAbsoluteUrl(); } @@ -223,8 +228,8 @@ namespace Azure { namespace Storage { namespace Sas { + "\n" + userDelegationKey.SignedService + "\n" + userDelegationKey.SignedVersion + "\n" + PreauthorizedAgentObjectId + "\n" + AgentObjectId + "\n" + CorrelationId + "\n" + (IPRange.HasValue() ? IPRange.Value() : "") + "\n" + protocol + "\n" + SasVersion + "\n" - + resource + "\n" + "\n" + CacheControl + "\n" + ContentDisposition + "\n" + ContentEncoding - + "\n" + ContentLanguage + "\n" + ContentType; + + resource + "\n" + "\n" + EncryptionScope + "\n" + CacheControl + "\n" + ContentDisposition + + "\n" + ContentEncoding + "\n" + ContentLanguage + "\n" + ContentType; std::string signature = Azure::Core::Convert::Base64Encode(_internal::HmacSha256( std::vector(stringToSign.begin(), stringToSign.end()), @@ -292,6 +297,10 @@ namespace Azure { namespace Storage { namespace Sas { { builder.AppendQueryParameter("rsct", _internal::UrlEncodeQueryParameter(ContentType)); } + if (!EncryptionScope.empty()) + { + builder.AppendQueryParameter("ses", _internal::UrlEncodeQueryParameter(EncryptionScope)); + } builder.AppendQueryParameter("sig", _internal::UrlEncodeQueryParameter(signature)); return builder.GetAbsoluteUrl(); diff --git a/sdk/storage/azure-storage-files-datalake/src/datalake_service_client.cpp b/sdk/storage/azure-storage-files-datalake/src/datalake_service_client.cpp index 4633d299ec..240abb8b65 100644 --- a/sdk/storage/azure-storage-files-datalake/src/datalake_service_client.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/datalake_service_client.cpp @@ -44,7 +44,8 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { : m_serviceUrl(serviceUrl), m_blobServiceClient( _detail::GetBlobUrlFromUrl(serviceUrl), credential, - _detail::GetBlobClientOptions(options)) + _detail::GetBlobClientOptions(options)), + m_customerProvidedKey(options.CustomerProvidedKey) { DataLakeClientOptions newOptions = options; newOptions.PerRetryPolicies.emplace_back( @@ -72,7 +73,8 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { : m_serviceUrl(serviceUrl), m_blobServiceClient( _detail::GetBlobUrlFromUrl(serviceUrl), credential, - _detail::GetBlobClientOptions(options)) + _detail::GetBlobClientOptions(options)), + m_customerProvidedKey(options.CustomerProvidedKey) { std::vector> perRetryPolicies; std::vector> perOperationPolicies; @@ -101,7 +103,8 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { const DataLakeClientOptions& options) : m_serviceUrl(serviceUrl), m_blobServiceClient( _detail::GetBlobUrlFromUrl(serviceUrl), - _detail::GetBlobClientOptions(options)) + _detail::GetBlobClientOptions(options)), + m_customerProvidedKey(options.CustomerProvidedKey) { std::vector> perRetryPolicies; std::vector> perOperationPolicies; @@ -124,7 +127,10 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { auto builder = m_serviceUrl; builder.AppendPath(_internal::UrlEncodePath(fileSystemName)); return DataLakeFileSystemClient( - builder, m_blobServiceClient.GetBlobContainerClient(fileSystemName), m_pipeline); + builder, + m_blobServiceClient.GetBlobContainerClient(fileSystemName), + m_pipeline, + m_customerProvidedKey); } ListFileSystemsPagedResponse DataLakeServiceClient::ListFileSystems( diff --git a/sdk/storage/azure-storage-files-datalake/src/datalake_utilities.cpp b/sdk/storage/azure-storage-files-datalake/src/datalake_utilities.cpp index 0d7c662f88..76a96546bb 100644 --- a/sdk/storage/azure-storage-files-datalake/src/datalake_utilities.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/datalake_utilities.cpp @@ -96,6 +96,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { nam blobOptions.SecondaryHostForRetryReads = _detail::GetBlobUrlFromUrl(options.SecondaryHostForRetryReads); blobOptions.ApiVersion = options.ApiVersion; + blobOptions.CustomerProvidedKey = options.CustomerProvidedKey; return blobOptions; } diff --git a/sdk/storage/azure-storage-files-datalake/src/private/datalake_utilities.hpp b/sdk/storage/azure-storage-files-datalake/src/private/datalake_utilities.hpp index a8e4e3adf6..d0d006882d 100644 --- a/sdk/storage/azure-storage-files-datalake/src/private/datalake_utilities.hpp +++ b/sdk/storage/azure-storage-files-datalake/src/private/datalake_utilities.hpp @@ -5,6 +5,7 @@ #include +#include #include #include @@ -28,4 +29,48 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { nam Blobs::BlobClientOptions GetBlobClientOptions(const DataLakeClientOptions& options); + /** + * @brief Provides conversion methods for Win32 FILETIME to an #Azure::DateTime. + * + */ + class Win32FileTimeConverter final { + public: + /** + * @brief Converts Win32 FILETIME to an #Azure::DateTime. + * + * @param win32Filetime The number of 100-nanoseconds since 1601-01-01. + * @return Calculated #Azure::DateTime. + */ + static DateTime Win32FileTimeToDateTime(int64_t win32Filetime) + { + auto t = DateTime(1601) + Azure::_detail::Clock::duration(win32Filetime); + return DateTime(t); + } + + /** + * @brief Converts a DateTime to Win32 FILETIME. + * + * @param dateTime The `%DateTime` to convert. + * @return The number of 100-nanoseconds since 1601-01-01. + */ + static int64_t DateTimeToWin32FileTime(DateTime const& dateTime) + { + return std::chrono::duration_cast(dateTime - DateTime(1601)) + .count(); + } + + /** + * @brief An instance of `%Win32FileTimeConverter` class cannot be created. + * + */ + Win32FileTimeConverter() = delete; + + /** + * @brief An instance of `%Win32FileTimeConverter` class cannot be destructed, because no + * instance can be created. + * + */ + ~Win32FileTimeConverter() = delete; + }; + }}}}} // namespace Azure::Storage::Files::DataLake::_detail diff --git a/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp b/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp index a19745cfdc..c105e1428a 100644 --- a/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp @@ -58,7 +58,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { request.GetUrl().AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); } - request.SetHeader("x-ms-version", "2020-02-10"); + request.SetHeader("x-ms-version", "2021-06-08"); if (options.ContinuationToken.HasValue() && !options.ContinuationToken.Value().empty()) { request.GetUrl().AppendQueryParameter( @@ -94,7 +94,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { ? jsonRoot["paths"] : Core::Json::_internal::json::array()) { - Models::PathItem vectorElement2; + Models::_detail::PathItem vectorElement2; vectorElement2.Name = var0["name"].get(); if (var0.count("isDirectory") != 0) { @@ -110,6 +110,18 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { vectorElement2.Owner = var0["owner"].get(); vectorElement2.Group = var0["group"].get(); vectorElement2.Permissions = var0["permissions"].get(); + if (var0.count("EncryptionScope") != 0) + { + vectorElement2.EncryptionScope = var0["EncryptionScope"].get(); + } + if (var0.count("creationTime") != 0) + { + vectorElement2.CreatedOn = var0["creationTime"].get(); + } + if (var0.count("expiryTime") != 0) + { + vectorElement2.ExpiresOn = var0["expiryTime"].get(); + } if (var0.count("etag") != 0) { vectorElement2.ETag = var0["etag"].get(); @@ -138,7 +150,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { request.GetUrl().AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); } - request.SetHeader("x-ms-version", "2020-02-10"); + request.SetHeader("x-ms-version", "2021-06-08"); if (options.Resource.HasValue() && !options.Resource.Value().ToString().empty()) { request.GetUrl().AppendQueryParameter( @@ -238,6 +250,49 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { "x-ms-source-if-unmodified-since", options.SourceIfUnmodifiedSince.Value().ToString(Azure::DateTime::DateFormat::Rfc1123)); } + if (options.EncryptionKey.HasValue() && !options.EncryptionKey.Value().empty()) + { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() + && !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()).empty()) + { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && !options.EncryptionAlgorithm.Value().empty()) + { + request.SetHeader("x-ms-encryption-algorithm", options.EncryptionAlgorithm.Value()); + } + if (options.Owner.HasValue() && !options.Owner.Value().empty()) + { + request.SetHeader("x-ms-owner", options.Owner.Value()); + } + if (options.Group.HasValue() && !options.Group.Value().empty()) + { + request.SetHeader("x-ms-group", options.Group.Value()); + } + if (options.Acl.HasValue() && !options.Acl.Value().empty()) + { + request.SetHeader("x-ms-acl", options.Acl.Value()); + } + if (options.ProposedLeaseId.HasValue() && !options.ProposedLeaseId.Value().empty()) + { + request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId.Value()); + } + if (options.LeaseDuration.HasValue()) + { + request.SetHeader("x-ms-lease-duration", std::to_string(options.LeaseDuration.Value())); + } + if (options.ExpiryOptions.HasValue() && !options.ExpiryOptions.Value().empty()) + { + request.SetHeader("x-ms-expiry-option", options.ExpiryOptions.Value()); + } + if (options.ExpiresOn.HasValue() && !options.ExpiresOn.Value().empty()) + { + request.SetHeader("x-ms-expiry-time", options.ExpiresOn.Value()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Created) @@ -252,6 +307,16 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { response.FileSize = std::stoll(pRawResponse->GetHeaders().at("Content-Length")); } + if (pRawResponse->GetHeaders().count("x-ms-request-server-encrypted") != 0) + { + response.IsServerEncrypted + = pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == std::string("true"); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) + { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } return Response(std::move(response), std::move(pRawResponse)); } Response PathClient::Delete( @@ -269,7 +334,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { request.GetUrl().AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); } - request.SetHeader("x-ms-version", "2020-02-10"); + request.SetHeader("x-ms-version", "2021-06-08"); if (options.Recursive.HasValue()) { request.GetUrl().AppendQueryParameter( @@ -361,7 +426,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { "If-Unmodified-Since", options.IfUnmodifiedSince.Value().ToString(Azure::DateTime::DateFormat::Rfc1123)); } - request.SetHeader("x-ms-version", "2020-02-10"); + request.SetHeader("x-ms-version", "2021-06-08"); auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -408,7 +473,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { request.SetHeader("x-ms-acl", options.Acl.Value()); } - request.SetHeader("x-ms-version", "2020-02-10"); + request.SetHeader("x-ms-version", "2021-06-08"); auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -449,6 +514,33 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { return Response( std::move(response), std::move(pRawResponse)); } + Response PathClient::Undelete( + Core::Http::_internal::HttpPipeline& pipeline, + const Core::Url& url, + const UndeletePathOptions& options, + const Core::Context& context) + { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "undelete"); + if (options.UndeleteSource.HasValue() && !options.UndeleteSource.Value().empty()) + { + request.SetHeader("x-ms-undelete-source", options.UndeleteSource.Value()); + } + request.SetHeader("x-ms-version", "2021-06-08"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) + { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::_detail::UndeletePathResult response; + if (pRawResponse->GetHeaders().count("x-ms-resource-type") != 0) + { + response.ResourceType = pRawResponse->GetHeaders().at("x-ms-resource-type"); + } + return Response( + std::move(response), std::move(pRawResponse)); + } Response PathClient::GetAccessControlList( Core::Http::_internal::HttpPipeline& pipeline, const Core::Url& url, @@ -485,7 +577,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { "If-Unmodified-Since", options.IfUnmodifiedSince.Value().ToString(Azure::DateTime::DateFormat::Rfc1123)); } - request.SetHeader("x-ms-version", "2020-02-10"); + request.SetHeader("x-ms-version", "2021-06-08"); auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -572,7 +664,22 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { "If-Unmodified-Since", options.IfUnmodifiedSince.Value().ToString(Azure::DateTime::DateFormat::Rfc1123)); } - request.SetHeader("x-ms-version", "2020-02-10"); + request.SetHeader("x-ms-version", "2021-06-08"); + if (options.EncryptionKey.HasValue() && !options.EncryptionKey.Value().empty()) + { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() + && !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()).empty()) + { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && !options.EncryptionAlgorithm.Value().empty()) + { + request.SetHeader("x-ms-encryption-algorithm", options.EncryptionAlgorithm.Value()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -584,6 +691,16 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { response.LastModified = DateTime::Parse( pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123); response.FileSize = std::stoll(pRawResponse->GetHeaders().at("Content-Length")); + if (pRawResponse->GetHeaders().count("x-ms-request-server-encrypted") != 0) + { + response.IsServerEncrypted + = pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == std::string("true"); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) + { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } return Response(std::move(response), std::move(pRawResponse)); } Response FileClient::Append( @@ -617,7 +734,26 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); } - request.SetHeader("x-ms-version", "2020-02-10"); + request.SetHeader("x-ms-version", "2021-06-08"); + if (options.EncryptionKey.HasValue() && !options.EncryptionKey.Value().empty()) + { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() + && !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()).empty()) + { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + if (options.EncryptionAlgorithm.HasValue() && !options.EncryptionAlgorithm.Value().empty()) + { + request.SetHeader("x-ms-encryption-algorithm", options.EncryptionAlgorithm.Value()); + } + if (options.Flush.HasValue()) + { + request.GetUrl().AppendQueryParameter("flush", options.Flush.Value() ? "true" : "false"); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Accepted) @@ -639,8 +775,16 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { = Core::Convert::Base64Decode(pRawResponse->GetHeaders().at("x-ms-content-crc64")); response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Crc64; } - response.IsServerEncrypted - = pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == std::string("true"); + if (pRawResponse->GetHeaders().count("x-ms-request-server-encrypted") != 0) + { + response.IsServerEncrypted + = pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == std::string("true"); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) + { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } return Response(std::move(response), std::move(pRawResponse)); } } // namespace _detail diff --git a/sdk/storage/azure-storage-files-datalake/swagger/README.md b/sdk/storage/azure-storage-files-datalake/swagger/README.md index 0e9b87c617..b7c915b212 100644 --- a/sdk/storage/azure-storage-files-datalake/swagger/README.md +++ b/sdk/storage/azure-storage-files-datalake/swagger/README.md @@ -9,7 +9,7 @@ package-name: azure-storage-files-datalake namespace: Azure::Storage::Files::DataLake output-folder: generated clear-output-folder: true -input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/storage-main/specification/storage/data-plane/Microsoft.StorageDataLake/stable/2020-06-12/DataLakeStorage.json +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/storage/data-plane/Azure.Storage.Files.DataLake/preview/2021-06-08/DataLakeStorage.json ``` ## ModelFour Options @@ -66,12 +66,11 @@ directive: delete $["/{filesystem}"].patch; delete $["/{filesystem}"].head; delete $["/{filesystem}"].delete; - delete $["/{filesystem}?restype=container&comp=list&hierarchy"]; delete $["/{filesystem}/{path}"].post; delete $["/{filesystem}/{path}"].get; delete $["/{filesystem}/{path}"].patch; delete $["/{filesystem}/{path}?comp=expiry"]; - delete $["/{filesystem}/{path}?comp=undelete"]; + delete $["/{filesystem}?restype=container&comp=list&hierarchy"]; ``` ### API Version @@ -89,13 +88,13 @@ directive: "name": "ApiVersion", "modelAsString": false }, - "enum": ["2020-02-10"], + "enum": ["2021-06-08"], "description": "The version used for the operations to Azure storage services." }; - from: swagger-document where: $.parameters transform: > - $.ApiVersionParameter.enum[0] = "2020-02-10"; + $.ApiVersionParameter.enum[0] = "2021-06-08"; ``` ### Rename Operations @@ -118,14 +117,72 @@ directive: } ``` +### Return Type namespace + +```yaml +directive: + - from: swagger-document + where: $ + transform: > + const operations = [ + "Path_Undelete", + ]; + for (const url in $["x-ms-paths"]) { + for (const verb in $["x-ms-paths"][url]) { + if (!operations.includes($["x-ms-paths"][url][verb].operationId)) continue; + const operation = $["x-ms-paths"][url][verb]; + + const status_codes = Object.keys(operation.responses).filter(s => s !== "default"); + status_codes.forEach((status_code, i) => { + if (!operation.responses[status_code].schema) { + const operationId = operation.operationId; + const clientName = operationId.substr(0, operationId.indexOf("_")); + const operationName = operationId.substr(operationId.indexOf("_") + 1); + let operationWords = operationName.split(/(?=[A-Z])/); + operationWords.splice(1, 0, clientName); + const defaultReturnTypeName = operationWords.join("") + "Result"; + operation.responses[status_code].schema = { + "type": "object", + "x-ms-sealed": false, + "x-ms-client-name": defaultReturnTypeName, + "x-namespace": "_detail", + "properties": { + "__placeHolder": {"type": "integer"} + } + }; + } else if (operation.responses[status_code].schema["$ref"]) { + let obj = $; + for (const p of operation.responses[status_code].schema["$ref"].split("/").slice(1)) { + obj = obj[p]; + } + obj["x-namespace"] = "_detail"; + } else { + operation.responses[status_code].schema["x-namespace"] = "_detail"; + } + }); + } + } +``` + ### Global Changes for Definitions, Types etc. ```yaml directive: + - from: swagger-document + where: $["x-ms-paths"].*.*.responses.*.headers + transform: > + for (const h in $) { + if (h === "x-ms-encryption-key-sha256") { + $[h]["format"] = "byte"; + } + } - from: swagger-document where: $.parameters transform: > $.Continuation["x-ms-client-name"] = "ContinuationToken"; + $.EncryptionKeySha256["format"] = "byte"; + delete $.EncryptionAlgorithm["enum"]; + delete $.EncryptionAlgorithm["x-ms-enum"]; - from: swagger-document where: $.definitions transform: > @@ -172,9 +229,13 @@ directive: where: $.definitions transform: > $.Path["x-ms-client-name"] = "PathItem"; + $.Path["x-namespace"] = "_detail"; $.Path.properties["lastModified"]["format"] = "date-time-rfc1123"; $.Path.properties["contentLength"]["x-ms-client-name"] = "FileSize"; $.Path.properties["isDirectory"]["x-ms-client-default"] = false; + $.Path.properties["EncryptionScope"]["x-nullable"] = true; + $.Path.properties["creationTime"] = {"type": "string", "x-ms-client-name": "CreatedOn", "x-nullable": true}; + $.Path.properties["expiryTime"] = {"type": "string", "x-ms-client-name": "ExpiresOn", "x-nullable": true}; $.Path.properties["etag"] = {"type": "string", "x-ms-format": "string", "x-ms-client-default": "", "x-ms-client-name": "ETag"}; delete $.Path.properties["eTag"]; $.PathList["x-namespace"] = "_detail"; @@ -197,6 +258,8 @@ directive: transform: > $["201"].headers["Content-Length"]["x-ms-client-name"] = "FileSize"; $["201"].headers["Content-Length"]["x-nullable"] = true; + $["201"].headers["x-ms-request-server-encrypted"]["x-nullable"] = true; + $["201"].headers["x-ms-encryption-key-sha256"]["x-nullable"] = true; delete $["201"].headers["x-ms-continuation"]; $["201"].schema = { "type": "object", @@ -208,6 +271,20 @@ directive: }; ``` + +### SetExpiry + +```yaml +directive: + - from: swagger-document + where: $.parameters + transform: > + delete $["PathExpiryOptions"]; + delete $.PathExpiryOptionsOptional["enum"]; + delete $.PathExpiryOptionsOptional["x-ms-enum"]; + +``` + ### DeletePath ```yaml @@ -253,6 +330,16 @@ directive: } ``` +### UndeletePath + +```yaml +directive: + - from: swagger-document + where: $["x-ms-paths"]["/{filesystem}/{path}?comp=undelete"].put.responses + transform: > + $["200"].headers["x-ms-resource-type"]["x-nullable"] = true; +``` + ### GetPathAccessControlList ```yaml @@ -349,6 +436,8 @@ directive: $["Content-MD5"]["x-nullable"] = true; $["x-ms-content-crc64"]["x-ms-client-name"] = "TransactionalContentHash"; $["x-ms-content-crc64"]["x-nullable"] = true; + $["x-ms-request-server-encrypted"]["x-nullable"] = true; + $["x-ms-encryption-key-sha256"]["x-nullable"] = true; delete $["ETag"]; ``` @@ -360,4 +449,6 @@ directive: where: $["x-ms-paths"]["/{filesystem}/{path}?action=flush"].patch.responses["200"].headers transform: > $["Content-Length"]["x-ms-client-name"] = "FileSize"; + $["x-ms-request-server-encrypted"]["x-nullable"] = true; + $["x-ms-encryption-key-sha256"]["x-nullable"] = true; ``` \ No newline at end of file diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/CMakeLists.txt b/sdk/storage/azure-storage-files-datalake/test/ut/CMakeLists.txt index a8d6fe32fe..ea2c7d2fd0 100644 --- a/sdk/storage/azure-storage-files-datalake/test/ut/CMakeLists.txt +++ b/sdk/storage/azure-storage-files-datalake/test/ut/CMakeLists.txt @@ -18,6 +18,7 @@ add_executable ( datalake_directory_client_test.hpp datalake_file_client_test.cpp datalake_file_client_test.hpp + datalake_file_query_test.cpp datalake_file_system_client_test.cpp datalake_file_system_client_test.hpp datalake_path_client_test.cpp diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_client_test.cpp b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_client_test.cpp index 099135cd54..a253e807bf 100644 --- a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_client_test.cpp +++ b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_client_test.cpp @@ -29,6 +29,7 @@ namespace Azure { namespace Storage { namespace Test { void DataLakeFileClientTest::SetUp() { DataLakeFileSystemClientTest::SetUp(); + CHECK_SKIP_TEST(); m_fileName = GetFileSystemValidName(); m_fileClient = std::make_shared( m_fileSystemClient->GetFileClient(m_fileName)); @@ -37,6 +38,7 @@ namespace Azure { namespace Storage { namespace Test { void DataLakeFileClientTest::TearDown() { + CHECK_SKIP_TEST(); m_fileSystemClient->GetFileClient(m_fileName).Delete(); DataLakeFileSystemClientTest::TearDown(); } @@ -243,6 +245,40 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_EQ(buffer, downloaded); } + TEST_F(DataLakeFileClientTest, AppendFileWithFlush) + { + const int32_t bufferSize = 4 * 1024; // 4KB data size + std::vector buffer(bufferSize, 'x'); + auto bufferStream = std::make_unique( + Azure::Core::IO::MemoryBodyStream(buffer)); + + // Append with flush option + { + auto client = m_fileSystemClient->GetFileClient(GetTestNameLowerCase() + "_flush_true"); + client.Create(); + auto properties1 = client.GetProperties(); + Files::DataLake::AppendFileOptions options; + options.Flush = true; + bufferStream->Rewind(); + client.Append(*bufferStream, 0, options); + auto properties2 = client.GetProperties(); + EXPECT_NE(properties1.Value.ETag, properties2.Value.ETag); + EXPECT_EQ(bufferSize, properties2.Value.FileSize); + } + { + auto client = m_fileSystemClient->GetFileClient(GetTestNameLowerCase() + "_flush_false"); + client.Create(); + auto properties1 = client.GetProperties(); + Files::DataLake::AppendFileOptions options; + options.Flush = false; + bufferStream->Rewind(); + client.Append(*bufferStream, 0, options); + auto properties2 = client.GetProperties(); + EXPECT_EQ(properties1.Value.ETag, properties2.Value.ETag); + EXPECT_EQ(0ll, properties2.Value.FileSize); + } + } + TEST_F(DataLakeFileClientTest, FileReadReturns) { const int32_t bufferSize = 4 * 1024; // 4KB data size diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_query_test.cpp b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_query_test.cpp new file mode 100644 index 0000000000..1aa6a8c3d8 --- /dev/null +++ b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_query_test.cpp @@ -0,0 +1,430 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include "datalake_file_client_test.hpp" + +#include +#include +#include + +// cspell:ignore sapote + +namespace Azure { namespace Storage { namespace Test { + + const std::string JsonQueryTestData = + R"json( +{"id": 100, "name": "oranges", "price": 100} +{"id": 101, "name": "limes", "price": 50} +{"id": 102, "name": "berries", "price": 199} +{"id": 103, "name": "apples", "price": 99} +{"id": 104, "name": "clementines", "price": 399} +{"id": 105, "name": "grapes", "price": 150} +{"id": 106, "name": "lemons", "price": 69} +{"id": 107, "name": "pears", "price": 100} +{"id": 108, "name": "cherries", "price": 281} +{"id": 109, "name": "coconut", "price": 178} +{"id": 110, "name": "bananas", "price": 39} +{"id": 111, "name": "peaches", "price": 117} +{"id": 112, "name": "sapote,\"mamey", "price": 50} +)json"; + + const std::string CsvQueryTestData = R"csv( +id,name,price +100,oranges,100 +101,limes,50 +102,berries,199 +103,apples,99 +104,clementines,399 +105,grapes,150 +106,lemons,69 +107,pears,100 +108,cherries,281 +109,coconut,178 +110,bananas,39 +111,peaches,117 +112,sapote\,mamey,50 +)csv"; + + const std::vector ParquetQueryTestData = Core::Convert::Base64Decode( + "UEFSMRUAFewBFewBLBUaFQAVBhUIAAACAAAAGgFkAAAAAAAAAGUAAAAAAAAAZgAAAAAAAABnAAAAAAAAAGgAAAAAAAAA" + "aQAAAAAAAABqAAAAAAAAAGsAAAAAAAAAbAAAAAAAAABtAAAAAAAAAG4AAAAAAAAAbwAAAAAAAABwAAAAAAAAAAAAAAAA" + "AAAAFQAVxAIVxAIsFRoVABUGFQgAAAIAAAAaAQcAAABvcmFuZ2VzBQAAAGxpbWVzBwAAAGJlcnJpZXMGAAAAYXBwbGVz" + "CwAAAGNsZW1lbnRpbmVzBgAAAGdyYXBlcwYAAABsZW1vbnMFAAAAcGVhcnMIAAAAY2hlcnJpZXMHAAAAY29jb251dAcA" + "AABiYW5hbmFzBwAAAHBlYWNoZXMOAAAAc2Fwb3RlLCJtYW1leSIAAAAAAAAAABUAFewBFewBLBUaFQAVBhUIAAACAAAA" + "GgFkAAAAAAAAADIAAAAAAAAAxwAAAAAAAABjAAAAAAAAAI8BAAAAAAAAlgAAAAAAAABFAAAAAAAAAGQAAAAAAAAAGQEA" + "AAAAAACyAAAAAAAAACcAAAAAAAAAdQAAAAAAAAAyAAAAAAAAAAAAAAAAAAAAFQIZTEgGc2NoZW1hFQYAFQQVgAEVAhgC" + "aWQAFQwlAhgEbmFtZSUAABUEFYABFQIYBXByaWNlABYaGRwZPCaaAhwVBBkVABkYAmlkFQAWGhaSAhaSAhkAFgg8GAhw" + "AAAAAAAAABgIZAAAAAAAAAAWAAAZHBUAFQAVAgAAACaEBRwVDBkVABkYBG5hbWUVABYaFuoCFuoCGQAWmgI8GA5zYXBv" + "dGUsIm1hbWV5IhgGYXBwbGVzFgAAGRwVABUAFQIAAAAmlgccFQQZFQAZGAVwcmljZRUAFhoWkgIWkgIZABaEBTwYCI8B" + "AAAAAAAAGAgnAAAAAAAAABYAABkcFQAVABUCAAAAFo4HFhoAGRwYBnBhbmRhcxiRBXsiY29sdW1uX2luZGV4ZXMiOiBb" + "eyJmaWVsZF9uYW1lIjogbnVsbCwgIm1ldGFkYXRhIjogbnVsbCwgIm5hbWUiOiBudWxsLCAibnVtcHlfdHlwZSI6ICJv" + "YmplY3QiLCAicGFuZGFzX3R5cGUiOiAibWl4ZWQtaW50ZWdlciJ9XSwgImNvbHVtbnMiOiBbeyJmaWVsZF9uYW1lIjog" + "ImlkIiwgIm1ldGFkYXRhIjogbnVsbCwgIm5hbWUiOiAiaWQiLCAibnVtcHlfdHlwZSI6ICJpbnQ2NCIsICJwYW5kYXNf" + "dHlwZSI6ICJpbnQ2NCJ9LCB7ImZpZWxkX25hbWUiOiAibmFtZSIsICJtZXRhZGF0YSI6IG51bGwsICJuYW1lIjogIm5h" + "bWUiLCAibnVtcHlfdHlwZSI6ICJvYmplY3QiLCAicGFuZGFzX3R5cGUiOiAidW5pY29kZSJ9LCB7ImZpZWxkX25hbWUi" + "OiAicHJpY2UiLCAibWV0YWRhdGEiOiBudWxsLCAibmFtZSI6ICJwcmljZSIsICJudW1weV90eXBlIjogImludDY0Iiwg" + "InBhbmRhc190eXBlIjogImludDY0In1dLCAiY3JlYXRvciI6IHsibGlicmFyeSI6ICJmYXN0cGFycXVldCIsICJ2ZXJz" + "aW9uIjogIjAuOC4xIn0sICJpbmRleF9jb2x1bW5zIjogW3sia2luZCI6ICJyYW5nZSIsICJuYW1lIjogbnVsbCwgInN0" + "YXJ0IjogMCwgInN0ZXAiOiAxLCAic3RvcCI6IDEzfV0sICJwYW5kYXNfdmVyc2lvbiI6ICIxLjQuMiIsICJwYXJ0aXRp" + "b25fY29sdW1ucyI6IFtdfQAYKmZhc3RwYXJxdWV0LXB5dGhvbiB2ZXJzaW9uIDAuOC4xIChidWlsZCAwKQDXAwAAUEFS" + "MQ=="); + + TEST_F(DataLakeFileClientTest, QueryJsonInputCsvOutput_LIVEONLY_) + { + auto const testName(GetTestName()); + auto client = m_fileSystemClient->GetFileClient(testName); + + client.UploadFrom( + reinterpret_cast(JsonQueryTestData.data()), JsonQueryTestData.size()); + + Files::DataLake::QueryFileOptions queryOptions; + queryOptions.InputTextConfiguration + = Files::DataLake::FileQueryInputTextOptions::CreateJsonTextOptions(); + + { + queryOptions.OutputTextConfiguration + = Files::DataLake::FileQueryOutputTextOptions::CreateCsvTextOptions(); + auto queryResponse + = client.Query("SELECT * from BlobStorage WHERE id > 101 AND price < 100;", queryOptions); + auto data = queryResponse.Value.BodyStream->ReadToEnd(); + EXPECT_EQ( + std::string(data.begin(), data.end()), + R"csv(103,apples,99 +106,lemons,69 +110,bananas,39 +112,"sapote,""mamey",50 +)csv"); + } + + { + queryOptions.OutputTextConfiguration + = Files::DataLake::FileQueryOutputTextOptions::CreateCsvTextOptions( + "|", ".", "[", "\\", true); + auto queryResponse + = client.Query("SELECT * from BlobStorage WHERE id > 101 AND price < 100;", queryOptions); + + auto data = queryResponse.Value.BodyStream->ReadToEnd(); + EXPECT_EQ( + std::string(data.begin(), data.end()), + R"csv(103.apples.99|106.lemons.69|110.bananas.39|112.sapote,"mamey.50|)csv"); + } + } + + TEST_F(DataLakeFileClientTest, QueryCsvInputJsonOutput_LIVEONLY_) + { + auto const testName(GetTestName()); + auto client = m_fileSystemClient->GetFileClient(testName); + + client.UploadFrom( + reinterpret_cast(CsvQueryTestData.data()), CsvQueryTestData.size()); + + Files::DataLake::QueryFileOptions queryOptions; + queryOptions.InputTextConfiguration + = Files::DataLake::FileQueryInputTextOptions::CreateCsvTextOptions( + "\n", ",", "\"", "\\", true); + queryOptions.OutputTextConfiguration + = Files::DataLake::FileQueryOutputTextOptions::CreateJsonTextOptions("|"); + auto queryResponse + = client.Query("SELECT * from BlobStorage WHERE id > 101 AND price < 100;", queryOptions); + + auto data = queryResponse.Value.BodyStream->ReadToEnd(); + EXPECT_EQ( + std::string(data.begin(), data.end()), + R"json({"id":"103","name":"apples","price":"99"}|{"id":"106","name":"lemons","price":"69"}|{"id":"110","name":"bananas","price":"39"}|{"id":"112","name":"sapote,mamey","price":"50"}|)json"); + } + + TEST_F(DataLakeFileClientTest, QueryCsvInputArrowOutput_LIVEONLY_) + { + auto const testName(GetTestName()); + auto client = m_fileSystemClient->GetFileClient(testName); + + client.UploadFrom( + reinterpret_cast(CsvQueryTestData.data()), CsvQueryTestData.size()); + + Files::DataLake::QueryFileOptions queryOptions; + queryOptions.InputTextConfiguration + = Files::DataLake::FileQueryInputTextOptions::CreateCsvTextOptions( + "\n", ",", "\"", "\\", true); + std::vector fields; + Files::DataLake::Models::FileQueryArrowField field; + field.Type = Files::DataLake::Models::FileQueryArrowFieldType::Int64; + field.Name = "id"; + fields.push_back(field); + field.Type = Files::DataLake::Models::FileQueryArrowFieldType::String; + field.Name = "name"; + fields.push_back(field); + field.Type = Files::DataLake::Models::FileQueryArrowFieldType::Decimal; + field.Name = "price"; + field.Precision = 10; + field.Scale = 2; + fields.push_back(field); + queryOptions.OutputTextConfiguration + = Files::DataLake::FileQueryOutputTextOptions::CreateArrowTextOptions(std::move(fields)); + auto queryResponse + = client.Query("SELECT * from BlobStorage WHERE id > 101 AND price < 100;", queryOptions); + + auto data = queryResponse.Value.BodyStream->ReadToEnd(); + const auto expectedData = Core::Convert::Base64Decode( + "/////" + "+gAAAAQAAAAAAAKAAwABgAFAAgACgAAAAABBAAMAAAACAAIAAAABAAIAAAABAAAAAMAAACAAAAAQAAAAAQAAAC" + "c////AAABBxAAAAAgAAAABAAAAAAAAAAFAAAAcHJpY2UAAAAIAAwABAAIAAgAAAAKAAAAAgAAANT///" + "8AAAEFEAAAABwAAAAEAAAAAAAAAAQAAABuYW1lAAAAAAQABAAEAAAAEAAUAAgABgAHAAwAAAAQABAAAAAAAAEC" + "EAAAABwAAAAEAAAAAAAAAAIAAABpZAAACAAMAAgABwAIAAAAAAAAAUAAAAAAAAAA//////" + "AAAAAUAAAAAAAAAAwAGgAGAAUACAAMAAwAAAAAAwQAHAAAAAgAAAAAAAAAAAAAAAAACgAMAAAABAAIAAoAAACA" + "AAAABAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAQAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAMA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////" + "4AAAAFAAAAAAAAAAMABYABgAFAAgADAAMAAAAAAMEABgAAACYAAAAAAAAAAAACgAYAAwABAAIAAoAAACMAAAAE" + "AAAAAQAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAAAAAAAA" + "AAAAgAAAAAAAAABQAAAAAAAAAOAAAAAAAAAAfAAAAAAAAAFgAAAAAAAAAAAAAAAAAAABYAAAAAAAAAEAAAAAAA" + "AAAAAAAAAMAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAABnAAAAAAA" + "AAGoAAAAAAAAAbgAAAAAAAABwAAAAAAAAAAAAAAAGAAAADAAAABMAAAAfAAAAAAAAAGFwcGxlc2xlbW9uc2Jhb" + "mFuYXNzYXBvdGUsbWFtZXkAYwAAAAAAAAAAAAAAAAAAAEUAAAAAAAAAAAAAAAAAAAAnAAAAAAAAAAAAAAAAAAA" + "AMgAAAAAAAAAAAAAAAAAAAA=="); + EXPECT_EQ(data, expectedData); + } + + TEST_F(DataLakeFileClientTest, QueryParquetInputArrowOutput_LIVEONLY_) + { + auto const testName(GetTestName()); + auto client = m_fileSystemClient->GetFileClient(testName); + + client.UploadFrom(ParquetQueryTestData.data(), ParquetQueryTestData.size()); + + Files::DataLake::QueryFileOptions queryOptions; + queryOptions.InputTextConfiguration + = Files::DataLake::FileQueryInputTextOptions::CreateParquetTextOptions(); + std::vector fields; + Files::DataLake::Models::FileQueryArrowField field; + field.Type = Files::DataLake::Models::FileQueryArrowFieldType::Int64; + field.Name = "id"; + fields.push_back(field); + field.Type = Files::DataLake::Models::FileQueryArrowFieldType::String; + field.Name = "name"; + fields.push_back(field); + field.Type = Files::DataLake::Models::FileQueryArrowFieldType::Int64; + field.Name = "price"; + fields.push_back(field); + queryOptions.OutputTextConfiguration + = Files::DataLake::FileQueryOutputTextOptions::CreateArrowTextOptions(std::move(fields)); + auto queryResponse + = client.Query("SELECT * from BlobStorage WHERE id > 101 AND price < 100;", queryOptions); + auto data = queryResponse.Value.BodyStream->ReadToEnd(); + const auto expectedData = Core::Convert::Base64Decode( + "/////" + "+AAAAAQAAAAAAAKAAwABgAFAAgACgAAAAABBAAMAAAACAAIAAAABAAIAAAABAAAAAMAAAB4AAAAOAAAAAQAAAC" + "k////AAABAhAAAAAYAAAABAAAAAAAAAAFAAAAcHJpY2UAAACY////AAAAAUAAAADU////" + "AAABBRAAAAAcAAAABAAAAAAAAAAEAAAAbmFtZQAAAAAEAAQABAAAABAAFAAIAAYABwAMAAAAEAAQAAAAAAABAh" + "AAAAAcAAAABAAAAAAAAAACAAAAaWQAAAgADAAIAAcACAAAAAAAAAFAAAAAAAAAAP/////" + "wAAAAFAAAAAAAAAAMABoABgAFAAgADAAMAAAAAAMEABwAAAAIAAAAAAAAAAAAAAAAAAoADAAAAAQACAAKAAAAg" + "AAAAAQAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAEAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAADA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////" + "+AAAABQAAAAAAAAADAAWAAYABQAIAAwADAAAAAADBAAYAAAAIAAAAAAAAAAAAAoAGAAMAAQACAAKAAAAjAAAAB" + "AAAAABAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAAAAAAAAAAAAA" + "AAAACAAAAAAAAAAIAAAAAAAAABAAAAAAAAAABgAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAIAAAAAA" + "AAAAAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAZwAAAAAA" + "AAAAAAAABgAAAGFwcGxlcwAAYwAAAAAAAAD/////" + "+AAAABQAAAAAAAAADAAWAAYABQAIAAwADAAAAAADBAAYAAAAIAAAAAAAAAAAAAoAGAAMAAQACAAKAAAAjAAAAB" + "AAAAABAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAAAAAAAAAAAAA" + "AAAACAAAAAAAAAAIAAAAAAAAABAAAAAAAAAABgAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAIAAAAAA" + "AAAAAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAagAAAAAA" + "AAAAAAAABgAAAGxlbW9ucwAARQAAAAAAAAD/////" + "+AAAABQAAAAAAAAADAAWAAYABQAIAAwADAAAAAADBAAYAAAAIAAAAAAAAAAAAAoAGAAMAAQACAAKAAAAjAAAAB" + "AAAAABAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAAAAAAAAAAAAA" + "AAAACAAAAAAAAAAIAAAAAAAAABAAAAAAAAAABwAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAIAAAAAA" + "AAAAAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAbgAAAAAA" + "AAAAAAAABwAAAGJhbmFuYXMAJwAAAAAAAAD/////" + "+AAAABQAAAAAAAAADAAWAAYABQAIAAwADAAAAAADBAAYAAAAKAAAAAAAAAAAAAoAGAAMAAQACAAKAAAAjAAAAB" + "AAAAABAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAAAAAAAAAAAAA" + "AAAACAAAAAAAAAAIAAAAAAAAABAAAAAAAAAADgAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAIAAAAAA" + "AAAAAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAcAAAAAAA" + "AAAAAAAADgAAAHNhcG90ZSwibWFtZXkiAAAyAAAAAAAAAP////8AAAAA"); + EXPECT_EQ(data, expectedData); + } + + TEST_F(DataLakeFileClientTest, QueryWithError_LIVEONLY_) + { + auto const testName(GetTestName()); + auto client = m_fileSystemClient->GetFileClient(testName); + + const std::string malformedData = + R"json( +{"id": 100, "name": "oranges", "price": 100} +{"id": 101, "name": "limes", "price": "aa"} +{"id": 102, "name": "berries", "price": 199} +{"id": 103, "name": "apples", "price": "bb"} +{"id": 104, "name": "clementines", "price": 399} +xx +)json"; + client.UploadFrom(reinterpret_cast(malformedData.data()), malformedData.size()); + + Files::DataLake::QueryFileOptions queryOptions; + queryOptions.InputTextConfiguration + = Files::DataLake::FileQueryInputTextOptions::CreateJsonTextOptions(); + queryOptions.OutputTextConfiguration + = Files::DataLake::FileQueryOutputTextOptions::CreateJsonTextOptions(); + auto queryResponse = client.Query("SELECT * FROM BlobStorage WHERE price > 0;", queryOptions); + + try + { + auto data = queryResponse.Value.BodyStream->ReadToEnd(); + FAIL(); + } + catch (StorageException& e) + { + EXPECT_EQ(e.StatusCode, Core::Http::HttpStatusCode::Ok); + EXPECT_EQ(e.ReasonPhrase, "OK"); + EXPECT_FALSE(e.RequestId.empty()); + EXPECT_FALSE(e.ClientRequestId.empty()); + EXPECT_EQ(e.ErrorCode, "ParseError"); + EXPECT_FALSE(e.Message.empty()); + EXPECT_FALSE(std::string(e.what()).empty()); + } + + bool progressCallbackCalled = false; + queryOptions.ProgressHandler + = [&malformedData, &progressCallbackCalled](int64_t offset, int64_t totalBytes) { + EXPECT_EQ(totalBytes, static_cast(malformedData.size())); + EXPECT_TRUE(offset >= 0 && offset <= totalBytes); + progressCallbackCalled = true; + }; + int numNonFatalErrors = 0; + int numFatalErrors = 0; + queryOptions.ErrorHandler + = [&numNonFatalErrors, &numFatalErrors](Files::DataLake::FileQueryError e) { + if (e.IsFatal) + { + ++numFatalErrors; + } + else + { + ++numNonFatalErrors; + } + }; + queryResponse = client.Query("SELECT * FROM BlobStorage WHERE price > 0;", queryOptions); + queryResponse.Value.BodyStream->ReadToEnd(); + + EXPECT_EQ(numNonFatalErrors, 2); + EXPECT_EQ(numFatalErrors, 1); + EXPECT_TRUE(progressCallbackCalled); + } + + TEST_F(DataLakeFileClientTest, QueryDefaultInputOutput_LIVEONLY_) + { + auto const testName(GetTestName()); + auto client = m_fileSystemClient->GetFileClient(testName); + + const std::string csvData = "100,oranges,100"; + client.UploadFrom(reinterpret_cast(csvData.data()), csvData.size()); + auto queryResponse = client.Query("SELECT * from BlobStorage;"); + + auto data = queryResponse.Value.BodyStream->ReadToEnd(); + } + + TEST_F(DataLakeFileClientTest, QueryLargeBlob_LIVEONLY_) + { + auto const testName(GetTestName()); + auto client = m_fileSystemClient->GetFileClient(testName); + + constexpr size_t DataSize = static_cast(32_MB); + + int recordCounter = 0; + std::string csvData; + std::string jsonData; + while (csvData.size() < DataSize) + { + std::string counter = std::to_string(recordCounter++); + std::string record = RandomString(static_cast(RandomInt(1, 3000))); + csvData += counter + "," + record + "\n"; + jsonData += "{\"_1\":\"" + counter + "\",\"_2\":\"" + record + "\"}\n"; + } + + client.UploadFrom(reinterpret_cast(csvData.data()), csvData.size()); + + Files::DataLake::QueryFileOptions queryOptions; + queryOptions.InputTextConfiguration + = Files::DataLake::FileQueryInputTextOptions::CreateCsvTextOptions(); + queryOptions.OutputTextConfiguration + = Files::DataLake::FileQueryOutputTextOptions::CreateJsonTextOptions(); + auto queryResponse = client.Query("SELECT * FROM BlobStorage;", queryOptions); + + size_t comparePos = 0; + std::vector readBuffer(4096); + while (true) + { + auto s = queryResponse.Value.BodyStream->Read(readBuffer.data(), readBuffer.size()); + if (s == 0) + { + break; + } + ASSERT_TRUE(comparePos + s <= jsonData.size()); + ASSERT_EQ( + std::string(readBuffer.begin(), readBuffer.begin() + s), jsonData.substr(comparePos, s)); + comparePos += s; + } + } + + TEST_F(DataLakeFileClientTest, QueryBlobAccessConditionLeaseId_LIVEONLY_) + { + auto const testName(GetTestName()); + auto client = m_fileSystemClient->GetFileClient(testName); + client.UploadFrom(nullptr, 0); + + Files::DataLake::DataLakeLeaseClient leaseClient( + client, Files::DataLake::DataLakeLeaseClient::CreateUniqueLeaseId()); + leaseClient.Acquire(Files::DataLake::DataLakeLeaseClient::InfiniteLeaseDuration); + + Files::DataLake::QueryFileOptions queryOptions; + queryOptions.AccessConditions.LeaseId + = Files::DataLake::DataLakeLeaseClient::CreateUniqueLeaseId(); + EXPECT_THROW(client.Query("SELECT * FROM BlobStorage;", queryOptions), StorageException); + + queryOptions.AccessConditions.LeaseId = leaseClient.GetLeaseId(); + EXPECT_NO_THROW(client.Query("SELECT * FROM BlobStorage;", queryOptions)); + } + + TEST_F(DataLakeFileClientTest, QueryBlobAccessConditionLastModifiedTime_LIVEONLY_) + { + auto const testName(GetTestName()); + auto client = m_fileSystemClient->GetFileClient(testName); + client.UploadFrom(nullptr, 0); + + auto lastModifiedTime = client.GetProperties().Value.LastModified; + auto timeBeforeStr = lastModifiedTime - std::chrono::seconds(2); + auto timeAfterStr = lastModifiedTime + std::chrono::seconds(2); + + Files::DataLake::QueryFileOptions queryOptions; + queryOptions.AccessConditions.IfModifiedSince = timeBeforeStr; + EXPECT_NO_THROW(client.Query("SELECT * FROM BlobStorage;", queryOptions)); + queryOptions.AccessConditions.IfModifiedSince = timeAfterStr; + EXPECT_THROW(client.Query("SELECT * FROM BlobStorage;", queryOptions), StorageException); + + queryOptions = Files::DataLake::QueryFileOptions(); + queryOptions.AccessConditions.IfUnmodifiedSince = timeBeforeStr; + EXPECT_THROW(client.Query("SELECT * FROM BlobStorage;", queryOptions), StorageException); + queryOptions.AccessConditions.IfUnmodifiedSince = timeAfterStr; + EXPECT_NO_THROW(client.Query("SELECT * FROM BlobStorage;", queryOptions)); + } + + TEST_F(DataLakeFileClientTest, QueryBlobAccessConditionETag_LIVEONLY_) + { + auto const testName(GetTestName()); + auto client = m_fileSystemClient->GetFileClient(testName); + client.UploadFrom(nullptr, 0); + + auto etag = client.GetProperties().Value.ETag; + + Files::DataLake::QueryFileOptions queryOptions; + queryOptions.AccessConditions.IfMatch = etag; + EXPECT_NO_THROW(client.Query("SELECT * FROM BlobStorage;", queryOptions)); + queryOptions.AccessConditions.IfMatch = DummyETag; + EXPECT_THROW(client.Query("SELECT * FROM BlobStorage;", queryOptions), StorageException); + + queryOptions = Files::DataLake::QueryFileOptions(); + queryOptions.AccessConditions.IfNoneMatch = DummyETag; + EXPECT_NO_THROW(client.Query("SELECT * FROM BlobStorage;", queryOptions)); + queryOptions.AccessConditions.IfNoneMatch = etag; + EXPECT_THROW(client.Query("SELECT * FROM BlobStorage;", queryOptions), StorageException); + } +}}} // namespace Azure::Storage::Test diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_system_client_test.cpp b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_system_client_test.cpp index 615e1096d1..5278d72e59 100644 --- a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_system_client_test.cpp +++ b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_system_client_test.cpp @@ -5,6 +5,7 @@ #include +#include #include #include @@ -289,6 +290,8 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_NE(result.end(), iter); EXPECT_EQ(iter->Name, name); EXPECT_EQ(iter->Name.substr(0U, m_directoryA.size()), m_directoryA); + EXPECT_TRUE(iter->CreatedOn.HasValue()); + EXPECT_FALSE(iter->ExpiresOn.HasValue()); } for (const auto& name : m_pathNameSetB) { @@ -299,6 +302,8 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_NE(result.end(), iter); EXPECT_EQ(iter->Name, name); EXPECT_EQ(iter->Name.substr(0U, m_directoryB.size()), m_directoryB); + EXPECT_TRUE(iter->CreatedOn.HasValue()); + EXPECT_FALSE(iter->ExpiresOn.HasValue()); } } { @@ -313,6 +318,8 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_NE(result.end(), iter); EXPECT_EQ(iter->Name, name); EXPECT_EQ(iter->Name.substr(0U, m_directoryA.size()), m_directoryA); + EXPECT_TRUE(iter->CreatedOn.HasValue()); + EXPECT_FALSE(iter->ExpiresOn.HasValue()); } for (const auto& name : m_pathNameSetB) { @@ -330,6 +337,23 @@ namespace Azure { namespace Storage { namespace Test { auto response = m_fileSystemClient->ListPaths(true, options); EXPECT_LE(2U, response.Paths.size()); } + { + // check expiry time + const std::string filename = GetTestNameLowerCase() + "check_expiry"; + auto client = m_fileSystemClient->GetFileClient(GetTestNameLowerCase() + "check_expiry"); + Files::DataLake::CreateFileOptions createOptions; + createOptions.ScheduleDeletionOptions.ExpiresOn = Azure::DateTime::Parse( + "Wed, 29 Sep 2100 09:53:03 GMT", Azure::DateTime::DateFormat::Rfc1123); + client.Create(createOptions); + + auto result = ListAllPaths(false); + auto iter = std::find_if( + result.begin(), result.end(), [&filename](const Files::DataLake::Models::PathItem& path) { + return path.Name == filename; + }); + EXPECT_TRUE(iter->ExpiresOn.HasValue()); + EXPECT_EQ(createOptions.ScheduleDeletionOptions.ExpiresOn.Value(), iter->ExpiresOn.Value()); + } } TEST_F(DataLakeFileSystemClientTest, UnencodedPathDirectoryFileNameWorks) @@ -397,6 +421,231 @@ namespace Azure { namespace Storage { namespace Test { } } + TEST_F(DataLakeFileSystemClientTest, CustomerProvidedKey_LIVEONLY_) + { + + auto getRandomCustomerProvidedKey = [&]() { + Files::DataLake::EncryptionKey key; + std::vector aes256Key; + aes256Key.resize(32); + RandomBuffer(&aes256Key[0], aes256Key.size()); + key.Key = Azure::Core::Convert::Base64Encode(aes256Key); + key.KeyHash = Azure::Core::Cryptography::_internal::Sha256Hash().Final( + aes256Key.data(), aes256Key.size()); + key.Algorithm = Blobs::Models::EncryptionAlgorithmType::Aes256; + return key; + }; + + const int32_t bufferSize = 1024; // 1KB data size + auto buffer = std::make_shared>(bufferSize, 'x'); + Azure::Core::IO::MemoryBodyStream bodyStream(buffer->data(), buffer->size()); + + auto customerProvidedKey + = std::make_shared(getRandomCustomerProvidedKey()); + Files::DataLake::DataLakeClientOptions options; + options.CustomerProvidedKey = *customerProvidedKey; + auto fileServiceClient = std::make_shared( + Files::DataLake::DataLakeServiceClient::CreateFromConnectionString( + AdlsGen2ConnectionString(), options)); + auto fileSystemClient = std::make_shared( + fileServiceClient->GetFileSystemClient(m_fileSystemName)); + + // fileSystem works + { + auto fileSystemClientWithoutEncryptionKey + = Azure::Storage::Files::DataLake::DataLakeFileSystemClient::CreateFromConnectionString( + AdlsGen2ConnectionString(), m_fileSystemName); + // Rename File + const std::string filename1 = GetTestName() + "file1"; + const std::string filename2 = GetTestName() + "file2"; + const std::string filename3 = GetTestName() + "file3"; + const std::string filename4 = GetTestName() + "file4"; + + auto oldFileClient = fileSystemClient->GetFileClient(filename1); + oldFileClient.Create(); + auto newFileClient = fileSystemClient->RenameFile(filename1, filename2).Value; + auto properties = std::make_shared( + newFileClient.GetProperties().Value); + EXPECT_EQ(customerProvidedKey->KeyHash, properties->EncryptionKeySha256.Value()); + auto newFileClientWithoutEncryptionKey + = Files::DataLake::DataLakeFileClient::CreateFromConnectionString( + AdlsGen2ConnectionString(), m_fileSystemName, filename2); + EXPECT_THROW(newFileClientWithoutEncryptionKey.GetProperties(), StorageException); + EXPECT_NO_THROW(fileSystemClientWithoutEncryptionKey.RenameFile(filename2, filename3)); + + // Rename Directory + const std::string testName(GetTestName()); + const std::string oldDirectoryName = testName + "dir1"; + const std::string newDirectoryName = testName + "dir2"; + const std::string newDirectoryName2 = testName + "dir3"; + + auto oldDirectoryClient = fileSystemClient->GetDirectoryClient(oldDirectoryName); + oldDirectoryClient.Create(); + oldDirectoryClient.GetFileClient(testName + "file3").Create(); + oldDirectoryClient.GetSubdirectoryClient(testName + "dir4").Create(); + + auto newDirectoryClient + = fileSystemClient->RenameDirectory(oldDirectoryName, newDirectoryName).Value; + properties = std::make_shared( + newDirectoryClient.GetProperties().Value); + EXPECT_TRUE(properties->EncryptionKeySha256.HasValue()); + EXPECT_EQ(customerProvidedKey->KeyHash, properties->EncryptionKeySha256.Value()); + auto newDirectoryClientWithoutEncryptionKey + = Files::DataLake::DataLakeDirectoryClient::CreateFromConnectionString( + AdlsGen2ConnectionString(), m_fileSystemName, newDirectoryName); + EXPECT_THROW(newDirectoryClientWithoutEncryptionKey.GetProperties(), StorageException); + EXPECT_NO_THROW(fileSystemClientWithoutEncryptionKey.RenameDirectory( + newDirectoryName, newDirectoryName2)); + + auto fileSystemClientWithEncryptionKey + = Azure::Storage::Files::DataLake::DataLakeFileSystemClient::CreateFromConnectionString( + AdlsGen2ConnectionString(), m_fileSystemName, options); + auto created = std::make_shared( + fileSystemClientWithEncryptionKey.GetFileClient(filename4).Create().Value); + EXPECT_TRUE(created->EncryptionKeySha256.HasValue()); + EXPECT_EQ(customerProvidedKey->KeyHash, created->EncryptionKeySha256.Value()); + } + + // path works + { + const std::string pathName = "path"; + const std::string pathName2 = "path2"; + + auto pathClient = Files::DataLake::DataLakePathClient::CreateFromConnectionString( + AdlsGen2ConnectionString(), m_fileSystemName, pathName, options); + EXPECT_NO_THROW(pathClient.Create(Files::DataLake::Models::PathResourceType::File)); + EXPECT_NO_THROW(pathClient.SetMetadata(GetMetadata())); + auto properties = std::make_shared( + pathClient.GetProperties().Value); + EXPECT_TRUE(properties->EncryptionKeySha256.HasValue()); + EXPECT_EQ(customerProvidedKey->KeyHash, properties->EncryptionKeySha256.Value()); + auto pathClientWithoutEncryptionKey + = Files::DataLake::DataLakePathClient::CreateFromConnectionString( + AdlsGen2ConnectionString(), m_fileSystemName, pathName); + EXPECT_THROW(pathClientWithoutEncryptionKey.SetMetadata(GetMetadata()), StorageException); + EXPECT_THROW(pathClientWithoutEncryptionKey.GetProperties(), StorageException); + EXPECT_NO_THROW(pathClientWithoutEncryptionKey.GetAccessControlList()); + EXPECT_NO_THROW(pathClientWithoutEncryptionKey.SetHttpHeaders( + Files::DataLake::Models::PathHttpHeaders())); + EXPECT_NO_THROW(pathClientWithoutEncryptionKey.SetPermissions("rwxrw-rw-")); + + auto pathClientWithEncryptionKey + = Files::DataLake::DataLakePathClient::CreateFromConnectionString( + AdlsGen2ConnectionString(), m_fileSystemName, pathName2, options); + auto created + = pathClientWithEncryptionKey.Create(Files::DataLake::Models::PathResourceType::File) + .Value; + EXPECT_TRUE(created.EncryptionKeySha256.HasValue()); + EXPECT_EQ(customerProvidedKey->KeyHash, created.EncryptionKeySha256.Value()); + } + + // file works + { + const std::string fileName = "file"; + const std::string fileName2 = "file2"; + auto fileClient = fileSystemClient->GetFileClient(fileName); + auto fileClientWithoutEncryptionKey + = Files::DataLake::DataLakeFileClient::CreateFromConnectionString( + AdlsGen2ConnectionString(), m_fileSystemName, fileName); + // upload test + EXPECT_NO_THROW(fileClient.Create()); + EXPECT_NO_THROW(fileClient.UploadFrom(buffer->data(), bufferSize)); + auto result = fileClient.Download(); + auto downloaded = std::make_shared>(ReadBodyStream(result.Value.Body)); + EXPECT_EQ(*buffer, *downloaded); + EXPECT_NO_THROW(fileClient.Delete()); + // append test + EXPECT_NO_THROW(fileClient.Create()); + bodyStream.Rewind(); + EXPECT_NO_THROW(fileClient.Append(bodyStream, 0)); + bodyStream.Rewind(); + EXPECT_THROW(fileClientWithoutEncryptionKey.Append(bodyStream, bufferSize), StorageException); + EXPECT_NO_THROW(fileClient.Flush(bufferSize)); + result = fileClient.Download(); + downloaded = std::make_shared>(ReadBodyStream(result.Value.Body)); + EXPECT_EQ(*buffer, *downloaded); + EXPECT_NO_THROW(fileClient.SetMetadata(GetMetadata())); + auto properties = std::make_shared( + fileClient.GetProperties().Value); + EXPECT_TRUE(properties->EncryptionKeySha256.HasValue()); + EXPECT_EQ(customerProvidedKey->KeyHash, properties->EncryptionKeySha256.Value()); + EXPECT_THROW(fileClientWithoutEncryptionKey.Flush(bufferSize), StorageException); + EXPECT_THROW(fileClientWithoutEncryptionKey.Download(), StorageException); + + auto fileClientWithEncryptionKey + = Files::DataLake::DataLakeFileClient::CreateFromConnectionString( + AdlsGen2ConnectionString(), m_fileSystemName, fileName2, options); + auto created = std::make_shared( + fileClientWithEncryptionKey.Create().Value); + EXPECT_TRUE(created->EncryptionKeySha256.HasValue()); + EXPECT_EQ(customerProvidedKey->KeyHash, created->EncryptionKeySha256.Value()); + } + // directory works + { + const std::string directoryName = "directory"; + const std::string directoryName2 = "directory2"; + const std::string subdirectoryName1 = "subdirectory1"; + const std::string subdirectoryName2 = "subdirectory2"; + const std::string subdirectoryName3 = "subdirectory3"; + const std::string fileName1 = "file1"; + const std::string fileName2 = "file2"; + const std::string fileName3 = "file3"; + auto directoryClient = fileSystemClient->GetDirectoryClient(directoryName); + auto directoryClientWithoutEncryptionKey + = Files::DataLake::DataLakeDirectoryClient::CreateFromConnectionString( + AdlsGen2ConnectionString(), m_fileSystemName, directoryName); + // create subdirectory/file + EXPECT_NO_THROW(directoryClient.Create()); + auto subdirectoryClient = directoryClient.GetSubdirectoryClient(subdirectoryName1); + EXPECT_NO_THROW(subdirectoryClient.Create()); + auto fileClient = directoryClient.GetFileClient(fileName1); + EXPECT_NO_THROW(fileClient.Create()); + auto subdirectoryProperties = std::make_shared( + subdirectoryClient.GetProperties().Value); + EXPECT_EQ(customerProvidedKey->KeyHash, subdirectoryProperties->EncryptionKeySha256.Value()); + auto fileProperties = fileClient.GetProperties(); + EXPECT_EQ(customerProvidedKey->KeyHash, fileProperties.Value.EncryptionKeySha256.Value()); + + // rename file + auto newFileClient + = directoryClient.RenameFile(fileName1, directoryName + "/" + fileName2).Value; + auto newFileProperties = std::make_shared( + newFileClient.GetProperties().Value); + EXPECT_EQ(customerProvidedKey->KeyHash, newFileProperties->EncryptionKeySha256.Value()); + auto newFileClientWithoutEncryptionKey + = Files::DataLake::DataLakeFileClient::CreateFromConnectionString( + AdlsGen2ConnectionString(), m_fileSystemName, directoryName + "/" + fileName2); + EXPECT_THROW(newFileClientWithoutEncryptionKey.GetProperties(), StorageException); + EXPECT_NO_THROW(directoryClientWithoutEncryptionKey.RenameFile( + fileName2, directoryName + "/" + fileName3)); + + auto newSubdirectoryClient + = directoryClient + .RenameSubdirectory(subdirectoryName1, directoryName + "/" + subdirectoryName2) + .Value; + auto newSubdirectoryProperties = std::make_shared( + newSubdirectoryClient.GetProperties().Value); + EXPECT_EQ( + customerProvidedKey->KeyHash, newSubdirectoryProperties->EncryptionKeySha256.Value()); + auto newsubdirectoryClientWithoutEncryptionKey + = Files::DataLake::DataLakeDirectoryClient::CreateFromConnectionString( + AdlsGen2ConnectionString(), + m_fileSystemName, + directoryName + "/" + subdirectoryName2); + EXPECT_THROW(newsubdirectoryClientWithoutEncryptionKey.GetProperties(), StorageException); + EXPECT_NO_THROW(directoryClientWithoutEncryptionKey.RenameSubdirectory( + subdirectoryName2, directoryName + "/" + subdirectoryName3)); + + auto directoryClientWithEncryptionKey + = Files::DataLake::DataLakeDirectoryClient::CreateFromConnectionString( + AdlsGen2ConnectionString(), m_fileSystemName, directoryName2, options); + auto created = std::make_shared( + directoryClientWithEncryptionKey.Create().Value); + EXPECT_TRUE(created->EncryptionKeySha256.HasValue()); + EXPECT_EQ(customerProvidedKey->KeyHash, created->EncryptionKeySha256.Value()); + } + } + TEST_F(DataLakeFileSystemClientTest, GetSetAccessPolicy_LIVEONLY_) { CHECK_SKIP_TEST(); @@ -595,4 +844,134 @@ namespace Azure { namespace Storage { namespace Test { m_fileSystemClient->GetDirectoryClient(destinationDirectoryName).GetProperties()); } + TEST_F(DataLakeFileSystemClientTest, DISABLED_ListDeletedPaths) + { + const std::string deletedFilename = GetTestNameLowerCase() + "_file_deleted"; + const std::string nonDeletedFilename = GetTestNameLowerCase() + "_file"; + const std::string deletedDirectoryName = GetTestNameLowerCase() + "_dir_deleted"; + const std::string nonDeletedDirectoryName = GetTestNameLowerCase() + "_dir"; + + auto deletedFileClient = m_fileSystemClient->GetFileClient(deletedFilename); + auto nonDeletedFileClient = m_fileSystemClient->GetFileClient(nonDeletedFilename); + auto deletedDirectoryClient = m_fileSystemClient->GetDirectoryClient(deletedDirectoryName); + auto nonDeletedDirectoryClient + = m_fileSystemClient->GetDirectoryClient(nonDeletedDirectoryName); + + deletedFileClient.Create(); + deletedFileClient.Delete(); + nonDeletedFileClient.Create(); + deletedDirectoryClient.Create(); + deletedDirectoryClient.DeleteEmpty(); + nonDeletedDirectoryClient.Create(); + + { + std::vector paths; + for (auto pageResult = m_fileSystemClient->ListDeletedPaths(); pageResult.HasPage(); + pageResult.MoveToNextPage()) + { + paths.insert(paths.end(), pageResult.DeletedPaths.begin(), pageResult.DeletedPaths.end()); + } + EXPECT_EQ(2, paths.size()); + EXPECT_EQ(deletedDirectoryName, paths[0].Name); + EXPECT_EQ(deletedFilename, paths[1].Name); + } + // List max result + { + Files::DataLake::ListDeletedPathsOptions options; + options.PageSizeHint = 1; + std::vector paths; + for (auto pageResult = m_fileSystemClient->ListDeletedPaths(options); pageResult.HasPage(); + pageResult.MoveToNextPage()) + { + paths.insert(paths.end(), pageResult.DeletedPaths.begin(), pageResult.DeletedPaths.end()); + EXPECT_LE(pageResult.DeletedPaths.size(), 1); + } + EXPECT_EQ(2, paths.size()); + } + // prefix works + { + const std::string directoryName = GetTestNameLowerCase() + "_prefix"; + const std::string filename = "file"; + + auto directoryClient = m_fileSystemClient->GetDirectoryClient(directoryName); + directoryClient.Create(); + auto fileClient = directoryClient.GetFileClient(filename); + fileClient.Create(); + fileClient.Delete(); + + Files::DataLake::ListDeletedPathsOptions options; + options.Prefix = directoryName; + std::vector paths; + for (auto pageResult = m_fileSystemClient->ListDeletedPaths(options); pageResult.HasPage(); + pageResult.MoveToNextPage()) + { + paths.insert(paths.end(), pageResult.DeletedPaths.begin(), pageResult.DeletedPaths.end()); + } + EXPECT_EQ(1, paths.size()); + EXPECT_EQ(directoryName + "/" + filename, paths[0].Name); + } + } + + TEST_F(DataLakeFileSystemClientTest, DISABLED_Undelete) + { + const std::string directoryName = GetTestNameLowerCase() + "_dir"; + const std::string subFileName = "sub_file"; + + auto directoryClient = m_fileSystemClient->GetDirectoryClient(directoryName); + directoryClient.Create(); + auto subFileClient = m_fileSystemClient->GetFileClient(directoryName + "/" + subFileName); + subFileClient.Create(); + Files::DataLake::Models::PathProperties properties = directoryClient.GetProperties().Value; + Files::DataLake::Models::PathProperties subFileProperties = subFileClient.GetProperties().Value; + + // recursive works + { + directoryClient.DeleteRecursive(); + + auto paths = m_fileSystemClient->ListDeletedPaths().DeletedPaths; + const std::string deletionId = paths[0].DeletionId; + + auto restoredClient = m_fileSystemClient->UndeletePath(directoryName, deletionId).Value; + + paths = m_fileSystemClient->ListDeletedPaths().DeletedPaths; + EXPECT_EQ(0, paths.size()); + Files::DataLake::Models::PathProperties restoredProperties; + EXPECT_NO_THROW(restoredProperties = restoredClient.GetProperties().Value); + EXPECT_TRUE(restoredProperties.IsDirectory); + EXPECT_EQ(properties.ETag, restoredProperties.ETag); + Files::DataLake::Models::PathProperties restoredSubFileProperties; + EXPECT_NO_THROW(restoredSubFileProperties = subFileClient.GetProperties().Value); + EXPECT_TRUE(!restoredSubFileProperties.IsDirectory); + EXPECT_EQ(subFileProperties.ETag, restoredSubFileProperties.ETag); + } + // not recursive works + { + subFileClient.Delete(); + directoryClient.DeleteEmpty(); + + auto paths = m_fileSystemClient->ListDeletedPaths().DeletedPaths; + std::string deletionId = paths[0].DeletionId; + + // restore directory + auto restoredClient = m_fileSystemClient->UndeletePath(directoryName, deletionId).Value; + paths = m_fileSystemClient->ListDeletedPaths().DeletedPaths; + EXPECT_EQ(1, paths.size()); // not restore subFile + Files::DataLake::Models::PathProperties restoredProperties; + EXPECT_NO_THROW(restoredProperties = restoredClient.GetProperties().Value); + EXPECT_TRUE(restoredProperties.IsDirectory); + EXPECT_EQ(properties.ETag, restoredProperties.ETag); + EXPECT_THROW(subFileClient.GetProperties(), StorageException); + + // restore file + deletionId = paths[0].DeletionId; + restoredClient + = m_fileSystemClient->UndeletePath(directoryName + "/" + subFileName, deletionId).Value; + paths = m_fileSystemClient->ListDeletedPaths().DeletedPaths; + EXPECT_EQ(0, paths.size()); + EXPECT_NO_THROW(restoredProperties = restoredClient.GetProperties().Value); + EXPECT_FALSE(restoredProperties.IsDirectory); + EXPECT_EQ(subFileProperties.ETag, restoredProperties.ETag); + } + } + }}} // namespace Azure::Storage::Test diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_path_client_test.cpp b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_path_client_test.cpp index fd434af7c1..efdb41e9e0 100644 --- a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_path_client_test.cpp +++ b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_path_client_test.cpp @@ -57,6 +57,87 @@ namespace Azure { namespace Storage { namespace Test { return result; } + TEST_F(DataLakePathClientTest, CreateWithOptions) + { + // owner&group + { + auto client = m_fileSystemClient->GetFileClient(GetTestNameLowerCase() + "owner_group"); + Files::DataLake::CreateFileOptions options; + options.Group = "$superuser"; + options.Owner = "$superuser"; + EXPECT_NO_THROW(client.Create(options)); + auto response = client.GetAccessControlList(); + EXPECT_EQ(options.Group.Value(), response.Value.Group); + EXPECT_EQ(options.Owner.Value(), response.Value.Owner); + } + // acl + { + auto client = m_fileSystemClient->GetFileClient(GetTestNameLowerCase() + "_acl"); + Files::DataLake::CreateFileOptions options; + auto acls = GetValidAcls(); + options.Acls = acls; + EXPECT_NO_THROW(client.Create(options)); + auto resultAcls = client.GetAccessControlList().Value.Acls; + EXPECT_EQ(resultAcls.size(), acls.size() + 1); // Always append mask::rwx + for (const auto& acl : acls) + { + auto iter = std::find_if( + resultAcls.begin(), + resultAcls.end(), + [&acl](const Files::DataLake::Models::Acl& targetAcl) { + return (targetAcl.Type == acl.Type) && (targetAcl.Id == acl.Id) + && (targetAcl.Scope == acl.Scope); + }); + EXPECT_NE(iter, resultAcls.end()); + EXPECT_EQ(iter->Permissions, acl.Permissions); + } + } + // lease + { + auto client = m_fileSystemClient->GetFileClient(GetTestNameLowerCase() + "_lease"); + Files::DataLake::CreateFileOptions options; + options.LeaseId = Files::DataLake::DataLakeLeaseClient::CreateUniqueLeaseId(); + options.LeaseDuration = std::chrono::seconds(20); + EXPECT_NO_THROW(client.Create(options)); + auto response = client.GetProperties(); + EXPECT_TRUE(response.Value.LeaseStatus.HasValue()); + EXPECT_EQ(Files::DataLake::Models::LeaseStatus::Locked, response.Value.LeaseStatus.Value()); + EXPECT_TRUE(response.Value.LeaseState.HasValue()); + EXPECT_EQ(Files::DataLake::Models::LeaseState::Leased, response.Value.LeaseState.Value()); + EXPECT_TRUE(response.Value.LeaseDuration.HasValue()); + EXPECT_EQ( + Files::DataLake::Models::LeaseDurationType::Fixed, response.Value.LeaseDuration.Value()); + } + // relative expiry + { + auto client = m_fileSystemClient->GetFileClient(GetTestNameLowerCase() + "_relative_expiry"); + Files::DataLake::CreateFileOptions options; + options.ScheduleDeletionOptions.TimeToExpire = std::chrono::hours(1); + EXPECT_NO_THROW(client.Create(options)); + auto response = client.GetProperties(); + DateTime leftExpiryTime = response.Value.CreatedOn + + options.ScheduleDeletionOptions.TimeToExpire.Value() - std::chrono::seconds(5); + DateTime rightExpiryTime = response.Value.CreatedOn + + options.ScheduleDeletionOptions.TimeToExpire.Value() + std::chrono::seconds(5); + EXPECT_TRUE(response.Value.ExpiresOn.HasValue()); + EXPECT_TRUE( + response.Value.ExpiresOn.Value() > leftExpiryTime + && response.Value.ExpiresOn.Value() < rightExpiryTime); + } + // absolute expiry + { + auto client = m_fileSystemClient->GetFileClient(GetTestNameLowerCase() + "_absolute_expiry"); + Files::DataLake::CreateFileOptions options; + options.ScheduleDeletionOptions.ExpiresOn = Azure::DateTime::Parse( + "Wed, 29 Sep 2100 09:53:03 GMT", Azure::DateTime::DateFormat::Rfc1123); + EXPECT_NO_THROW(client.Create(options)); + auto response = client.GetProperties(); + EXPECT_TRUE(response.Value.ExpiresOn.HasValue()); + EXPECT_EQ( + options.ScheduleDeletionOptions.ExpiresOn.Value(), response.Value.ExpiresOn.Value()); + } + } + TEST_F(DataLakePathClientTest, PathMetadata) { auto metadata1 = GetMetadata(); diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_sas_test.cpp b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_sas_test.cpp index 4615159f45..75c25f8404 100644 --- a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_sas_test.cpp +++ b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_sas_test.cpp @@ -441,6 +441,39 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_EQ(p.Value.HttpHeaders.CacheControl, headers.CacheControl); EXPECT_EQ(p.Value.HttpHeaders.ContentEncoding, headers.ContentEncoding); } + + // Encryption scope + const auto encryptionScope = GetTestEncryptionScope(); + { + auto sasBuilderWithEncryptionScope = fileSasBuilder; + sasBuilderWithEncryptionScope.EncryptionScope = encryptionScope; + sasBuilderWithEncryptionScope.SetPermissions(Sas::DataLakeSasPermissions::All); + auto fileClientEncryptionScopeSas = Files::DataLake::DataLakeFileClient( + fileUrl + sasBuilderWithEncryptionScope.GenerateSasToken(*keyCredential)); + fileClientEncryptionScopeSas.Create(); + auto pRawResponse = fileClientEncryptionScopeSas.GetProperties().RawResponse; + ASSERT_TRUE(pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0); + EXPECT_EQ(pRawResponse->GetHeaders().at("x-ms-encryption-scope"), encryptionScope); + + fileClientEncryptionScopeSas = Files::DataLake::DataLakeFileClient( + fileUrl + sasBuilderWithEncryptionScope.GenerateSasToken(userDelegationKey, accountName)); + fileClientEncryptionScopeSas.Create(); + pRawResponse = fileClientEncryptionScopeSas.GetProperties().RawResponse; + ASSERT_TRUE(pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0); + EXPECT_EQ(pRawResponse->GetHeaders().at("x-ms-encryption-scope"), encryptionScope); + } + { + auto sasBuilderWithEncryptionScope = directorySasBuilder; + sasBuilderWithEncryptionScope.EncryptionScope = encryptionScope; + sasBuilderWithEncryptionScope.SetPermissions(Sas::DataLakeSasPermissions::All); + auto directoryClientEncryptionScopeSas = Files::DataLake::DataLakeDirectoryClient( + directory1Url + + sasBuilderWithEncryptionScope.GenerateSasToken(userDelegationKey, accountName)); + directoryClientEncryptionScopeSas.Create(); + auto pRawResponse = directoryClientEncryptionScopeSas.GetProperties().RawResponse; + ASSERT_TRUE(pRawResponse->GetHeaders().count("x-ms-encryption-scope") != 0); + EXPECT_EQ(pRawResponse->GetHeaders().at("x-ms-encryption-scope"), encryptionScope); + } } }}} // namespace Azure::Storage::Test diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_service_client_test.cpp b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_service_client_test.cpp index 2d8c7b4846..8eb1ada010 100644 --- a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_service_client_test.cpp +++ b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_service_client_test.cpp @@ -6,6 +6,66 @@ #include #include +namespace Azure { namespace Storage { namespace Blobs { namespace Models { + + bool operator==(const RetentionPolicy& lhs, const RetentionPolicy& rhs) + { + if (lhs.IsEnabled != rhs.IsEnabled) + { + return false; + } + if (lhs.Days.HasValue() != rhs.Days.HasValue()) + { + return false; + } + if (lhs.Days.HasValue() && rhs.Days.HasValue() && lhs.Days.Value() != rhs.Days.Value()) + { + return false; + } + return true; + } + + bool operator==(const CorsRule& lhs, const CorsRule& rhs) + { + return lhs.AllowedHeaders == rhs.AllowedHeaders && lhs.AllowedMethods == rhs.AllowedMethods + && lhs.AllowedOrigins == rhs.AllowedOrigins && lhs.ExposedHeaders == rhs.ExposedHeaders + && lhs.MaxAgeInSeconds == rhs.MaxAgeInSeconds; + } + + bool operator==(const StaticWebsite& lhs, const StaticWebsite& rhs) + { + if (lhs.IsEnabled != rhs.IsEnabled) + { + return false; + } + if (lhs.DefaultIndexDocumentPath.HasValue() != rhs.DefaultIndexDocumentPath.HasValue()) + { + return false; + } + if (lhs.DefaultIndexDocumentPath.HasValue() && rhs.DefaultIndexDocumentPath.HasValue() + && lhs.DefaultIndexDocumentPath.Value() != rhs.DefaultIndexDocumentPath.Value()) + { + return false; + } + if (lhs.DefaultIndexDocumentPath.HasValue() != rhs.DefaultIndexDocumentPath.HasValue()) + { + return false; + } + if (lhs.ErrorDocument404Path.HasValue() && rhs.ErrorDocument404Path.HasValue() + && lhs.ErrorDocument404Path.Value() != rhs.ErrorDocument404Path.Value()) + { + return false; + } + if (lhs.IndexDocument.HasValue() && rhs.IndexDocument.HasValue() + && lhs.IndexDocument.Value() != rhs.IndexDocument.Value()) + { + return false; + } + return true; + } + +}}}} // namespace Azure::Storage::Blobs::Models + namespace Azure { namespace Storage { namespace Test { const size_t FileSystemTestSize = 5; @@ -126,6 +186,27 @@ namespace Azure { namespace Storage { namespace Test { } } + TEST_F(DataLakeServiceClientTest, DISABLED_ListSystemFileSystems) + { + // Disabled temporarily because the test account on the pipeline hasn't system fileSystems. + // List system type FileSystems + Files::DataLake::ListFileSystemsOptions options; + options.Include = Files::DataLake::Models::ListFileSystemsIncludeFlags::System; + std::vector fileSystems; + for (auto pageResult = m_dataLakeServiceClient->ListFileSystems(options); pageResult.HasPage(); + pageResult.MoveToNextPage()) + { + for (const auto& c : pageResult.FileSystems) + { + if (c.Name[0] == '$') + { + fileSystems.push_back(c.Name); + } + } + } + EXPECT_FALSE(fileSystems.empty()); + } + TEST_F(DataLakeServiceClientTest, AnonymousConstructorsWorks_LIVEONLY_) { CHECK_SKIP_TEST(); @@ -153,4 +234,156 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_NO_THROW(datalakeServiceClient.ListFileSystems()); } + TEST_F(DataLakeServiceClientTest, GetProperties) + { + + auto ret = m_dataLakeServiceClient->GetProperties(); + auto properties = ret.Value; + auto logging = properties.Logging; + EXPECT_FALSE(logging.Version.empty()); + if (logging.RetentionPolicy.IsEnabled) + { + EXPECT_TRUE(logging.RetentionPolicy.Days.HasValue()); + } + auto hourMetrics = properties.HourMetrics; + if (hourMetrics.IsEnabled) + { + EXPECT_FALSE(hourMetrics.Version.empty()); + if (hourMetrics.RetentionPolicy.IsEnabled) + { + EXPECT_TRUE(hourMetrics.RetentionPolicy.Days.HasValue()); + } + } + auto minuteMetrics = properties.HourMetrics; + if (minuteMetrics.IsEnabled) + { + EXPECT_FALSE(minuteMetrics.Version.empty()); + if (minuteMetrics.RetentionPolicy.IsEnabled) + { + EXPECT_TRUE(minuteMetrics.RetentionPolicy.Days.HasValue()); + } + } + auto deleteRetentionPolicy = properties.DeleteRetentionPolicy; + if (deleteRetentionPolicy.IsEnabled) + { + EXPECT_TRUE(deleteRetentionPolicy.Days.HasValue()); + } + } + + TEST_F(DataLakeServiceClientTest, SetProperties) + { + + auto getServicePropertiesResult = m_dataLakeServiceClient->GetProperties().Value; + Files::DataLake::Models::DataLakeServiceProperties properties; + properties.Logging = getServicePropertiesResult.Logging; + properties.HourMetrics = getServicePropertiesResult.HourMetrics; + properties.MinuteMetrics = getServicePropertiesResult.MinuteMetrics; + properties.Cors = getServicePropertiesResult.Cors; + properties.DefaultServiceVersion = getServicePropertiesResult.DefaultServiceVersion; + properties.DeleteRetentionPolicy = getServicePropertiesResult.DeleteRetentionPolicy; + properties.StaticWebsite = getServicePropertiesResult.StaticWebsite; + + auto originalProperties = properties; + + properties.Logging.Delete = !properties.Logging.Delete; + properties.Logging.Read = !properties.Logging.Read; + properties.Logging.Write = !properties.Logging.Write; + properties.Logging.RetentionPolicy.IsEnabled = true; + properties.Logging.RetentionPolicy.Days = 3; + + properties.HourMetrics.IsEnabled = true; + properties.HourMetrics.RetentionPolicy.IsEnabled = true; + properties.HourMetrics.RetentionPolicy.Days = 4; + properties.HourMetrics.IncludeApis = true; + + properties.MinuteMetrics.IsEnabled = true; + properties.MinuteMetrics.RetentionPolicy.IsEnabled = true; + properties.MinuteMetrics.RetentionPolicy.Days = 4; + properties.MinuteMetrics.IncludeApis = true; + + properties.DefaultServiceVersion = Files::DataLake::_detail::ApiVersion; + + properties.StaticWebsite.IsEnabled = true; + properties.StaticWebsite.IndexDocument = "index.html"; + properties.StaticWebsite.ErrorDocument404Path = "404.html"; + properties.StaticWebsite.DefaultIndexDocumentPath.Reset(); + + Files::DataLake::Models::CorsRule corsRule; + corsRule.AllowedOrigins = "http://www.example1.com"; + corsRule.AllowedMethods = "GET,PUT"; + corsRule.AllowedHeaders = "x-ms-header1,x-ms-header2"; + corsRule.ExposedHeaders = "x-ms-header3"; + corsRule.MaxAgeInSeconds = 10; + properties.Cors.emplace_back(corsRule); + + corsRule.AllowedOrigins = "http://www.example2.com"; + corsRule.AllowedMethods = "DELETE"; + corsRule.AllowedHeaders = "x-ms-header1"; + corsRule.ExposedHeaders = "x-ms-header2,x-ms-header3"; + corsRule.MaxAgeInSeconds = 20; + properties.Cors.emplace_back(corsRule); + + properties.DeleteRetentionPolicy.IsEnabled = true; + properties.DeleteRetentionPolicy.Days = 7; + + EXPECT_NO_THROW(m_dataLakeServiceClient->SetProperties(properties)); + + // It takes some time before the new properties comes into effect. + using namespace std::chrono_literals; + TestSleep(10s); + auto downloadedProperties = m_dataLakeServiceClient->GetProperties().Value; + EXPECT_EQ(downloadedProperties.Logging.Version, properties.Logging.Version); + EXPECT_EQ(downloadedProperties.Logging.Delete, properties.Logging.Delete); + EXPECT_EQ(downloadedProperties.Logging.Read, properties.Logging.Read); + EXPECT_EQ(downloadedProperties.Logging.Write, properties.Logging.Write); + EXPECT_EQ(downloadedProperties.Logging.RetentionPolicy, properties.Logging.RetentionPolicy); + + EXPECT_EQ(downloadedProperties.HourMetrics.Version, properties.HourMetrics.Version); + EXPECT_EQ(downloadedProperties.HourMetrics.IsEnabled, properties.HourMetrics.IsEnabled); + EXPECT_EQ( + downloadedProperties.HourMetrics.IncludeApis.HasValue(), + properties.HourMetrics.IncludeApis.HasValue()); + if (downloadedProperties.HourMetrics.IncludeApis.HasValue() + == properties.HourMetrics.IncludeApis.HasValue()) + { + EXPECT_EQ( + downloadedProperties.HourMetrics.IncludeApis.Value(), + properties.HourMetrics.IncludeApis.Value()); + } + EXPECT_EQ( + downloadedProperties.HourMetrics.RetentionPolicy, properties.HourMetrics.RetentionPolicy); + + EXPECT_EQ(downloadedProperties.MinuteMetrics.Version, properties.MinuteMetrics.Version); + EXPECT_EQ(downloadedProperties.MinuteMetrics.IsEnabled, properties.MinuteMetrics.IsEnabled); + EXPECT_EQ( + downloadedProperties.MinuteMetrics.IncludeApis.HasValue(), + properties.MinuteMetrics.IncludeApis.HasValue()); + if (downloadedProperties.MinuteMetrics.IncludeApis.HasValue() + == properties.MinuteMetrics.IncludeApis.HasValue()) + { + EXPECT_EQ( + downloadedProperties.MinuteMetrics.IncludeApis.Value(), + properties.MinuteMetrics.IncludeApis.Value()); + } + EXPECT_EQ( + downloadedProperties.MinuteMetrics.RetentionPolicy, + properties.MinuteMetrics.RetentionPolicy); + + EXPECT_EQ( + downloadedProperties.DefaultServiceVersion.HasValue(), + properties.DefaultServiceVersion.HasValue()); + if (downloadedProperties.DefaultServiceVersion.HasValue()) + { + EXPECT_EQ( + downloadedProperties.DefaultServiceVersion.Value(), + properties.DefaultServiceVersion.Value()); + } + EXPECT_EQ(downloadedProperties.Cors, properties.Cors); + + EXPECT_EQ(downloadedProperties.StaticWebsite, properties.StaticWebsite); + + EXPECT_EQ(downloadedProperties.DeleteRetentionPolicy, properties.DeleteRetentionPolicy); + + auto res = m_dataLakeServiceClient->SetProperties(originalProperties); + } }}} // namespace Azure::Storage::Test diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeFileClientTest.AppendFileWithFlush.json b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeFileClientTest.AppendFileWithFlush.json new file mode 100644 index 0000000000..d002712baa --- /dev/null +++ b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeFileClientTest.AppendFileWithFlush.json @@ -0,0 +1,321 @@ +{ + "networkCallRecords": [ + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "589a9f12-0965-4803-646e-270620ce1db2", + "x-ms-version": "2021-04-10" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Fri, 23 Sep 2022 04:49:44 GMT", + "etag": "\"0x8DA9D1F08D9DF38\"", + "last-modified": "Fri, 23 Sep 2022 04:49:44 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "589a9f12-0965-4803-646e-270620ce1db2", + "x-ms-request-id": "82088cba-b01e-0077-1107-cf073b000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefileclienttestappendfilewithflush?restype=container" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "3e908b63-8bfa-4038-6608-e9c7bffacdb7", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Fri, 23 Sep 2022 04:49:45 GMT", + "etag": "\"0x8DA9D1F09AC46D3\"", + "last-modified": "Fri, 23 Sep 2022 04:49:45 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "3e908b63-8bfa-4038-6608-e9c7bffacdb7", + "x-ms-request-id": "1306a2f5-101f-008a-4c07-cf891e000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefileclienttestappendfilewithflush/datalakefileclienttestappendfilewithflush?resource=file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "e61cd103-cc06-4583-62aa-5fc6489f6b59", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Fri, 23 Sep 2022 04:49:46 GMT", + "etag": "\"0x8DA9D1F09DCBE9A\"", + "last-modified": "Fri, 23 Sep 2022 04:49:46 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "e61cd103-cc06-4583-62aa-5fc6489f6b59", + "x-ms-request-id": "1306a34a-101f-008a-2007-cf891e000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefileclienttestappendfilewithflush/appendfilewithflush_flush_true?resource=file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "15780334-3cf6-442d-5482-655fe1c6a124", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "0", + "content-type": "application/octet-stream", + "date": "Fri, 23 Sep 2022 04:49:45 GMT", + "etag": "\"0x8DA9D1F09DCBE9A\"", + "last-modified": "Fri, 23 Sep 2022 04:49:46 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "15780334-3cf6-442d-5482-655fe1c6a124", + "x-ms-creation-time": "Fri, 23 Sep 2022 04:49:46 GMT", + "x-ms-group": "$superuser", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-owner": "$superuser", + "x-ms-permissions": "rw-r-----", + "x-ms-request-id": "82089521-b01e-0077-3b07-cf073b000000", + "x-ms-resource-type": "file", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefileclienttestappendfilewithflush/appendfilewithflush_flush_true" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "4f31d3bb-e6d5-4228-407b-edd51ad82213", + "x-ms-version": "2021-06-08" + }, + "Method": "PATCH", + "Response": { + "BODY": "", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202", + "content-length": "0", + "date": "Fri, 23 Sep 2022 04:49:46 GMT", + "etag": "\"0x8DA9D1F0A3AE267\"", + "last-modified": "Fri, 23 Sep 2022 04:49:46 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "4f31d3bb-e6d5-4228-407b-edd51ad82213", + "x-ms-request-id": "1306a3a5-101f-008a-7b07-cf891e000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefileclienttestappendfilewithflush/appendfilewithflush_flush_true?action=append&flush=true&position=0" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "bbc64830-132f-4f9b-7d3e-1f3bedb0e340", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "4096", + "content-type": "application/octet-stream", + "date": "Fri, 23 Sep 2022 04:49:46 GMT", + "etag": "\"0x8DA9D1F0A3AE267\"", + "last-modified": "Fri, 23 Sep 2022 04:49:46 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "bbc64830-132f-4f9b-7d3e-1f3bedb0e340", + "x-ms-creation-time": "Fri, 23 Sep 2022 04:49:46 GMT", + "x-ms-group": "$superuser", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-owner": "$superuser", + "x-ms-permissions": "rw-r-----", + "x-ms-request-id": "820896e4-b01e-0077-6607-cf073b000000", + "x-ms-resource-type": "file", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefileclienttestappendfilewithflush/appendfilewithflush_flush_true" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "3be6d8cf-026b-4e1c-7201-c48d16b91314", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Fri, 23 Sep 2022 04:49:47 GMT", + "etag": "\"0x8DA9D1F0A97A92A\"", + "last-modified": "Fri, 23 Sep 2022 04:49:47 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "3be6d8cf-026b-4e1c-7201-c48d16b91314", + "x-ms-request-id": "1306a3d9-101f-008a-2f07-cf891e000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefileclienttestappendfilewithflush/appendfilewithflush_flush_false?resource=file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "0c923618-0455-4b10-625f-9bf0496e952d", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "0", + "content-type": "application/octet-stream", + "date": "Fri, 23 Sep 2022 04:49:47 GMT", + "etag": "\"0x8DA9D1F0A97A92A\"", + "last-modified": "Fri, 23 Sep 2022 04:49:47 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "0c923618-0455-4b10-625f-9bf0496e952d", + "x-ms-creation-time": "Fri, 23 Sep 2022 04:49:47 GMT", + "x-ms-group": "$superuser", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-owner": "$superuser", + "x-ms-permissions": "rw-r-----", + "x-ms-request-id": "8208990c-b01e-0077-6307-cf073b000000", + "x-ms-resource-type": "file", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefileclienttestappendfilewithflush/appendfilewithflush_flush_false" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "feaa3dc2-ef0f-45b2-7f22-32491891657f", + "x-ms-version": "2021-06-08" + }, + "Method": "PATCH", + "Response": { + "BODY": "", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202", + "content-length": "0", + "date": "Fri, 23 Sep 2022 04:49:47 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "feaa3dc2-ef0f-45b2-7f22-32491891657f", + "x-ms-request-id": "1306a41b-101f-008a-6e07-cf891e000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefileclienttestappendfilewithflush/appendfilewithflush_flush_false?action=append&flush=false&position=0" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "4bb822e2-f6d1-496f-582b-682a1c30b14a", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "0", + "content-type": "application/octet-stream", + "date": "Fri, 23 Sep 2022 04:49:47 GMT", + "etag": "\"0x8DA9D1F0A97A92A\"", + "last-modified": "Fri, 23 Sep 2022 04:49:47 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "4bb822e2-f6d1-496f-582b-682a1c30b14a", + "x-ms-creation-time": "Fri, 23 Sep 2022 04:49:47 GMT", + "x-ms-group": "$superuser", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-owner": "$superuser", + "x-ms-permissions": "rw-r-----", + "x-ms-request-id": "82089b11-b01e-0077-4e07-cf073b000000", + "x-ms-resource-type": "file", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefileclienttestappendfilewithflush/appendfilewithflush_flush_false" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "fb2ca437-05e9-4d64-660a-a843060785e0", + "x-ms-version": "2021-06-08" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-length": "0", + "date": "Fri, 23 Sep 2022 04:49:48 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "fb2ca437-05e9-4d64-660a-a843060785e0", + "x-ms-delete-type-permanent": "false", + "x-ms-deletion-id": "133083821885911938", + "x-ms-request-id": "1306a44f-101f-008a-2207-cf891e000000", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefileclienttestappendfilewithflush/datalakefileclienttestappendfilewithflush" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "73126a8f-adad-40d5-69f6-6bc16adf36af", + "x-ms-version": "2021-04-10" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202", + "content-length": "0", + "date": "Fri, 23 Sep 2022 04:49:48 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "73126a8f-adad-40d5-69f6-6bc16adf36af", + "x-ms-request-id": "82089dfb-b01e-0077-1007-cf073b000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefileclienttestappendfilewithflush?restype=container" + } + ] +} diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeFileSystemClientTest.ListDeletedPaths.json b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeFileSystemClientTest.ListDeletedPaths.json new file mode 100644 index 0000000000..b0764dbbd4 --- /dev/null +++ b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeFileSystemClientTest.ListDeletedPaths.json @@ -0,0 +1,334 @@ +{ + "networkCallRecords": [ + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "4852b7d9-3925-4652-42b3-dae71445ca10", + "x-ms-version": "2021-04-10" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:07 GMT", + "etag": "\"0x8DAA0348687215F\"", + "last-modified": "Tue, 27 Sep 2022 03:01:08 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "4852b7d9-3925-4652-42b3-dae71445ca10", + "x-ms-request-id": "3803bf63-901e-0084-381d-d2a0ae000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestlistdeletedpaths?restype=container" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "9597f3b2-8051-4fae-7a42-af04abd14058", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:09 GMT", + "etag": "\"0x8DAA03487668E60\"", + "last-modified": "Tue, 27 Sep 2022 03:01:09 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "9597f3b2-8051-4fae-7a42-af04abd14058", + "x-ms-request-id": "4c4b6f94-201f-0028-7d1d-d2b307000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistdeletedpaths/listdeletedpaths_file_deleted?resource=file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "283a24d9-c672-4a35-469d-38c6ddff5a3a", + "x-ms-version": "2021-06-08" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:10 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "283a24d9-c672-4a35-469d-38c6ddff5a3a", + "x-ms-delete-type-permanent": "false", + "x-ms-deletion-id": "133087212699969504", + "x-ms-request-id": "4c4b6faf-201f-0028-181d-d2b307000000", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistdeletedpaths/listdeletedpaths_file_deleted" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "fd92820d-a84c-4005-553c-236f35238574", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:10 GMT", + "etag": "\"0x8DAA03487DB1A28\"", + "last-modified": "Tue, 27 Sep 2022 03:01:10 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "fd92820d-a84c-4005-553c-236f35238574", + "x-ms-request-id": "4c4b6fd9-201f-0028-421d-d2b307000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistdeletedpaths/listdeletedpaths_file?resource=file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "98d837bb-2268-465e-5f0d-dd46d60a6ee6", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:10 GMT", + "etag": "\"0x8DAA0348811B4A5\"", + "last-modified": "Tue, 27 Sep 2022 03:01:10 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "98d837bb-2268-465e-5f0d-dd46d60a6ee6", + "x-ms-request-id": "4c4b6ffb-201f-0028-631d-d2b307000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistdeletedpaths/listdeletedpaths_dir_deleted?resource=directory" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "3b879536-f06b-4e70-4d1f-fa955c686651", + "x-ms-version": "2021-06-08" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:11 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "3b879536-f06b-4e70-4d1f-fa955c686651", + "x-ms-delete-type-permanent": "false", + "x-ms-deletion-id": "133087212712013186", + "x-ms-request-id": "4c4b7029-201f-0028-111d-d2b307000000", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistdeletedpaths/listdeletedpaths_dir_deleted?recursive=false" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "b1485ff3-9018-4e1d-7612-d7c6361391a2", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:11 GMT", + "etag": "\"0x8DAA03488877376\"", + "last-modified": "Tue, 27 Sep 2022 03:01:11 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "b1485ff3-9018-4e1d-7612-d7c6361391a2", + "x-ms-request-id": "4c4b704a-201f-0028-321d-d2b307000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistdeletedpaths/listdeletedpaths_dir?resource=directory" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "01922a3c-dfe2-444c-4ebe-35b4180305dd", + "x-ms-version": "2021-04-10" + }, + "Method": "GET", + "Response": { + "BODY": "listdeletedpaths_dir_deleted133087212712013186trueTue, 27 Sep 2022 03:01:10 GMTTue, 27 Sep 2022 03:01:10 GMTTue, 04 Oct 2022 03:01:11 GMT0x8DAA0348811B4A5directory0application/octet-streamAAAAAAAAAAA=BlockBlobHottruetrueTue, 27 Sep 2022 03:01:11 GMT6listdeletedpaths_file_deleted133087212699969504trueTue, 27 Sep 2022 03:01:09 GMTTue, 27 Sep 2022 03:01:09 GMTTue, 04 Oct 2022 03:01:09 GMT0x8DAA03487668E60file0application/octet-streamAAAAAAAAAAA=BlockBlobHottruetrueTue, 27 Sep 2022 03:01:09 GMT6", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-type": "application/xml", + "date": "Tue, 27 Sep 2022 03:01:11 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "01922a3c-dfe2-444c-4ebe-35b4180305dd", + "x-ms-request-id": "3803c98a-901e-0084-781d-d2a0ae000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestlistdeletedpaths?comp=list&restype=container&showonly=deleted" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "a4a99895-6c61-4928-6900-ab38c0040236", + "x-ms-version": "2021-04-10" + }, + "Method": "GET", + "Response": { + "BODY": "1listdeletedpaths_dir_deleted133087212712013186trueTue, 27 Sep 2022 03:01:10 GMTTue, 27 Sep 2022 03:01:10 GMTTue, 04 Oct 2022 03:01:11 GMT0x8DAA0348811B4A5directory0application/octet-streamAAAAAAAAAAA=BlockBlobHottruetrueTue, 27 Sep 2022 03:01:11 GMT62!384!MDAwMjQ0IVZCYjYrSnordTlTSjVQd0JHS2NCR0tFQkwzcGphR0Z1WjJSaGRHRnNZV3RsQVRBeFJEaENNRGd6TlVGR016VkdOak12SkhSeVlYTm9MMlJoZEdGc1lXdGxabWxzWlhONWMzUmxiV05zYVdWdWRIUmxjM1JzYVhOMFpHVnNaWFJsWkhCaGRHaHpBVEF4UkRoRU1qRkVOalF4TUVKQ1F6VUNMMnhwYzNSa1pXeGxkR1ZrY0dGMGFITmZabWxzWlY5a1pXeGxkR1ZrQVRJd01qSXRNRGt0TWpkVU1ETTZNREU2TURrdU9UazJPVFV3TkZvV0FBQUEhMDAwMDI4ITIwMjItMDktMjdUMDM6MDE6MTIuMTU4MDU1Mloh", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-type": "application/xml", + "date": "Tue, 27 Sep 2022 03:01:11 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "a4a99895-6c61-4928-6900-ab38c0040236", + "x-ms-request-id": "3803c9fc-901e-0084-5c1d-d2a0ae000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestlistdeletedpaths?comp=list&maxresults=1&restype=container&showonly=deleted" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "ee16b368-7738-415c-436f-f0c892a836d7", + "x-ms-version": "2021-04-10" + }, + "Method": "GET", + "Response": { + "BODY": "2!384!MDAwMjQ0IVZCYjYrSnordTlTSjVQd0JHS2NCR0tFQkwzcGphR0Z1WjJSaGRHRnNZV3RsQVRBeFJEaENNRGd6TlVGR016VkdOak12SkhSeVlYTm9MMlJoZEdGc1lXdGxabWxzWlhONWMzUmxiV05zYVdWdWRIUmxjM1JzYVhOMFpHVnNaWFJsWkhCaGRHaHpBVEF4UkRoRU1qRkVOalF4TUVKQ1F6VUNMMnhwYzNSa1pXeGxkR1ZrY0dGMGFITmZabWxzWlY5a1pXeGxkR1ZrQVRJd01qSXRNRGt0TWpkVU1ETTZNREU2TURrdU9UazJPVFV3TkZvV0FBQUEhMDAwMDI4ITIwMjItMDktMjdUMDM6MDE6MTIuMTU4MDU1Mloh1listdeletedpaths_file_deleted133087212699969504trueTue, 27 Sep 2022 03:01:09 GMTTue, 27 Sep 2022 03:01:09 GMTTue, 04 Oct 2022 03:01:09 GMT0x8DAA03487668E60file0application/octet-streamAAAAAAAAAAA=BlockBlobHottruetrueTue, 27 Sep 2022 03:01:09 GMT6", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-type": "application/xml", + "date": "Tue, 27 Sep 2022 03:01:11 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "ee16b368-7738-415c-436f-f0c892a836d7", + "x-ms-request-id": "3803ca64-901e-0084-391d-d2a0ae000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestlistdeletedpaths?comp=list&marker=2!384!MDAwMjQ0IVZCYjYrSnordTlTSjVQd0JHS2NCR0tFQkwzcGphR0Z1WjJSaGRHRnNZV3RsQVRBeFJEaENNRGd6TlVGR016VkdOak12SkhSeVlYTm9MMlJoZEdGc1lXdGxabWxzWlhONWMzUmxiV05zYVdWdWRIUmxjM1JzYVhOMFpHVnNaWFJsWkhCaGRHaHpBVEF4UkRoRU1qRkVOalF4TUVKQ1F6VUNMMnhwYzNSa1pXeGxkR1ZrY0dGMGFITmZabWxzWlY5a1pXeGxkR1ZrQVRJd01qSXRNRGt0TWpkVU1ETTZNREU2TURrdU9UazJPVFV3TkZvV0FBQUEhMDAwMDI4ITIwMjItMDktMjdUMDM6MDE6MTIuMTU4MDU1Mloh&maxresults=1&restype=container&showonly=deleted" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "b4b269ee-68df-4159-6b2f-dee9c01573ab", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:12 GMT", + "etag": "\"0x8DAA034893E6CF7\"", + "last-modified": "Tue, 27 Sep 2022 03:01:12 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "b4b269ee-68df-4159-6b2f-dee9c01573ab", + "x-ms-request-id": "4c4b7097-201f-0028-7f1d-d2b307000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistdeletedpaths/listdeletedpaths_prefix?resource=directory" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "6a1ff000-459b-4d1d-7692-e02752422968", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:13 GMT", + "etag": "\"0x8DAA034896F65DB\"", + "last-modified": "Tue, 27 Sep 2022 03:01:13 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "6a1ff000-459b-4d1d-7692-e02752422968", + "x-ms-request-id": "4c4b70b7-201f-0028-1f1d-d2b307000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistdeletedpaths/listdeletedpaths_prefix/file?resource=file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "46f874e5-552f-4866-564e-ad35c1f89ffb", + "x-ms-version": "2021-06-08" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:13 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "46f874e5-552f-4866-564e-ad35c1f89ffb", + "x-ms-delete-type-permanent": "false", + "x-ms-deletion-id": "133087212735027045", + "x-ms-request-id": "4c4b70d2-201f-0028-3a1d-d2b307000000", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistdeletedpaths/listdeletedpaths_prefix/file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "fe187a16-e3e7-4992-5fd9-57cde493b940", + "x-ms-version": "2021-04-10" + }, + "Method": "GET", + "Response": { + "BODY": "listdeletedpaths_prefixlistdeletedpaths_prefix/file133087212735027045trueTue, 27 Sep 2022 03:01:13 GMTTue, 27 Sep 2022 03:01:13 GMTTue, 04 Oct 2022 03:01:13 GMT0x8DAA034896F65DBfile0application/octet-streamAAAAAAAAAAA=BlockBlobHottruetrueTue, 27 Sep 2022 03:01:13 GMT6", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-type": "application/xml", + "date": "Tue, 27 Sep 2022 03:01:13 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "fe187a16-e3e7-4992-5fd9-57cde493b940", + "x-ms-request-id": "3803cce8-901e-0084-031d-d2a0ae000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestlistdeletedpaths?comp=list&prefix=listdeletedpaths_prefix&restype=container&showonly=deleted" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "449930df-a9cb-44a9-5ad9-59eb4cca1288", + "x-ms-version": "2021-04-10" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:13 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "449930df-a9cb-44a9-5ad9-59eb4cca1288", + "x-ms-request-id": "3803cd63-901e-0084-721d-d2a0ae000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestlistdeletedpaths?restype=container" + } + ] +} diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeFileSystemClientTest.ListPaths.json b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeFileSystemClientTest.ListPaths.json index 7148243f33..c9a66a8140 100644 --- a/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeFileSystemClientTest.ListPaths.json +++ b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeFileSystemClientTest.ListPaths.json @@ -2,9 +2,9 @@ "networkCallRecords": [ { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Windows 10 Pro 6.3 19041 19041.1.amd64fre.vb_release.191206-1406)", - "x-ms-client-request-id": "8f08d654-ff1e-4ddd-442d-664d7041f178", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "6de26491-c99e-4400-52f6-83e5a7769efd", + "x-ms-version": "2021-04-10" }, "Method": "PUT", "Response": { @@ -12,21 +12,21 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Thu, 10 Feb 2022 12:30:43 GMT", - "etag": "\"0x8D9EC9127C0EEAB\"", - "last-modified": "Thu, 10 Feb 2022 12:30:43 GMT", + "date": "Fri, 23 Sep 2022 05:04:04 GMT", + "etag": "\"0x8DA9D2109B6B4D5\"", + "last-modified": "Fri, 23 Sep 2022 05:04:04 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "8f08d654-ff1e-4ddd-442d-664d7041f178", - "x-ms-request-id": "b2045056-d01e-0044-327a-1e1884000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "6de26491-c99e-4400-52f6-83e5a7769efd", + "x-ms-request-id": "167a5741-d01e-0085-4309-cfff72000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestlistpaths?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-files-datalake/12.3.0-beta.1 (Windows 10 Pro 6.3 19041 19041.1.amd64fre.vb_release.191206-1406)", - "x-ms-client-request-id": "894906f1-b0ec-4eb3-790f-e26a5d88e144", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "6154d696-cf93-4d9b-54db-9f3ca23732fb", + "x-ms-version": "2021-06-08" }, "Method": "PUT", "Response": { @@ -34,22 +34,22 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Thu, 10 Feb 2022 12:30:43 GMT", - "etag": "\"0x8D9EC91287C7FD3\"", - "last-modified": "Thu, 10 Feb 2022 12:30:44 GMT", + "date": "Fri, 23 Sep 2022 05:04:05 GMT", + "etag": "\"0x8DA9D210A80C6F7\"", + "last-modified": "Fri, 23 Sep 2022 05:04:06 GMT", "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "894906f1-b0ec-4eb3-790f-e26a5d88e144", - "x-ms-request-id": "e84af67f-d01f-004f-4c7a-1e00f0000000", + "x-ms-client-request-id": "6154d696-cf93-4d9b-54db-9f3ca23732fb", + "x-ms-request-id": "959586e8-901f-0070-5009-cf6b58000000", "x-ms-request-server-encrypted": "true", - "x-ms-version": "2020-02-10" + "x-ms-version": "2021-06-08" }, "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistpaths/datalakefilesystemclienttestlistpata/0?resource=file" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-files-datalake/12.3.0-beta.1 (Windows 10 Pro 6.3 19041 19041.1.amd64fre.vb_release.191206-1406)", - "x-ms-client-request-id": "07971491-f58a-43cc-4327-0d5ea89be5ca", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "6daa4718-03f6-4081-4d01-1dc9f08b1c73", + "x-ms-version": "2021-06-08" }, "Method": "PUT", "Response": { @@ -57,22 +57,22 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Thu, 10 Feb 2022 12:30:43 GMT", - "etag": "\"0x8D9EC9128A6F7D9\"", - "last-modified": "Thu, 10 Feb 2022 12:30:44 GMT", + "date": "Fri, 23 Sep 2022 05:04:05 GMT", + "etag": "\"0x8DA9D210AB3EC4B\"", + "last-modified": "Fri, 23 Sep 2022 05:04:06 GMT", "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "07971491-f58a-43cc-4327-0d5ea89be5ca", - "x-ms-request-id": "e84af680-d01f-004f-4d7a-1e00f0000000", + "x-ms-client-request-id": "6daa4718-03f6-4081-4d01-1dc9f08b1c73", + "x-ms-request-id": "9595873b-901f-0070-2109-cf6b58000000", "x-ms-request-server-encrypted": "true", - "x-ms-version": "2020-02-10" + "x-ms-version": "2021-06-08" }, "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistpaths/datalakefilesystemclienttestlistpatb/0?resource=file" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-files-datalake/12.3.0-beta.1 (Windows 10 Pro 6.3 19041 19041.1.amd64fre.vb_release.191206-1406)", - "x-ms-client-request-id": "29ad9060-ef81-4ceb-69db-e4841d557801", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "16d6a7ee-680f-467f-6f8e-549adfc3306b", + "x-ms-version": "2021-06-08" }, "Method": "PUT", "Response": { @@ -80,22 +80,22 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Thu, 10 Feb 2022 12:30:44 GMT", - "etag": "\"0x8D9EC9128CD98A4\"", - "last-modified": "Thu, 10 Feb 2022 12:30:44 GMT", + "date": "Fri, 23 Sep 2022 05:04:05 GMT", + "etag": "\"0x8DA9D210AE31D0D\"", + "last-modified": "Fri, 23 Sep 2022 05:04:06 GMT", "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "29ad9060-ef81-4ceb-69db-e4841d557801", - "x-ms-request-id": "e84af681-d01f-004f-4e7a-1e00f0000000", + "x-ms-client-request-id": "16d6a7ee-680f-467f-6f8e-549adfc3306b", + "x-ms-request-id": "9595876e-901f-0070-5409-cf6b58000000", "x-ms-request-server-encrypted": "true", - "x-ms-version": "2020-02-10" + "x-ms-version": "2021-06-08" }, "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistpaths/datalakefilesystemclienttestlistpata/1?resource=file" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-files-datalake/12.3.0-beta.1 (Windows 10 Pro 6.3 19041 19041.1.amd64fre.vb_release.191206-1406)", - "x-ms-client-request-id": "cc31b893-142d-4d02-4948-522e34578dd9", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "9d468ae7-c6c1-496d-4e07-08259994e452", + "x-ms-version": "2021-06-08" }, "Method": "PUT", "Response": { @@ -103,22 +103,22 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Thu, 10 Feb 2022 12:30:44 GMT", - "etag": "\"0x8D9EC9128F5FE1B\"", - "last-modified": "Thu, 10 Feb 2022 12:30:45 GMT", + "date": "Fri, 23 Sep 2022 05:04:06 GMT", + "etag": "\"0x8DA9D210B1149EB\"", + "last-modified": "Fri, 23 Sep 2022 05:04:07 GMT", "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "cc31b893-142d-4d02-4948-522e34578dd9", - "x-ms-request-id": "e84af682-d01f-004f-4f7a-1e00f0000000", + "x-ms-client-request-id": "9d468ae7-c6c1-496d-4e07-08259994e452", + "x-ms-request-id": "95958797-901f-0070-7d09-cf6b58000000", "x-ms-request-server-encrypted": "true", - "x-ms-version": "2020-02-10" + "x-ms-version": "2021-06-08" }, "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistpaths/datalakefilesystemclienttestlistpatb/1?resource=file" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-files-datalake/12.3.0-beta.1 (Windows 10 Pro 6.3 19041 19041.1.amd64fre.vb_release.191206-1406)", - "x-ms-client-request-id": "396fe3bc-c524-4a71-52e3-af3eb0e52156", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "5689db32-34d4-430c-584f-5c2720b4b946", + "x-ms-version": "2021-06-08" }, "Method": "PUT", "Response": { @@ -126,22 +126,22 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Thu, 10 Feb 2022 12:30:44 GMT", - "etag": "\"0x8D9EC91291D2661\"", - "last-modified": "Thu, 10 Feb 2022 12:30:45 GMT", + "date": "Fri, 23 Sep 2022 05:04:06 GMT", + "etag": "\"0x8DA9D210B3F8FB2\"", + "last-modified": "Fri, 23 Sep 2022 05:04:07 GMT", "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "396fe3bc-c524-4a71-52e3-af3eb0e52156", - "x-ms-request-id": "e84af685-d01f-004f-507a-1e00f0000000", + "x-ms-client-request-id": "5689db32-34d4-430c-584f-5c2720b4b946", + "x-ms-request-id": "959587cc-901f-0070-3109-cf6b58000000", "x-ms-request-server-encrypted": "true", - "x-ms-version": "2020-02-10" + "x-ms-version": "2021-06-08" }, "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistpaths/datalakefilesystemclienttestlistpata/2?resource=file" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-files-datalake/12.3.0-beta.1 (Windows 10 Pro 6.3 19041 19041.1.amd64fre.vb_release.191206-1406)", - "x-ms-client-request-id": "b0141a42-0b54-49c5-6f0e-a383ebc4c53b", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "10386e25-e34e-43d9-442b-75acee9d11cc", + "x-ms-version": "2021-06-08" }, "Method": "PUT", "Response": { @@ -149,22 +149,22 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Thu, 10 Feb 2022 12:30:44 GMT", - "etag": "\"0x8D9EC912944F0EB\"", - "last-modified": "Thu, 10 Feb 2022 12:30:45 GMT", + "date": "Fri, 23 Sep 2022 05:04:06 GMT", + "etag": "\"0x8DA9D210B6DF840\"", + "last-modified": "Fri, 23 Sep 2022 05:04:07 GMT", "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "b0141a42-0b54-49c5-6f0e-a383ebc4c53b", - "x-ms-request-id": "e84af686-d01f-004f-517a-1e00f0000000", + "x-ms-client-request-id": "10386e25-e34e-43d9-442b-75acee9d11cc", + "x-ms-request-id": "95958802-901f-0070-6709-cf6b58000000", "x-ms-request-server-encrypted": "true", - "x-ms-version": "2020-02-10" + "x-ms-version": "2021-06-08" }, "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistpaths/datalakefilesystemclienttestlistpatb/2?resource=file" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-files-datalake/12.3.0-beta.1 (Windows 10 Pro 6.3 19041 19041.1.amd64fre.vb_release.191206-1406)", - "x-ms-client-request-id": "d452f0c5-674d-4c59-763d-91c1913e9779", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "04e95cf9-dbc2-4d96-6234-89d9515458ca", + "x-ms-version": "2021-06-08" }, "Method": "PUT", "Response": { @@ -172,22 +172,22 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Thu, 10 Feb 2022 12:30:45 GMT", - "etag": "\"0x8D9EC91296C18D8\"", - "last-modified": "Thu, 10 Feb 2022 12:30:45 GMT", + "date": "Fri, 23 Sep 2022 05:04:07 GMT", + "etag": "\"0x8DA9D210B9C6B59\"", + "last-modified": "Fri, 23 Sep 2022 05:04:08 GMT", "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "d452f0c5-674d-4c59-763d-91c1913e9779", - "x-ms-request-id": "e84af687-d01f-004f-527a-1e00f0000000", + "x-ms-client-request-id": "04e95cf9-dbc2-4d96-6234-89d9515458ca", + "x-ms-request-id": "9595882e-901f-0070-1309-cf6b58000000", "x-ms-request-server-encrypted": "true", - "x-ms-version": "2020-02-10" + "x-ms-version": "2021-06-08" }, "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistpaths/datalakefilesystemclienttestlistpata/3?resource=file" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-files-datalake/12.3.0-beta.1 (Windows 10 Pro 6.3 19041 19041.1.amd64fre.vb_release.191206-1406)", - "x-ms-client-request-id": "aa41924d-4b0f-4fc4-4087-5fa5949d765b", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "5fc7addd-af4d-408b-48b0-2a77365da9fd", + "x-ms-version": "2021-06-08" }, "Method": "PUT", "Response": { @@ -195,22 +195,22 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Thu, 10 Feb 2022 12:30:45 GMT", - "etag": "\"0x8D9EC9129925C55\"", - "last-modified": "Thu, 10 Feb 2022 12:30:46 GMT", + "date": "Fri, 23 Sep 2022 05:04:07 GMT", + "etag": "\"0x8DA9D210BCAF016\"", + "last-modified": "Fri, 23 Sep 2022 05:04:08 GMT", "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "aa41924d-4b0f-4fc4-4087-5fa5949d765b", - "x-ms-request-id": "e84af688-d01f-004f-537a-1e00f0000000", + "x-ms-client-request-id": "5fc7addd-af4d-408b-48b0-2a77365da9fd", + "x-ms-request-id": "95958867-901f-0070-4c09-cf6b58000000", "x-ms-request-server-encrypted": "true", - "x-ms-version": "2020-02-10" + "x-ms-version": "2021-06-08" }, "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistpaths/datalakefilesystemclienttestlistpatb/3?resource=file" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-files-datalake/12.3.0-beta.1 (Windows 10 Pro 6.3 19041 19041.1.amd64fre.vb_release.191206-1406)", - "x-ms-client-request-id": "79e178cc-8486-4158-6a8f-e918d55b6e0a", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "90b9c96c-ac13-4f96-67ae-17be2b2adc3e", + "x-ms-version": "2021-06-08" }, "Method": "PUT", "Response": { @@ -218,22 +218,22 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Thu, 10 Feb 2022 12:30:45 GMT", - "etag": "\"0x8D9EC9129B81E52\"", - "last-modified": "Thu, 10 Feb 2022 12:30:46 GMT", + "date": "Fri, 23 Sep 2022 05:04:07 GMT", + "etag": "\"0x8DA9D210BF9C7D5\"", + "last-modified": "Fri, 23 Sep 2022 05:04:08 GMT", "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "79e178cc-8486-4158-6a8f-e918d55b6e0a", - "x-ms-request-id": "e84af689-d01f-004f-547a-1e00f0000000", + "x-ms-client-request-id": "90b9c96c-ac13-4f96-67ae-17be2b2adc3e", + "x-ms-request-id": "9595889e-901f-0070-0309-cf6b58000000", "x-ms-request-server-encrypted": "true", - "x-ms-version": "2020-02-10" + "x-ms-version": "2021-06-08" }, "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistpaths/datalakefilesystemclienttestlistpata/4?resource=file" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-files-datalake/12.3.0-beta.1 (Windows 10 Pro 6.3 19041 19041.1.amd64fre.vb_release.191206-1406)", - "x-ms-client-request-id": "772483af-f632-46d7-416e-05dc3a83985e", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "ce57591b-39c8-443b-6eef-bc459b75d192", + "x-ms-version": "2021-06-08" }, "Method": "PUT", "Response": { @@ -241,86 +241,130 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Thu, 10 Feb 2022 12:30:45 GMT", - "etag": "\"0x8D9EC9129DFAE38\"", - "last-modified": "Thu, 10 Feb 2022 12:30:46 GMT", + "date": "Fri, 23 Sep 2022 05:04:08 GMT", + "etag": "\"0x8DA9D210C28D121\"", + "last-modified": "Fri, 23 Sep 2022 05:04:08 GMT", "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "772483af-f632-46d7-416e-05dc3a83985e", - "x-ms-request-id": "e84af68a-d01f-004f-557a-1e00f0000000", + "x-ms-client-request-id": "ce57591b-39c8-443b-6eef-bc459b75d192", + "x-ms-request-id": "959588d6-901f-0070-3b09-cf6b58000000", "x-ms-request-server-encrypted": "true", - "x-ms-version": "2020-02-10" + "x-ms-version": "2021-06-08" }, "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistpaths/datalakefilesystemclienttestlistpatb/4?resource=file" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-files-datalake/12.3.0-beta.1 (Windows 10 Pro 6.3 19041 19041.1.amd64fre.vb_release.191206-1406)", - "x-ms-client-request-id": "67f00dbb-6eb6-4fc7-4ea1-0c0a700a2b64", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "5288db61-9c12-4d3a-6f0e-c805e391af33", + "x-ms-version": "2021-06-08" }, "Method": "GET", "Response": { - "BODY": "{\"paths\":[{\"contentLength\":\"0\",\"creationTime\":\"132889698443120578\",\"etag\":\"0x8D9EC912879D279\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"isDirectory\":\"true\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:44 GMT\",\"name\":\"datalakefilesystemclienttestlistpata\",\"owner\":\"$superuser\",\"permissions\":\"rwxr-x---\"},{\"contentLength\":\"0\",\"creationTime\":\"132889698443296723\",\"etag\":\"0x8D9EC91287C7FD3\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:44 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/0\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"132889698448611492\",\"etag\":\"0x8D9EC9128CD98A4\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:44 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/1\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"132889698453825121\",\"etag\":\"0x8D9EC91291D2661\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:45 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/2\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"132889698458999000\",\"etag\":\"0x8D9EC91296C18D8\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:45 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/3\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"132889698463981138\",\"etag\":\"0x8D9EC9129B81E52\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:46 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/4\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"132889698445865410\",\"etag\":\"0x8D9EC9128A3B3C1\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"isDirectory\":\"true\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:44 GMT\",\"name\":\"datalakefilesystemclienttestlistpatb\",\"owner\":\"$superuser\",\"permissions\":\"rwxr-x---\"},{\"contentLength\":\"0\",\"creationTime\":\"132889698446079961\",\"etag\":\"0x8D9EC9128A6F7D9\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:44 GMT\",\"name\":\"datalakefilesystemclienttestlistpatb/0\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"132889698451258907\",\"etag\":\"0x8D9EC9128F5FE1B\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:45 GMT\",\"name\":\"datalakefilesystemclienttestlistpatb/1\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"132889698456432875\",\"etag\":\"0x8D9EC912944F0EB\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:45 GMT\",\"name\":\"datalakefilesystemclienttestlistpatb/2\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"132889698461506645\",\"etag\":\"0x8D9EC9129925C55\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:46 GMT\",\"name\":\"datalakefilesystemclienttestlistpatb/3\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"132889698466573880\",\"etag\":\"0x8D9EC9129DFAE38\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:46 GMT\",\"name\":\"datalakefilesystemclienttestlistpatb/4\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"}]}\n", + "BODY": "{\"paths\":[{\"contentLength\":\"0\",\"creationTime\":\"133083830461752560\",\"etag\":\"0x8DA9D210A7C66C1\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"isDirectory\":\"true\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:06 GMT\",\"name\":\"datalakefilesystemclienttestlistpata\",\"owner\":\"$superuser\",\"permissions\":\"rwxr-x---\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830462039799\",\"etag\":\"0x8DA9D210A80C6F7\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:06 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/0\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830468484365\",\"etag\":\"0x8DA9D210AE31D0D\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:06 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/1\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830474543026\",\"etag\":\"0x8DA9D210B3F8FB2\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:07 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/2\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830480628569\",\"etag\":\"0x8DA9D210B9C6B59\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:08 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/3\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830486747093\",\"etag\":\"0x8DA9D210BF9C7D5\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:08 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/4\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830465204460\",\"etag\":\"0x8DA9D210AB110ED\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"isDirectory\":\"true\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:06 GMT\",\"name\":\"datalakefilesystemclienttestlistpatb\",\"owner\":\"$superuser\",\"permissions\":\"rwxr-x---\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830465391691\",\"etag\":\"0x8DA9D210AB3EC4B\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:06 GMT\",\"name\":\"datalakefilesystemclienttestlistpatb/0\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830471510507\",\"etag\":\"0x8DA9D210B1149EB\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:07 GMT\",\"name\":\"datalakefilesystemclienttestlistpatb/1\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830477584448\",\"etag\":\"0x8DA9D210B6DF840\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:07 GMT\",\"name\":\"datalakefilesystemclienttestlistpatb/2\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830483677206\",\"etag\":\"0x8DA9D210BCAF016\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:08 GMT\",\"name\":\"datalakefilesystemclienttestlistpatb/3\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830489829665\",\"etag\":\"0x8DA9D210C28D121\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:08 GMT\",\"name\":\"datalakefilesystemclienttestlistpatb/4\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"}]}\n", "REASON_PHRASE": "OK", "STATUS_CODE": "200", "content-type": "application/json;charset=utf-8", - "date": "Thu, 10 Feb 2022 12:30:46 GMT", + "date": "Fri, 23 Sep 2022 05:04:08 GMT", "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", "transfer-encoding": "chunked", - "x-ms-client-request-id": "67f00dbb-6eb6-4fc7-4ea1-0c0a700a2b64", - "x-ms-request-id": "e84af68b-d01f-004f-567a-1e00f0000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "5288db61-9c12-4d3a-6f0e-c805e391af33", + "x-ms-request-id": "95958903-901f-0070-6809-cf6b58000000", + "x-ms-version": "2021-06-08" }, "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistpaths?recursive=true&resource=filesystem" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-files-datalake/12.3.0-beta.1 (Windows 10 Pro 6.3 19041 19041.1.amd64fre.vb_release.191206-1406)", - "x-ms-client-request-id": "f14b09c8-57ac-423e-6c51-d7755f4d6e60", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "cbffe896-0fd4-42fe-4d48-61767cb1ae2c", + "x-ms-version": "2021-06-08" }, "Method": "GET", "Response": { - "BODY": "{\"paths\":[{\"contentLength\":\"0\",\"creationTime\":\"132889698443296723\",\"etag\":\"0x8D9EC91287C7FD3\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:44 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/0\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"132889698448611492\",\"etag\":\"0x8D9EC9128CD98A4\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:44 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/1\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"132889698453825121\",\"etag\":\"0x8D9EC91291D2661\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:45 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/2\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"132889698458999000\",\"etag\":\"0x8D9EC91296C18D8\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:45 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/3\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"132889698463981138\",\"etag\":\"0x8D9EC9129B81E52\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:46 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/4\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"}]}\n", + "BODY": "{\"paths\":[{\"contentLength\":\"0\",\"creationTime\":\"133083830462039799\",\"etag\":\"0x8DA9D210A80C6F7\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:06 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/0\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830468484365\",\"etag\":\"0x8DA9D210AE31D0D\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:06 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/1\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830474543026\",\"etag\":\"0x8DA9D210B3F8FB2\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:07 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/2\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830480628569\",\"etag\":\"0x8DA9D210B9C6B59\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:08 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/3\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830486747093\",\"etag\":\"0x8DA9D210BF9C7D5\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:08 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/4\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"}]}\n", "REASON_PHRASE": "OK", "STATUS_CODE": "200", "content-type": "application/json;charset=utf-8", - "date": "Thu, 10 Feb 2022 12:30:46 GMT", + "date": "Fri, 23 Sep 2022 05:04:08 GMT", "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", "transfer-encoding": "chunked", - "x-ms-client-request-id": "f14b09c8-57ac-423e-6c51-d7755f4d6e60", - "x-ms-request-id": "e84af68c-d01f-004f-577a-1e00f0000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "cbffe896-0fd4-42fe-4d48-61767cb1ae2c", + "x-ms-request-id": "95958928-901f-0070-0d09-cf6b58000000", + "x-ms-version": "2021-06-08" }, "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistpaths?directory=datalakefilesystemclienttestlistpata&recursive=true&resource=filesystem" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-files-datalake/12.3.0-beta.1 (Windows 10 Pro 6.3 19041 19041.1.amd64fre.vb_release.191206-1406)", - "x-ms-client-request-id": "78793360-1ec9-408b-41ec-981f22bc060e", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "f5be34a1-afd9-4ad9-4576-bcd875fe5daa", + "x-ms-version": "2021-06-08" }, "Method": "GET", "Response": { - "BODY": "{\"paths\":[{\"contentLength\":\"0\",\"creationTime\":\"132889698443120578\",\"etag\":\"0x8D9EC912879D279\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"isDirectory\":\"true\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:44 GMT\",\"name\":\"datalakefilesystemclienttestlistpata\",\"owner\":\"$superuser\",\"permissions\":\"rwxr-x---\"},{\"contentLength\":\"0\",\"creationTime\":\"132889698443296723\",\"etag\":\"0x8D9EC91287C7FD3\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Thu, 10 Feb 2022 12:30:44 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/0\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"}]}\n", + "BODY": "{\"paths\":[{\"contentLength\":\"0\",\"creationTime\":\"133083830461752560\",\"etag\":\"0x8DA9D210A7C66C1\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"isDirectory\":\"true\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:06 GMT\",\"name\":\"datalakefilesystemclienttestlistpata\",\"owner\":\"$superuser\",\"permissions\":\"rwxr-x---\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830462039799\",\"etag\":\"0x8DA9D210A80C6F7\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:06 GMT\",\"name\":\"datalakefilesystemclienttestlistpata/0\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"}]}\n", "REASON_PHRASE": "OK", "STATUS_CODE": "200", "content-type": "application/json;charset=utf-8", - "date": "Thu, 10 Feb 2022 12:30:46 GMT", + "date": "Fri, 23 Sep 2022 05:04:09 GMT", "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", "transfer-encoding": "chunked", - "x-ms-client-request-id": "78793360-1ec9-408b-41ec-981f22bc060e", - "x-ms-continuation": "VBap0Y+oqtbCh+8BGH8Yei9hZGxzZ2VuMnV0ATAxRDU5NDU4NDQ4MTM5NzAvZGF0YWxha2VmaWxlc3lzdGVtY2xpZW50dGVzdGxpc3RwYXRocwEwMUQ4MUU3QTA1NEEwQzc0L2RhdGFsYWtlZmlsZXN5c3RlbWNsaWVudHRlc3RsaXN0cGF0YS8xFgAAAA==", - "x-ms-request-id": "e84af68d-d01f-004f-587a-1e00f0000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "f5be34a1-afd9-4ad9-4576-bcd875fe5daa", + "x-ms-continuation": "VBb46dPpnZTanOsBGIMBGH4vemNoYW5nZGF0YWxha2UBMDFEOEIwODM1QUYzNUY2My9kYXRhbGFrZWZpbGVzeXN0ZW1jbGllbnR0ZXN0bGlzdHBhdGhzATAxRDhDRjA5RTc0MEFFNDEvZGF0YWxha2VmaWxlc3lzdGVtY2xpZW50dGVzdGxpc3RwYXRhLzEWAAAA", + "x-ms-request-id": "95958955-901f-0070-3a09-cf6b58000000", + "x-ms-version": "2021-06-08" }, "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistpaths?maxResults=2&recursive=true&resource=filesystem" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Windows 10 Pro 6.3 19041 19041.1.amd64fre.vb_release.191206-1406)", - "x-ms-client-request-id": "db058798-a0d5-444e-6664-6eb6c21f71ea", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "728f981e-3bcc-485d-54b2-5d06bb4832db", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Fri, 23 Sep 2022 05:04:09 GMT", + "etag": "\"0x8DA9D210CE3AF64\"", + "last-modified": "Fri, 23 Sep 2022 05:04:10 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "728f981e-3bcc-485d-54b2-5d06bb4832db", + "x-ms-request-id": "9595897d-901f-0070-6209-cf6b58000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistpaths/listpathscheck_expiry?resource=file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "b751c4eb-73d2-49ae-6f5d-a8286181c316", + "x-ms-version": "2021-06-08" + }, + "Method": "GET", + "Response": { + "BODY": "{\"paths\":[{\"contentLength\":\"0\",\"creationTime\":\"133083830461752560\",\"etag\":\"0x8DA9D210A7C66C1\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"isDirectory\":\"true\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:06 GMT\",\"name\":\"datalakefilesystemclienttestlistpata\",\"owner\":\"$superuser\",\"permissions\":\"rwxr-x---\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830465204460\",\"etag\":\"0x8DA9D210AB110ED\",\"expiryTime\":\"0\",\"group\":\"$superuser\",\"isDirectory\":\"true\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:06 GMT\",\"name\":\"datalakefilesystemclienttestlistpatb\",\"owner\":\"$superuser\",\"permissions\":\"rwxr-x---\"},{\"contentLength\":\"0\",\"creationTime\":\"133083830502076260\",\"etag\":\"0x8DA9D210CE3AF64\",\"expiryTime\":\"157703683830000000\",\"group\":\"$superuser\",\"lastModified\":\"Fri, 23 Sep 2022 05:04:10 GMT\",\"name\":\"listpathscheck_expiry\",\"owner\":\"$superuser\",\"permissions\":\"rw-r-----\"}]}\n", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-type": "application/json;charset=utf-8", + "date": "Fri, 23 Sep 2022 05:04:09 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "b751c4eb-73d2-49ae-6f5d-a8286181c316", + "x-ms-request-id": "959589a9-901f-0070-0e09-cf6b58000000", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestlistpaths?recursive=false&resource=filesystem" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "8ad5c2bc-6aa8-4434-43ef-b4526c2270aa", + "x-ms-version": "2021-04-10" }, "Method": "DELETE", "Response": { @@ -328,11 +372,11 @@ "REASON_PHRASE": "Accepted", "STATUS_CODE": "202", "content-length": "0", - "date": "Thu, 10 Feb 2022 12:30:47 GMT", + "date": "Fri, 23 Sep 2022 05:04:09 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "db058798-a0d5-444e-6664-6eb6c21f71ea", - "x-ms-request-id": "b2045ad2-d01e-0044-4d7a-1e1884000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "8ad5c2bc-6aa8-4434-43ef-b4526c2270aa", + "x-ms-request-id": "167a652a-d01e-0085-0109-cfff72000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestlistpaths?restype=container" } diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeFileSystemClientTest.Undelete.json b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeFileSystemClientTest.Undelete.json new file mode 100644 index 0000000000..bdb126a06b --- /dev/null +++ b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeFileSystemClientTest.Undelete.json @@ -0,0 +1,563 @@ +{ + "networkCallRecords": [ + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "f268529f-3a61-4d97-7a8b-87c1bf7722d6", + "x-ms-version": "2021-04-10" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:13 GMT", + "etag": "\"0x8DAA0348A4720C7\"", + "last-modified": "Tue, 27 Sep 2022 03:01:14 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "f268529f-3a61-4d97-7a8b-87c1bf7722d6", + "x-ms-request-id": "3803ce00-901e-0084-7b1d-d2a0ae000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete?restype=container" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "3ca3565f-4f12-453a-449e-d412b76ecc28", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:14 GMT", + "etag": "\"0x8DAA0348A7A8ACF\"", + "last-modified": "Tue, 27 Sep 2022 03:01:14 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "3ca3565f-4f12-453a-449e-d412b76ecc28", + "x-ms-request-id": "4c4b714d-201f-0028-331d-d2b307000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestundelete/undelete_dir?resource=directory" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "80d7247b-af1e-4b67-5ae6-24dcbe1afdb8", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:15 GMT", + "etag": "\"0x8DAA0348AAE3164\"", + "last-modified": "Tue, 27 Sep 2022 03:01:15 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "80d7247b-af1e-4b67-5ae6-24dcbe1afdb8", + "x-ms-request-id": "4c4b7165-201f-0028-4b1d-d2b307000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestundelete/undelete_dir/sub_file?resource=file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "6e0c849e-d03a-4470-7e93-230e9967aeb6", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "0", + "content-type": "application/octet-stream", + "date": "Tue, 27 Sep 2022 03:01:14 GMT", + "etag": "\"0x8DAA0348A7A8ACF\"", + "last-modified": "Tue, 27 Sep 2022 03:01:14 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "6e0c849e-d03a-4470-7e93-230e9967aeb6", + "x-ms-creation-time": "Tue, 27 Sep 2022 03:01:14 GMT", + "x-ms-group": "$superuser", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-meta-hdi_isfolder": "true", + "x-ms-owner": "$superuser", + "x-ms-permissions": "rwxr-x---", + "x-ms-request-id": "3803cf55-901e-0084-1c1d-d2a0ae000000", + "x-ms-resource-type": "directory", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete/undelete_dir" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "c6d3db69-4932-4fbc-654b-d93773ce37ce", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "0", + "content-type": "application/octet-stream", + "date": "Tue, 27 Sep 2022 03:01:14 GMT", + "etag": "\"0x8DAA0348AAE3164\"", + "last-modified": "Tue, 27 Sep 2022 03:01:15 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "c6d3db69-4932-4fbc-654b-d93773ce37ce", + "x-ms-creation-time": "Tue, 27 Sep 2022 03:01:15 GMT", + "x-ms-group": "$superuser", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-owner": "$superuser", + "x-ms-permissions": "rw-r-----", + "x-ms-request-id": "3803cfc8-901e-0084-051d-d2a0ae000000", + "x-ms-resource-type": "file", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete/undelete_dir/sub_file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "9cf7aead-77ab-44ce-5b4f-64f8425e8e07", + "x-ms-version": "2021-06-08" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:16 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "9cf7aead-77ab-44ce-5b4f-64f8425e8e07", + "x-ms-delete-type-permanent": "false", + "x-ms-deletion-id": "133087212760750222", + "x-ms-request-id": "4c4b71b3-201f-0028-171d-d2b307000000", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestundelete/undelete_dir?recursive=true" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "d96f0fc6-feb6-49b1-4a05-077bc9370ee0", + "x-ms-version": "2021-04-10" + }, + "Method": "GET", + "Response": { + "BODY": "undelete_dir133087212760750222trueTue, 27 Sep 2022 03:01:14 GMTTue, 27 Sep 2022 03:01:14 GMTTue, 04 Oct 2022 03:01:16 GMT0x8DAA0348A7A8ACFdirectory0application/octet-streamAAAAAAAAAAA=BlockBlobHottruetrueTue, 27 Sep 2022 03:01:16 GMT6", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-type": "application/xml", + "date": "Tue, 27 Sep 2022 03:01:15 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "d96f0fc6-feb6-49b1-4a05-077bc9370ee0", + "x-ms-request-id": "3803d1e4-901e-0084-591d-d2a0ae000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete?comp=list&restype=container&showonly=deleted" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "f31e94c6-3605-4f8b-70c9-fb23b35f071a", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:16 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "f31e94c6-3605-4f8b-70c9-fb23b35f071a", + "x-ms-creation-time": "Tue, 27 Sep 2022 03:01:14 GMT", + "x-ms-request-id": "3803d270-901e-0084-581d-d2a0ae000000", + "x-ms-resource-type": "directory", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete/undelete_dir?comp=undelete" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "a5210b6f-e947-4216-7312-c8c1e02da4ec", + "x-ms-version": "2021-04-10" + }, + "Method": "GET", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-type": "application/xml", + "date": "Tue, 27 Sep 2022 03:01:16 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "a5210b6f-e947-4216-7312-c8c1e02da4ec", + "x-ms-request-id": "3803d370-901e-0084-3b1d-d2a0ae000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete?comp=list&restype=container&showonly=deleted" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "7a2a53d1-5a47-44af-65d8-1f5c9ceb07b8", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "0", + "content-type": "application/octet-stream", + "date": "Tue, 27 Sep 2022 03:01:16 GMT", + "etag": "\"0x8DAA0348A7A8ACF\"", + "last-modified": "Tue, 27 Sep 2022 03:01:14 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "7a2a53d1-5a47-44af-65d8-1f5c9ceb07b8", + "x-ms-creation-time": "Tue, 27 Sep 2022 03:01:14 GMT", + "x-ms-group": "$superuser", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-meta-hdi_isfolder": "true", + "x-ms-owner": "$superuser", + "x-ms-permissions": "rwxr-x---", + "x-ms-request-id": "3803d427-901e-0084-6b1d-d2a0ae000000", + "x-ms-resource-type": "directory", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete/undelete_dir" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "6db9b566-c773-4f1c-623d-658776e8072e", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "0", + "content-type": "application/octet-stream", + "date": "Tue, 27 Sep 2022 03:01:17 GMT", + "etag": "\"0x8DAA0348AAE3164\"", + "last-modified": "Tue, 27 Sep 2022 03:01:15 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "6db9b566-c773-4f1c-623d-658776e8072e", + "x-ms-creation-time": "Tue, 27 Sep 2022 03:01:15 GMT", + "x-ms-group": "$superuser", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-owner": "$superuser", + "x-ms-permissions": "rw-r-----", + "x-ms-request-id": "3803d4c8-901e-0084-7d1d-d2a0ae000000", + "x-ms-resource-type": "file", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete/undelete_dir/sub_file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "21dc66de-ddfe-448b-47ed-b27f94e8c077", + "x-ms-version": "2021-06-08" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:18 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "21dc66de-ddfe-448b-47ed-b27f94e8c077", + "x-ms-delete-type-permanent": "false", + "x-ms-deletion-id": "133087212781678638", + "x-ms-request-id": "4c4b727f-201f-0028-5e1d-d2b307000000", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestundelete/undelete_dir/sub_file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "37df0b10-09dd-4cd4-5a36-b96ba299910a", + "x-ms-version": "2021-06-08" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:18 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "37df0b10-09dd-4cd4-5a36-b96ba299910a", + "x-ms-delete-type-permanent": "false", + "x-ms-deletion-id": "133087212785510990", + "x-ms-request-id": "4c4b72b1-201f-0028-101d-d2b307000000", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakefilesystemclienttestundelete/undelete_dir?recursive=false" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "2a834864-f79e-4b1a-6f9d-6e0d97aa73d2", + "x-ms-version": "2021-04-10" + }, + "Method": "GET", + "Response": { + "BODY": "undelete_dir133087212785510990trueTue, 27 Sep 2022 03:01:14 GMTTue, 27 Sep 2022 03:01:14 GMTTue, 04 Oct 2022 03:01:18 GMT0x8DAA0348A7A8ACFdirectory0application/octet-streamAAAAAAAAAAA=BlockBlobHottruetrueTue, 27 Sep 2022 03:01:18 GMT6undelete_dir/sub_file133087212781678638trueTue, 27 Sep 2022 03:01:15 GMTTue, 27 Sep 2022 03:01:15 GMTTue, 04 Oct 2022 03:01:18 GMT0x8DAA0348AAE3164file0application/octet-streamAAAAAAAAAAA=BlockBlobHottruetrueTue, 27 Sep 2022 03:01:18 GMT6", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-type": "application/xml", + "date": "Tue, 27 Sep 2022 03:01:18 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "2a834864-f79e-4b1a-6f9d-6e0d97aa73d2", + "x-ms-request-id": "3803d788-901e-0084-101d-d2a0ae000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete?comp=list&restype=container&showonly=deleted" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "e4026214-e9d2-4954-7e54-e044c02c50f4", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:18 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "e4026214-e9d2-4954-7e54-e044c02c50f4", + "x-ms-creation-time": "Tue, 27 Sep 2022 03:01:14 GMT", + "x-ms-request-id": "3803d86d-901e-0084-671d-d2a0ae000000", + "x-ms-resource-type": "directory", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete/undelete_dir?comp=undelete" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "1e70a5c5-5183-432f-7e26-4f833541d032", + "x-ms-version": "2021-04-10" + }, + "Method": "GET", + "Response": { + "BODY": "undelete_dir/sub_file133087212781678638trueTue, 27 Sep 2022 03:01:15 GMTTue, 27 Sep 2022 03:01:15 GMTTue, 04 Oct 2022 03:01:18 GMT0x8DAA0348AAE3164file0application/octet-streamAAAAAAAAAAA=BlockBlobHottruetrueTue, 27 Sep 2022 03:01:18 GMT6", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-type": "application/xml", + "date": "Tue, 27 Sep 2022 03:01:18 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "1e70a5c5-5183-432f-7e26-4f833541d032", + "x-ms-request-id": "3803d921-901e-0084-0d1d-d2a0ae000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete?comp=list&restype=container&showonly=deleted" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "012ef39d-9e4b-418e-7d34-0a6ec5334788", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "0", + "content-type": "application/octet-stream", + "date": "Tue, 27 Sep 2022 03:01:19 GMT", + "etag": "\"0x8DAA0348A7A8ACF\"", + "last-modified": "Tue, 27 Sep 2022 03:01:14 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "012ef39d-9e4b-418e-7d34-0a6ec5334788", + "x-ms-creation-time": "Tue, 27 Sep 2022 03:01:14 GMT", + "x-ms-group": "$superuser", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-meta-hdi_isfolder": "true", + "x-ms-owner": "$superuser", + "x-ms-permissions": "rwxr-x---", + "x-ms-request-id": "3803d9c6-901e-0084-281d-d2a0ae000000", + "x-ms-resource-type": "directory", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete/undelete_dir" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "061ab627-ac84-4754-78d7-b4e2b7d11f70", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "The specified blob does not exist.", + "STATUS_CODE": "404", + "date": "Tue, 27 Sep 2022 03:01:19 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "061ab627-ac84-4754-78d7-b4e2b7d11f70", + "x-ms-error-code": "BlobNotFound", + "x-ms-request-id": "3803da20-901e-0084-7c1d-d2a0ae000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete/undelete_dir/sub_file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "8655ee98-73bc-4597-63af-a1f5548ac3f9", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:21 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "8655ee98-73bc-4597-63af-a1f5548ac3f9", + "x-ms-creation-time": "Tue, 27 Sep 2022 03:01:15 GMT", + "x-ms-request-id": "03af34b7-601e-0080-121d-d22da9000000", + "x-ms-resource-type": "file", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete/undelete_dir/sub_file?comp=undelete" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "f8ccabc0-3e10-499c-4c2c-bce7860b0aae", + "x-ms-version": "2021-04-10" + }, + "Method": "GET", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-type": "application/xml", + "date": "Tue, 27 Sep 2022 03:01:21 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "f8ccabc0-3e10-499c-4c2c-bce7860b0aae", + "x-ms-request-id": "03af374d-601e-0080-691d-d22da9000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete?comp=list&restype=container&showonly=deleted" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "5455eddc-71a6-4548-4a9a-519a0e0f0723", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "0", + "content-type": "application/octet-stream", + "date": "Tue, 27 Sep 2022 03:01:21 GMT", + "etag": "\"0x8DAA0348AAE3164\"", + "last-modified": "Tue, 27 Sep 2022 03:01:15 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "5455eddc-71a6-4548-4a9a-519a0e0f0723", + "x-ms-creation-time": "Tue, 27 Sep 2022 03:01:15 GMT", + "x-ms-group": "$superuser", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-owner": "$superuser", + "x-ms-permissions": "rw-r-----", + "x-ms-request-id": "03af3852-601e-0080-451d-d22da9000000", + "x-ms-resource-type": "file", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete/undelete_dir/sub_file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "77c75e1a-136c-4119-7de7-70a21e03e300", + "x-ms-version": "2021-04-10" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:22 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "77c75e1a-136c-4119-7de7-70a21e03e300", + "x-ms-request-id": "03af390f-601e-0080-691d-d22da9000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakefilesystemclienttestundelete?restype=container" + } + ] +} diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakePathClientTest.CreateWithOptions.json b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakePathClientTest.CreateWithOptions.json new file mode 100644 index 0000000000..6f2c3eb842 --- /dev/null +++ b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakePathClientTest.CreateWithOptions.json @@ -0,0 +1,364 @@ +{ + "networkCallRecords": [ + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "e3fe567c-0f47-4060-60f8-ed314816a807", + "x-ms-version": "2021-04-10" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Thu, 22 Sep 2022 08:15:21 GMT", + "etag": "\"0x8DA9C7298ACCD16\"", + "last-modified": "Thu, 22 Sep 2022 08:15:22 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "e3fe567c-0f47-4060-60f8-ed314816a807", + "x-ms-request-id": "1b7c2128-801e-0098-7f5b-cef2ce000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakepathclienttestcreatewithoptions?restype=container" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "06f95515-d0dd-4600-5f1a-deefe5600fd1", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Thu, 22 Sep 2022 08:15:24 GMT", + "etag": "\"0x8DA9C7299841A56\"", + "last-modified": "Thu, 22 Sep 2022 08:15:24 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "06f95515-d0dd-4600-5f1a-deefe5600fd1", + "x-ms-request-id": "1b286777-f01f-003b-705b-ce970b000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakepathclienttestcreatewithoptions/datalakepathclienttestcreatewithoptions?resource=file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "819b4146-7e5a-4444-63cc-8821a68f324a", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Thu, 22 Sep 2022 08:15:24 GMT", + "etag": "\"0x8DA9C7299B43EFD\"", + "last-modified": "Thu, 22 Sep 2022 08:15:24 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "819b4146-7e5a-4444-63cc-8821a68f324a", + "x-ms-request-id": "1b2867c3-f01f-003b-3c5b-ce970b000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakepathclienttestcreatewithoptions/createwithoptionsowner_group?resource=file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "a92a43db-ac5d-4ed4-5c59-57eff2e80175", + "x-ms-version": "2021-06-08" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "date": "Thu, 22 Sep 2022 08:15:24 GMT", + "etag": "\"0x8DA9C7299B43EFD\"", + "last-modified": "Thu, 22 Sep 2022 08:15:24 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-acl": "user::rw-,group::r--,other::---", + "x-ms-client-request-id": "a92a43db-ac5d-4ed4-5c59-57eff2e80175", + "x-ms-group": "$superuser", + "x-ms-owner": "$superuser", + "x-ms-permissions": "rw-r-----", + "x-ms-request-id": "1b2867f0-f01f-003b-685b-ce970b000000", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakepathclienttestcreatewithoptions/createwithoptionsowner_group?action=getAccessControl" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "1175eaa4-02db-48fa-622f-54a4af42eaff", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Thu, 22 Sep 2022 08:15:25 GMT", + "etag": "\"0x8DA9C729A128834\"", + "last-modified": "Thu, 22 Sep 2022 08:15:25 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "1175eaa4-02db-48fa-622f-54a4af42eaff", + "x-ms-request-id": "1b286825-f01f-003b-1d5b-ce970b000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakepathclienttestcreatewithoptions/createwithoptions_acl?resource=file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "4c3e31ae-4d33-4257-732d-7853423d7a11", + "x-ms-version": "2021-06-08" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "date": "Thu, 22 Sep 2022 08:15:25 GMT", + "etag": "\"0x8DA9C729A128834\"", + "last-modified": "Thu, 22 Sep 2022 08:15:25 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-acl": "user::rwx,user:72a3f86f-271f-439e-b031-25678907d381:rwx,group::r--,mask::rwx,other::---", + "x-ms-client-request-id": "4c3e31ae-4d33-4257-732d-7853423d7a11", + "x-ms-group": "$superuser", + "x-ms-owner": "$superuser", + "x-ms-permissions": "rwxrwx---+", + "x-ms-request-id": "1b28684f-f01f-003b-455b-ce970b000000", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakepathclienttestcreatewithoptions/createwithoptions_acl?action=getAccessControl" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "340169e3-a8c6-4f26-5c83-a59959fd1668", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Thu, 22 Sep 2022 08:15:25 GMT", + "etag": "\"0x8DA9C729A7003AB\"", + "last-modified": "Thu, 22 Sep 2022 08:15:25 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "340169e3-a8c6-4f26-5c83-a59959fd1668", + "x-ms-request-id": "1b28688d-f01f-003b-765b-ce970b000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakepathclienttestcreatewithoptions/createwithoptions_lease?resource=file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "a2b37160-8f93-4f8b-75a3-e87d599f420b", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "0", + "content-type": "application/octet-stream", + "date": "Thu, 22 Sep 2022 08:15:25 GMT", + "etag": "\"0x8DA9C729A7003AB\"", + "last-modified": "Thu, 22 Sep 2022 08:15:25 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "a2b37160-8f93-4f8b-75a3-e87d599f420b", + "x-ms-creation-time": "Thu, 22 Sep 2022 08:15:25 GMT", + "x-ms-group": "$superuser", + "x-ms-lease-duration": "fixed", + "x-ms-lease-state": "leased", + "x-ms-lease-status": "locked", + "x-ms-owner": "$superuser", + "x-ms-permissions": "rw-r-----", + "x-ms-request-id": "1b7c29b3-801e-0098-4c5b-cef2ce000000", + "x-ms-resource-type": "file", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakepathclienttestcreatewithoptions/createwithoptions_lease" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "ef662d54-a94f-460c-6b31-ca23dfcc1c2c", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Thu, 22 Sep 2022 08:15:26 GMT", + "etag": "\"0x8DA9C729ACE097A\"", + "last-modified": "Thu, 22 Sep 2022 08:15:26 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "ef662d54-a94f-460c-6b31-ca23dfcc1c2c", + "x-ms-request-id": "1b2868d7-f01f-003b-405b-ce970b000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakepathclienttestcreatewithoptions/createwithoptions_relative_expiry?resource=file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "506f83b9-2b74-4a4a-42a2-fc2aa7c3b476", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "0", + "content-type": "application/octet-stream", + "date": "Thu, 22 Sep 2022 08:15:25 GMT", + "etag": "\"0x8DA9C729ACE097A\"", + "last-modified": "Thu, 22 Sep 2022 08:15:26 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "506f83b9-2b74-4a4a-42a2-fc2aa7c3b476", + "x-ms-creation-time": "Thu, 22 Sep 2022 08:15:26 GMT", + "x-ms-expiry-time": "Thu, 22 Sep 2022 09:15:26 GMT", + "x-ms-group": "$superuser", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-owner": "$superuser", + "x-ms-permissions": "rw-r-----", + "x-ms-request-id": "1b7c2bb7-801e-0098-285b-cef2ce000000", + "x-ms-resource-type": "file", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakepathclienttestcreatewithoptions/createwithoptions_relative_expiry" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "7c3cfe20-69f0-4b10-6b5a-f1bd0c8d3fba", + "x-ms-version": "2021-06-08" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Created", + "STATUS_CODE": "201", + "content-length": "0", + "date": "Thu, 22 Sep 2022 08:15:26 GMT", + "etag": "\"0x8DA9C729B2A21E1\"", + "last-modified": "Thu, 22 Sep 2022 08:15:26 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "7c3cfe20-69f0-4b10-6b5a-f1bd0c8d3fba", + "x-ms-request-id": "1b28691f-f01f-003b-085b-ce970b000000", + "x-ms-request-server-encrypted": "true", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakepathclienttestcreatewithoptions/createwithoptions_absolute_expiry?resource=file" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "0002140c-80d8-403c-57d9-5ddab7c8ef3b", + "x-ms-version": "2021-04-10" + }, + "Method": "HEAD", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "accept-ranges": "bytes", + "content-length": "0", + "content-type": "application/octet-stream", + "date": "Thu, 22 Sep 2022 08:15:26 GMT", + "etag": "\"0x8DA9C729B2A21E1\"", + "last-modified": "Thu, 22 Sep 2022 08:15:26 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-access-tier": "Hot", + "x-ms-access-tier-inferred": "true", + "x-ms-blob-type": "BlockBlob", + "x-ms-client-request-id": "0002140c-80d8-403c-57d9-5ddab7c8ef3b", + "x-ms-creation-time": "Thu, 22 Sep 2022 08:15:26 GMT", + "x-ms-expiry-time": "Wed, 29 Sep 2100 09:53:03 GMT", + "x-ms-group": "$superuser", + "x-ms-lease-state": "available", + "x-ms-lease-status": "unlocked", + "x-ms-owner": "$superuser", + "x-ms-permissions": "rw-r-----", + "x-ms-request-id": "1b7c2e26-801e-0098-6d5b-cef2ce000000", + "x-ms-resource-type": "file", + "x-ms-server-encrypted": "true", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakepathclienttestcreatewithoptions/createwithoptions_absolute_expiry" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-files-datalake/12.4.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "e8a2a362-5cf5-4d44-478c-7767eed9625e", + "x-ms-version": "2021-06-08" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-length": "0", + "date": "Thu, 22 Sep 2022 08:15:27 GMT", + "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "e8a2a362-5cf5-4d44-478c-7767eed9625e", + "x-ms-delete-type-permanent": "false", + "x-ms-deletion-id": "133083081276164640", + "x-ms-request-id": "1b28696c-f01f-003b-545b-ce970b000000", + "x-ms-version": "2021-06-08" + }, + "Url": "https://REDACTED.dfs.core.windows.net/datalakepathclienttestcreatewithoptions/datalakepathclienttestcreatewithoptions" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "0f3d271c-2eb5-4ae9-5892-1823d52a5c2e", + "x-ms-version": "2021-04-10" + }, + "Method": "DELETE", + "Response": { + "BODY": "", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202", + "content-length": "0", + "date": "Thu, 22 Sep 2022 08:15:27 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "0f3d271c-2eb5-4ae9-5892-1823d52a5c2e", + "x-ms-request-id": "1b7c3069-801e-0098-1a5b-cef2ce000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net/datalakepathclienttestcreatewithoptions?restype=container" + } + ] +} diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeServiceClientTest.GetProperties.json b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeServiceClientTest.GetProperties.json new file mode 100644 index 0000000000..fd3652f422 --- /dev/null +++ b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeServiceClientTest.GetProperties.json @@ -0,0 +1,25 @@ +{ + "networkCallRecords": [ + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "4ab022bd-238e-47ef-6d84-52a8364d6bf5", + "x-ms-version": "2021-04-10" + }, + "Method": "GET", + "Response": { + "BODY": "1.0falsefalsefalsefalse1.0truetruetrue71.0falsefalsetrue7falsefalse2021-06-08", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-type": "application/xml", + "date": "Tue, 27 Sep 2022 03:01:22 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "4ab022bd-238e-47ef-6d84-52a8364d6bf5", + "x-ms-request-id": "03af39bd-601e-0080-031d-d22da9000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net?comp=properties&restype=service" + } + ] +} diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeServiceClientTest.ListFileSystemsSegment.json b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeServiceClientTest.ListFileSystemsSegment.json index 9596a5d006..7deaa0747a 100644 --- a/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeServiceClientTest.ListFileSystemsSegment.json +++ b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeServiceClientTest.ListFileSystemsSegment.json @@ -2,9 +2,9 @@ "networkCallRecords": [ { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "bf53e4c5-25ec-4e68-726a-60228c7cd73f", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "310854f2-ce79-46ae-51d6-087239c131e8", + "x-ms-version": "2021-04-10" }, "Method": "PUT", "Response": { @@ -12,21 +12,21 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", - "etag": "\"0x8D9C4E91C558D96\"", - "last-modified": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:39 GMT", + "etag": "\"0x8DA99E307B315D2\"", + "last-modified": "Mon, 19 Sep 2022 02:02:39 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "bf53e4c5-25ec-4e68-726a-60228c7cd73f", - "x-ms-request-id": "4b990357-b01e-0030-50d1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "310854f2-ce79-46ae-51d6-087239c131e8", + "x-ms-request-id": "78851512-a01e-0036-27cb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmea0?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "917bdd8e-fdf2-41a2-553b-7080cdbc8247", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "1363400b-85b6-41e3-4372-6e33c9ae451a", + "x-ms-version": "2021-04-10" }, "Method": "PUT", "Response": { @@ -34,21 +34,21 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", - "etag": "\"0x8D9C4E91C5B8030\"", - "last-modified": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:39 GMT", + "etag": "\"0x8DA99E308112D7D\"", + "last-modified": "Mon, 19 Sep 2022 02:02:39 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "917bdd8e-fdf2-41a2-553b-7080cdbc8247", - "x-ms-request-id": "4b990370-b01e-0030-66d1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "1363400b-85b6-41e3-4372-6e33c9ae451a", + "x-ms-request-id": "788516e3-a01e-0036-59cb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmeb0?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "863b9955-4183-4b71-6f4a-c2b39c70012b", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "ff9c7bc1-aa9c-4a23-6de8-6a06aac863d3", + "x-ms-version": "2021-04-10" }, "Method": "PUT", "Response": { @@ -56,21 +56,21 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", - "etag": "\"0x8D9C4E91C5FC557\"", - "last-modified": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:40 GMT", + "etag": "\"0x8DA99E308516153\"", + "last-modified": "Mon, 19 Sep 2022 02:02:40 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "863b9955-4183-4b71-6f4a-c2b39c70012b", - "x-ms-request-id": "4b990384-b01e-0030-77d1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "ff9c7bc1-aa9c-4a23-6de8-6a06aac863d3", + "x-ms-request-id": "78851868-a01e-0036-1acb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmea1?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "66a23a38-8a9a-4fda-5360-ab6018123eaa", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "5eaba000-6a08-48f9-4c8d-d42d97306edb", + "x-ms-version": "2021-04-10" }, "Method": "PUT", "Response": { @@ -78,21 +78,21 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", - "etag": "\"0x8D9C4E91C64318A\"", - "last-modified": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:40 GMT", + "etag": "\"0x8DA99E308825522\"", + "last-modified": "Mon, 19 Sep 2022 02:02:40 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "66a23a38-8a9a-4fda-5360-ab6018123eaa", - "x-ms-request-id": "4b990398-b01e-0030-09d1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "5eaba000-6a08-48f9-4c8d-d42d97306edb", + "x-ms-request-id": "788519e0-a01e-0036-78cb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmeb1?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "f76a8403-9342-4cb2-5005-ea4a4eecce57", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "c268d310-da0a-44b3-6174-050703c11fb5", + "x-ms-version": "2021-04-10" }, "Method": "PUT", "Response": { @@ -100,21 +100,21 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", - "etag": "\"0x8D9C4E91C684F9A\"", - "last-modified": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:40 GMT", + "etag": "\"0x8DA99E308B1E99E\"", + "last-modified": "Mon, 19 Sep 2022 02:02:40 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "f76a8403-9342-4cb2-5005-ea4a4eecce57", - "x-ms-request-id": "4b9903a7-b01e-0030-16d1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "c268d310-da0a-44b3-6174-050703c11fb5", + "x-ms-request-id": "78851af5-a01e-0036-7dcb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmea2?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "0ca86a5b-3323-4b00-4676-e3341a6b0580", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "a362d29c-aa6c-49d4-66ea-5523a9e23e66", + "x-ms-version": "2021-04-10" }, "Method": "PUT", "Response": { @@ -122,21 +122,21 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", - "etag": "\"0x8D9C4E91C6DCD0A\"", - "last-modified": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:41 GMT", + "etag": "\"0x8DA99E308E48AE7\"", + "last-modified": "Mon, 19 Sep 2022 02:02:41 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "0ca86a5b-3323-4b00-4676-e3341a6b0580", - "x-ms-request-id": "4b9903bd-b01e-0030-28d1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "a362d29c-aa6c-49d4-66ea-5523a9e23e66", + "x-ms-request-id": "78851c17-a01e-0036-0acb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmeb2?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "2279452a-9291-4159-41ce-a0465314a9aa", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "1fce1c5e-3775-406f-7727-ee5f769b3b8b", + "x-ms-version": "2021-04-10" }, "Method": "PUT", "Response": { @@ -144,21 +144,21 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", - "etag": "\"0x8D9C4E91C721241\"", - "last-modified": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:41 GMT", + "etag": "\"0x8DA99E309141F6E\"", + "last-modified": "Mon, 19 Sep 2022 02:02:41 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "2279452a-9291-4159-41ce-a0465314a9aa", - "x-ms-request-id": "4b9903ca-b01e-0030-34d1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "1fce1c5e-3775-406f-7727-ee5f769b3b8b", + "x-ms-request-id": "78851d0f-a01e-0036-6ecb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmea3?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "495f60b3-52e2-4fa7-45a0-7a92622f5e4a", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "020cdf3a-63cd-43eb-5f44-6ef046ca9f08", + "x-ms-version": "2021-04-10" }, "Method": "PUT", "Response": { @@ -166,21 +166,21 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", - "etag": "\"0x8D9C4E91C767E5F\"", - "last-modified": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:41 GMT", + "etag": "\"0x8DA99E30943B3D7\"", + "last-modified": "Mon, 19 Sep 2022 02:02:41 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "495f60b3-52e2-4fa7-45a0-7a92622f5e4a", - "x-ms-request-id": "4b9903d4-b01e-0030-3dd1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "020cdf3a-63cd-43eb-5f44-6ef046ca9f08", + "x-ms-request-id": "78851e8c-a01e-0036-56cb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmeb3?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "887208f0-9813-4a11-5373-2347240dc6d1", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "f768fad7-e31d-431d-719e-dd5c16c84adc", + "x-ms-version": "2021-04-10" }, "Method": "PUT", "Response": { @@ -188,21 +188,21 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", - "etag": "\"0x8D9C4E91C7AC385\"", - "last-modified": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:42 GMT", + "etag": "\"0x8DA99E30977B482\"", + "last-modified": "Mon, 19 Sep 2022 02:02:42 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "887208f0-9813-4a11-5373-2347240dc6d1", - "x-ms-request-id": "4b9903e4-b01e-0030-4cd1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "f768fad7-e31d-431d-719e-dd5c16c84adc", + "x-ms-request-id": "78851ffe-a01e-0036-30cb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmea4?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "e21707e2-aa61-4558-72ba-4d39c8fbb592", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "a62399b5-59b8-434a-55de-defacbdacad8", + "x-ms-version": "2021-04-10" }, "Method": "PUT", "Response": { @@ -210,84 +210,84 @@ "REASON_PHRASE": "Created", "STATUS_CODE": "201", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", - "etag": "\"0x8D9C4E91C7EBA8B\"", - "last-modified": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:42 GMT", + "etag": "\"0x8DA99E309A6D3CE\"", + "last-modified": "Mon, 19 Sep 2022 02:02:42 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "e21707e2-aa61-4558-72ba-4d39c8fbb592", - "x-ms-request-id": "4b9903fd-b01e-0030-61d1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "a62399b5-59b8-434a-55de-defacbdacad8", + "x-ms-request-id": "78852132-a01e-0036-4dcb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmeb4?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "aeba04e9-d97d-4dc3-6ebf-761ed23dcd0a", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "45b66566-3378-4bd3-70b7-3f7630dd260b", + "x-ms-version": "2021-04-10" }, "Method": "GET", "Response": { - "BODY": "datalakeserviceclienttestlistfilesystemssegmea0Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C558D96\"unlockedavailable$account-encryption-keyfalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea1Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C5FC557\"unlockedavailable$account-encryption-keyfalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea2Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C684F9A\"unlockedavailable$account-encryption-keyfalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea3Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C721241\"unlockedavailable$account-encryption-keyfalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea4Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C7AC385\"unlockedavailable$account-encryption-keyfalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmeb0Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C5B8030\"unlockedavailable$account-encryption-keyfalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmeb1Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C64318A\"unlockedavailable$account-encryption-keyfalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmeb2Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C6DCD0A\"unlockedavailable$account-encryption-keyfalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmeb3Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C767E5F\"unlockedavailable$account-encryption-keyfalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmeb4Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C7EBA8B\"unlockedavailable$account-encryption-keyfalsefalsefalse", + "BODY": "datalakeserviceclienttestlistfilesystemssegmea0Mon, 19 Sep 2022 02:02:39 GMT\"0x8DA99E307B315D2\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea1Mon, 19 Sep 2022 02:02:40 GMT\"0x8DA99E308516153\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea2Mon, 19 Sep 2022 02:02:40 GMT\"0x8DA99E308B1E99E\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea3Mon, 19 Sep 2022 02:02:41 GMT\"0x8DA99E309141F6E\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea4Mon, 19 Sep 2022 02:02:42 GMT\"0x8DA99E30977B482\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmeb0Mon, 19 Sep 2022 02:02:39 GMT\"0x8DA99E308112D7D\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmeb1Mon, 19 Sep 2022 02:02:40 GMT\"0x8DA99E308825522\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmeb2Mon, 19 Sep 2022 02:02:41 GMT\"0x8DA99E308E48AE7\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmeb3Mon, 19 Sep 2022 02:02:41 GMT\"0x8DA99E30943B3D7\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmeb4Mon, 19 Sep 2022 02:02:42 GMT\"0x8DA99E309A6D3CE\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse", "REASON_PHRASE": "OK", "STATUS_CODE": "200", "content-type": "application/xml", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:42 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", "transfer-encoding": "chunked", - "x-ms-client-request-id": "aeba04e9-d97d-4dc3-6ebf-761ed23dcd0a", - "x-ms-request-id": "4b99040c-b01e-0030-6ed1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "45b66566-3378-4bd3-70b7-3f7630dd260b", + "x-ms-request-id": "78852219-a01e-0036-20cb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net?comp=list" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "9d9e768f-9ee3-45b3-54fe-2e98860d3614", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "f1918a86-b048-481e-4370-69b8f1ad8b3b", + "x-ms-version": "2021-04-10" }, "Method": "GET", "Response": { - "BODY": "datalakeserviceclienttestlistfilesystemssegmeadatalakeserviceclienttestlistfilesystemssegmea0Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C558D96\"unlockedavailable$account-encryption-keyfalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea1Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C5FC557\"unlockedavailable$account-encryption-keyfalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea2Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C684F9A\"unlockedavailable$account-encryption-keyfalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea3Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C721241\"unlockedavailable$account-encryption-keyfalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea4Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C7AC385\"unlockedavailable$account-encryption-keyfalsefalsefalse", + "BODY": "datalakeserviceclienttestlistfilesystemssegmeadatalakeserviceclienttestlistfilesystemssegmea0Mon, 19 Sep 2022 02:02:39 GMT\"0x8DA99E307B315D2\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea1Mon, 19 Sep 2022 02:02:40 GMT\"0x8DA99E308516153\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea2Mon, 19 Sep 2022 02:02:40 GMT\"0x8DA99E308B1E99E\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea3Mon, 19 Sep 2022 02:02:41 GMT\"0x8DA99E309141F6E\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea4Mon, 19 Sep 2022 02:02:42 GMT\"0x8DA99E30977B482\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse", "REASON_PHRASE": "OK", "STATUS_CODE": "200", "content-type": "application/xml", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:43 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", "transfer-encoding": "chunked", - "x-ms-client-request-id": "9d9e768f-9ee3-45b3-54fe-2e98860d3614", - "x-ms-request-id": "4b990415-b01e-0030-77d1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "f1918a86-b048-481e-4370-69b8f1ad8b3b", + "x-ms-request-id": "78852420-a01e-0036-09cb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net?comp=list&prefix=datalakeserviceclienttestlistfilesystemssegmea" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "dd5bf53c-180e-4700-767d-bca8f65603da", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "2b915247-b739-4b57-7a13-f1e8edd3f76c", + "x-ms-version": "2021-04-10" }, "Method": "GET", "Response": { - "BODY": "2datalakeserviceclienttestlistfilesystemssegmea0Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C558D96\"unlockedavailable$account-encryption-keyfalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea1Wed, 22 Dec 2021 01:19:33 GMT\"0x8D9C4E91C5FC557\"unlockedavailable$account-encryption-keyfalsefalsefalse/datalakelivenow/datalakeserviceclienttestlistfilesystemssegmea2", + "BODY": "2datalakeserviceclienttestlistfilesystemssegmea0Mon, 19 Sep 2022 02:02:39 GMT\"0x8DA99E307B315D2\"unlockedavailable$account-encryption-keyfalsefalsefalsefalsedatalakeserviceclienttestlistfilesystemssegmea1Mon, 19 Sep 2022 02:02:40 GMT\"0x8DA99E308516153\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse/zchangdatalake/datalakeserviceclienttestlistfilesystemssegmea2", "REASON_PHRASE": "OK", "STATUS_CODE": "200", "content-type": "application/xml", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:43 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", "transfer-encoding": "chunked", - "x-ms-client-request-id": "dd5bf53c-180e-4700-767d-bca8f65603da", - "x-ms-request-id": "4b990420-b01e-0030-02d1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "2b915247-b739-4b57-7a13-f1e8edd3f76c", + "x-ms-request-id": "788525c2-a01e-0036-12cb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net?comp=list&maxresults=2" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "a5048e62-0520-4fe7-6dec-ab0a2d55b0f4", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "57fb18e6-0df1-4c98-48f7-e127ebf3961c", + "x-ms-version": "2021-04-10" }, "Method": "DELETE", "Response": { @@ -295,19 +295,19 @@ "REASON_PHRASE": "Accepted", "STATUS_CODE": "202", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:44 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "a5048e62-0520-4fe7-6dec-ab0a2d55b0f4", - "x-ms-request-id": "4b990425-b01e-0030-06d1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "57fb18e6-0df1-4c98-48f7-e127ebf3961c", + "x-ms-request-id": "788526af-a01e-0036-6dcb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmea0?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "147b4502-e3a5-4bed-40cd-9d9299272688", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "0bc8f713-b433-4829-7c00-7ed23ee9575f", + "x-ms-version": "2021-04-10" }, "Method": "DELETE", "Response": { @@ -315,19 +315,19 @@ "REASON_PHRASE": "Accepted", "STATUS_CODE": "202", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:44 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "147b4502-e3a5-4bed-40cd-9d9299272688", - "x-ms-request-id": "4b99042c-b01e-0030-0dd1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "0bc8f713-b433-4829-7c00-7ed23ee9575f", + "x-ms-request-id": "78852798-a01e-0036-42cb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmea1?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "b1f24459-581c-444d-7768-f18f48058170", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "178eb256-dad1-4e63-4faf-1a44b7f2543a", + "x-ms-version": "2021-04-10" }, "Method": "DELETE", "Response": { @@ -335,19 +335,19 @@ "REASON_PHRASE": "Accepted", "STATUS_CODE": "202", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:44 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "b1f24459-581c-444d-7768-f18f48058170", - "x-ms-request-id": "4b990437-b01e-0030-18d1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "178eb256-dad1-4e63-4faf-1a44b7f2543a", + "x-ms-request-id": "788528b0-a01e-0036-3bcb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmea2?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "89f523bc-0d08-4a1f-5333-edd04f4bec17", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "896bc83a-5b7c-41c5-52cf-8bd9853b83a6", + "x-ms-version": "2021-04-10" }, "Method": "DELETE", "Response": { @@ -355,19 +355,19 @@ "REASON_PHRASE": "Accepted", "STATUS_CODE": "202", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:45 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "89f523bc-0d08-4a1f-5333-edd04f4bec17", - "x-ms-request-id": "4b99043d-b01e-0030-1dd1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "896bc83a-5b7c-41c5-52cf-8bd9853b83a6", + "x-ms-request-id": "7885299b-a01e-0036-05cb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmea3?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "88db7494-cac3-4d30-7382-a888662c6ad3", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "1a769cfa-7205-4cf0-4c95-e6371db3c543", + "x-ms-version": "2021-04-10" }, "Method": "DELETE", "Response": { @@ -375,19 +375,19 @@ "REASON_PHRASE": "Accepted", "STATUS_CODE": "202", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:45 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "88db7494-cac3-4d30-7382-a888662c6ad3", - "x-ms-request-id": "4b990442-b01e-0030-22d1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "1a769cfa-7205-4cf0-4c95-e6371db3c543", + "x-ms-request-id": "78852a8c-a01e-0036-68cb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmea4?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "864c74f8-88b1-4542-4249-e9d32993fea5", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "97fe93d1-0a6b-4913-5355-5a8ec21283d6", + "x-ms-version": "2021-04-10" }, "Method": "DELETE", "Response": { @@ -395,19 +395,19 @@ "REASON_PHRASE": "Accepted", "STATUS_CODE": "202", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:45 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "864c74f8-88b1-4542-4249-e9d32993fea5", - "x-ms-request-id": "4b99044b-b01e-0030-2bd1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "97fe93d1-0a6b-4913-5355-5a8ec21283d6", + "x-ms-request-id": "78852c3f-a01e-0036-75cb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmeb0?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "c5590fb7-82b7-4088-7c40-b671d288a647", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "bf519a38-36b8-49e4-5ec9-1dd89e7ad736", + "x-ms-version": "2021-04-10" }, "Method": "DELETE", "Response": { @@ -415,19 +415,19 @@ "REASON_PHRASE": "Accepted", "STATUS_CODE": "202", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:45 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "c5590fb7-82b7-4088-7c40-b671d288a647", - "x-ms-request-id": "4b990451-b01e-0030-31d1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "bf519a38-36b8-49e4-5ec9-1dd89e7ad736", + "x-ms-request-id": "78852e02-a01e-0036-0fcb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmeb1?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "fd37808c-25f7-4847-406e-5f76c41d3afa", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "1020fc6a-79c8-48fa-6b06-641436621490", + "x-ms-version": "2021-04-10" }, "Method": "DELETE", "Response": { @@ -435,19 +435,19 @@ "REASON_PHRASE": "Accepted", "STATUS_CODE": "202", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:46 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "fd37808c-25f7-4847-406e-5f76c41d3afa", - "x-ms-request-id": "4b990459-b01e-0030-39d1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "1020fc6a-79c8-48fa-6b06-641436621490", + "x-ms-request-id": "78852f14-a01e-0036-0ccb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmeb2?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "0d459a84-32ba-41d8-4361-3937776e6e01", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "a9052ccc-e02a-4aef-710a-0b21a9f473e6", + "x-ms-version": "2021-04-10" }, "Method": "DELETE", "Response": { @@ -455,19 +455,19 @@ "REASON_PHRASE": "Accepted", "STATUS_CODE": "202", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:46 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "0d459a84-32ba-41d8-4361-3937776e6e01", - "x-ms-request-id": "4b99045c-b01e-0030-3cd1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "a9052ccc-e02a-4aef-710a-0b21a9f473e6", + "x-ms-request-id": "78852fd8-a01e-0036-43cb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmeb3?restype=container" }, { "Headers": { - "user-agent": "azsdk-cpp-storage-blobs/12.2.1 (Linux 5.4.0-1063-azure x86_64 #66~18.04.1-Ubuntu SMP Thu Oct 21 09:59:28 UTC 2021)", - "x-ms-client-request-id": "3395363d-006d-4cc9-6bfc-576bd439bdd4", - "x-ms-version": "2020-02-10" + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "cb9175c7-7e21-4e00-6fc0-6a203318f2d5", + "x-ms-version": "2021-04-10" }, "Method": "DELETE", "Response": { @@ -475,11 +475,11 @@ "REASON_PHRASE": "Accepted", "STATUS_CODE": "202", "content-length": "0", - "date": "Wed, 22 Dec 2021 01:19:33 GMT", + "date": "Mon, 19 Sep 2022 02:02:46 GMT", "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", - "x-ms-client-request-id": "3395363d-006d-4cc9-6bfc-576bd439bdd4", - "x-ms-request-id": "4b990462-b01e-0030-42d1-f67b20000000", - "x-ms-version": "2020-02-10" + "x-ms-client-request-id": "cb9175c7-7e21-4e00-6fc0-6a203318f2d5", + "x-ms-request-id": "788530b0-a01e-0036-80cb-cb5fdf000000", + "x-ms-version": "2021-04-10" }, "Url": "https://REDACTED.blob.core.windows.net/datalakeserviceclienttestlistfilesystemssegmeb4?restype=container" } diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeServiceClientTest.ListSystemFileSystems.json b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeServiceClientTest.ListSystemFileSystems.json new file mode 100644 index 0000000000..55aeab96c2 --- /dev/null +++ b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeServiceClientTest.ListSystemFileSystems.json @@ -0,0 +1,25 @@ +{ + "networkCallRecords": [ + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "f88eba0a-e316-459d-7a43-322398709e83", + "x-ms-version": "2021-04-10" + }, + "Method": "GET", + "Response": { + "BODY": "$logsMon, 15 Aug 2022 08:45:51 GMT\"0x8DA7E9A8EB2CBB3\"unlockedavailable$account-encryption-keyfalsefalsefalsefalse", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-type": "application/xml", + "date": "Mon, 19 Sep 2022 02:02:47 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "f88eba0a-e316-459d-7a43-322398709e83", + "x-ms-request-id": "788531a2-a01e-0036-5ecb-cb5fdf000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net?comp=list&include=system" + } + ] +} diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeServiceClientTest.SetProperties.json b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeServiceClientTest.SetProperties.json new file mode 100644 index 0000000000..2b273d75e3 --- /dev/null +++ b/sdk/storage/azure-storage-files-datalake/test/ut/recordings/DataLakeServiceClientTest.SetProperties.json @@ -0,0 +1,88 @@ +{ + "networkCallRecords": [ + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "c78bf5fa-f301-4939-6993-61a1345f6318", + "x-ms-version": "2021-04-10" + }, + "Method": "GET", + "Response": { + "BODY": "1.0falsefalsefalsefalse1.0truetruetrue71.0falsefalsetrue7falsefalse2021-06-08", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-type": "application/xml", + "date": "Tue, 27 Sep 2022 03:01:22 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "c78bf5fa-f301-4939-6993-61a1345f6318", + "x-ms-request-id": "03af3a6a-601e-0080-161d-d22da9000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net?comp=properties&restype=service" + }, + { + "Headers": { + "content-type": "application/xml; charset=UTF-8", + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "37898e72-ed62-4cb8-63d8-1f2efd991379", + "x-ms-version": "2021-04-10" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:23 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "37898e72-ed62-4cb8-63d8-1f2efd991379", + "x-ms-request-id": "03af3b21-601e-0080-331d-d22da9000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net?comp=properties&restype=service" + }, + { + "Headers": { + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "90d05d28-d31a-4083-5684-5a9a119077ef", + "x-ms-version": "2021-04-10" + }, + "Method": "GET", + "Response": { + "BODY": "1.0truetruetruetrue31.0truetruetrue41.0truetruetrue4GET,PUThttp://www.example1.comx-ms-header1,x-ms-header2x-ms-header310DELETEhttp://www.example2.comx-ms-header1x-ms-header2,x-ms-header320true7falsetrueindex.html404.html2021-06-08", + "REASON_PHRASE": "OK", + "STATUS_CODE": "200", + "content-type": "application/xml", + "date": "Tue, 27 Sep 2022 03:01:33 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "transfer-encoding": "chunked", + "x-ms-client-request-id": "90d05d28-d31a-4083-5684-5a9a119077ef", + "x-ms-request-id": "03af5887-601e-0080-551d-d22da9000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net?comp=properties&restype=service" + }, + { + "Headers": { + "content-type": "application/xml; charset=UTF-8", + "user-agent": "azsdk-cpp-storage-blobs/12.7.0-beta.1 (Windows 10 Enterprise 6.3 22000 22000.1.amd64fre.co_release.210604-1628)", + "x-ms-client-request-id": "efa1718f-4308-489a-6e79-306563b7d7c4", + "x-ms-version": "2021-04-10" + }, + "Method": "PUT", + "Response": { + "BODY": "", + "REASON_PHRASE": "Accepted", + "STATUS_CODE": "202", + "content-length": "0", + "date": "Tue, 27 Sep 2022 03:01:34 GMT", + "server": "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0", + "x-ms-client-request-id": "efa1718f-4308-489a-6e79-306563b7d7c4", + "x-ms-request-id": "03af5926-601e-0080-6b1d-d22da9000000", + "x-ms-version": "2021-04-10" + }, + "Url": "https://REDACTED.blob.core.windows.net?comp=properties&restype=service" + } + ] +} diff --git a/sdk/storage/test-resources-post.ps1 b/sdk/storage/test-resources-post.ps1 index 539c242e10..a02df05f80 100644 --- a/sdk/storage/test-resources-post.ps1 +++ b/sdk/storage/test-resources-post.ps1 @@ -8,6 +8,8 @@ param( New-AzStorageEncryptionScope -ResourceGroupName $ResourceGroupName -StorageAccountName $DeploymentOutputs['ACCOUNT_NAME'] -EncryptionScopeName "EncryptionScopeForTest" -StorageEncryption +New-AzStorageEncryptionScope -ResourceGroupName $ResourceGroupName -StorageAccountName $DeploymentOutputs['DATALAKE_ACCOUNT_NAME'] -EncryptionScopeName "EncryptionScopeForTest" -StorageEncryption + # This script is used to wait until XCache is refreshed for the service properties (30s), and role assignment takes effect (300s). Start-Sleep -s 300 diff --git a/sdk/storage/test-resources.json b/sdk/storage/test-resources.json index b785415ec2..1e4c36bb03 100644 --- a/sdk/storage/test-resources.json +++ b/sdk/storage/test-resources.json @@ -207,6 +207,10 @@ "kind": "StorageV2", "properties": { "isHnsEnabled": true, + "deleteRetentionPolicy": { + "enabled": true, + "days": 7 + }, "cors": { "corsRules": [ { diff --git a/vcpkg.json b/vcpkg.json index 3a5459cca4..1e586685dd 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -17,6 +17,10 @@ "name": "opentelemetry-cpp", "platform": "!uwp", "version>=": "1.3.0" + }, + { + "name": "wil", + "platform": "windows" } ] }