From 1da4dae17e744dbf104ddc154ae4bf18c3f95744 Mon Sep 17 00:00:00 2001 From: microzchang <110015819+microzchang@users.noreply.github.com> Date: Fri, 11 Oct 2024 10:48:52 +0800 Subject: [PATCH] Storage STG96 Features (#6078) * update swagger. (#6021) * Storage/STG96 File Ace for Copy (#6027) * file ace for copy * update recording * add back line * Storage/STG96 Provisioned v2 billing model for Azure Files (#6030) * add feature * add quota testing * update tests * Fix spell * Storage/STG96 ProvisionV2 latest swagger update (#6075) * Update to latest swagger * update cspell * Storage STG96/immpolicy snapshot version support (#6077) * update test cases * update record * update account sas version * Update test case * update comment * fix cspell * Update test resource * udpate test resource * update test resource * revert test resource --- .vscode/cspell.json | 1 + sdk/storage/assets.json | 2 +- .../azure-storage-blobs/swagger/README.md | 18 ++ .../test/ut/block_blob_client_test.cpp | 49 ++++ .../src/account_sas_builder.cpp | 2 +- .../test/ut/datalake_file_client_test.cpp | 3 +- .../test/ut/datalake_path_client_test.cpp | 6 +- .../storage/files/shares/rest_client.hpp | 107 ++++++- .../storage/files/shares/share_options.hpp | 38 ++- .../src/rest_client.cpp | 274 +++++++++++++++--- .../src/share_client.cpp | 11 + .../src/share_file_client.cpp | 1 + .../swagger/README.md | 47 ++- .../test/ut/share_client_test.cpp | 63 ++++ .../test/ut/share_file_client_test.cpp | 94 ++++++ .../test/ut/share_service_client_test.cpp | 30 ++ 16 files changed, 688 insertions(+), 58 deletions(-) diff --git a/.vscode/cspell.json b/.vscode/cspell.json index c824bd487..3f80b06b9 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -166,6 +166,7 @@ "mbedtls", "mchelnokov", "mbps", + "mebibytes", "MHSM", "mmdc", "mmspecial", diff --git a/sdk/storage/assets.json b/sdk/storage/assets.json index 5828dec16..1979cddfd 100644 --- a/sdk/storage/assets.json +++ b/sdk/storage/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "cpp", "TagPrefix": "cpp/storage", - "Tag": "cpp/storage_90767ef070" + "Tag": "cpp/storage_f9f7bb54df" } diff --git a/sdk/storage/azure-storage-blobs/swagger/README.md b/sdk/storage/azure-storage-blobs/swagger/README.md index e7483ffc5..c3bbde379 100644 --- a/sdk/storage/azure-storage-blobs/swagger/README.md +++ b/sdk/storage/azure-storage-blobs/swagger/README.md @@ -1722,6 +1722,20 @@ directive: }; $.headers["x-ms-immutability-policy-until-date"]["x-ms-client-path"] = "ImmutabilityPolicy.ExpiresOn"; $.headers["x-ms-immutability-policy-mode"]["x-ms-client-path"] = "ImmutabilityPolicy.PolicyMode"; + - from: swagger-document + where: $["x-ms-paths"]["/{containerName}/{blob}?comp=immutabilityPolicies"].put.parameters + transform: > + $ = $.filter(p => !p["$ref"] || (!p["$ref"].endsWith("#/parameters/Snapshot") && !p["$ref"].endsWith("#/parameters/VersionId"))); +``` + +### DeleteBlobImmutabilityPolicy + +```yaml +directive: + - from: swagger-document + where: $["x-ms-paths"]["/{containerName}/{blob}?comp=immutabilityPolicies"].delete.parameters + transform: > + $ = $.filter(p => !p["$ref"] || (!p["$ref"].endsWith("#/parameters/Snapshot") && !p["$ref"].endsWith("#/parameters/VersionId"))); ``` ### SetLegalHold @@ -1732,6 +1746,10 @@ directive: where: $["x-ms-paths"]["/{containerName}/{blob}?comp=legalhold"].put.responses["200"].headers transform: > $["x-ms-legal-hold"]["x-ms-client-name"] = "HasLegalHold"; + - from: swagger-document + where: $["x-ms-paths"]["/{containerName}/{blob}?comp=legalhold"].put.parameters + transform: > + $ = $.filter(p => !p["$ref"] || (!p["$ref"].endsWith("#/parameters/Snapshot") && !p["$ref"].endsWith("#/parameters/VersionId"))); ``` diff --git a/sdk/storage/azure-storage-blobs/test/ut/block_blob_client_test.cpp b/sdk/storage/azure-storage-blobs/test/ut/block_blob_client_test.cpp index 2a2933bbc..03c76ae6d 100644 --- a/sdk/storage/azure-storage-blobs/test/ut/block_blob_client_test.cpp +++ b/sdk/storage/azure-storage-blobs/test/ut/block_blob_client_test.cpp @@ -2133,4 +2133,53 @@ namespace Azure { namespace Storage { namespace Test { = Blobs::BlockBlobClient(m_blockBlobClient->GetUrl(), keyCredential, clientOptions); EXPECT_NO_THROW(blockBlobClient.GetProperties()); } + + TEST_F(BlockBlobClientTest, ImmutabilityPolicyLegalHoldWithSnapshot_PLAYBACKONLY_) + { + const auto ImmutabilityMaxLength = std::chrono::seconds(30); + + auto createSnapshotResult = m_blockBlobClient->CreateSnapshot(); + auto snapshotClient = m_blockBlobClient->WithSnapshot(createSnapshotResult.Value.Snapshot); + Blobs::Models::BlobImmutabilityPolicy policy; + policy.ExpiresOn = Azure::DateTime::Parse( + Azure::DateTime(std::chrono::system_clock::now() + ImmutabilityMaxLength) + .ToString(Azure::DateTime::DateFormat::Rfc1123), + Azure::DateTime::DateFormat::Rfc1123); + policy.PolicyMode = Blobs::Models::BlobImmutabilityPolicyMode::Unlocked; + auto setPolicyResponse = snapshotClient.SetImmutabilityPolicy(policy); + EXPECT_EQ(setPolicyResponse.Value.ImmutabilityPolicy, policy); + auto blobProperties = snapshotClient.GetProperties().Value; + ASSERT_TRUE(blobProperties.ImmutabilityPolicy.HasValue()); + EXPECT_EQ(blobProperties.ImmutabilityPolicy.Value(), policy); + + auto setLegalHoldResponse = snapshotClient.SetLegalHold(true); + EXPECT_TRUE(setLegalHoldResponse.Value.HasLegalHold); + blobProperties = snapshotClient.GetProperties().Value; + EXPECT_TRUE(blobProperties.HasLegalHold); + } + + TEST_F(BlockBlobClientTest, ImmutabilityPolicyLegalHoldWithVersion_PLAYBACKONLY_) + { + const auto ImmutabilityMaxLength = std::chrono::seconds(30); + auto versionId + = m_blockBlobClient->SetMetadata({{"key1", "value1"}, {"key2", "value2"}}).Value.VersionId; + ASSERT_TRUE(versionId.HasValue()); + auto versionClient = m_blockBlobClient->WithVersionId(versionId.Value()); + Blobs::Models::BlobImmutabilityPolicy policy; + policy.ExpiresOn = Azure::DateTime::Parse( + Azure::DateTime(std::chrono::system_clock::now() + ImmutabilityMaxLength) + .ToString(Azure::DateTime::DateFormat::Rfc1123), + Azure::DateTime::DateFormat::Rfc1123); + policy.PolicyMode = Blobs::Models::BlobImmutabilityPolicyMode::Unlocked; + auto setPolicyResponse = versionClient.SetImmutabilityPolicy(policy); + EXPECT_EQ(setPolicyResponse.Value.ImmutabilityPolicy, policy); + auto blobProperties = versionClient.GetProperties().Value; + ASSERT_TRUE(blobProperties.ImmutabilityPolicy.HasValue()); + EXPECT_EQ(blobProperties.ImmutabilityPolicy.Value(), policy); + + auto setLegalHoldResponse = versionClient.SetLegalHold(true); + EXPECT_TRUE(setLegalHoldResponse.Value.HasLegalHold); + blobProperties = versionClient.GetProperties().Value; + EXPECT_TRUE(blobProperties.HasLegalHold); + } }}} // namespace Azure::Storage::Test diff --git a/sdk/storage/azure-storage-common/src/account_sas_builder.cpp b/sdk/storage/azure-storage-common/src/account_sas_builder.cpp index 7db748218..d774accd3 100644 --- a/sdk/storage/azure-storage-common/src/account_sas_builder.cpp +++ b/sdk/storage/azure-storage-common/src/account_sas_builder.cpp @@ -9,7 +9,7 @@ namespace Azure { namespace Storage { namespace Sas { namespace { - constexpr static const char* SasVersion = "2024-11-04"; + constexpr static const char* SasVersion = "2025-01-05"; } void AccountSasBuilder::SetPermissions(AccountSasPermissions permissions) 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 52540d755..77a8b5f7f 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 @@ -728,7 +728,8 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_TRUE(downloadResult.Details.Permissions.HasValue()); } - TEST_F(DataLakeFileClientTest, FileDownloadWithUserPrincipalName) + // Test account's aad tenant in pipeline may be not the same as UserPrincipalName aad tenant. + TEST_F(DataLakeFileClientTest, FileDownloadWithUserPrincipalName_PLAYBACKONLY_) { std::string userPrincipalName = "kat@microsoft.com"; std::string userObjectId = "72a3f86f-271f-439e-b031-25678907d381"; 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 52b528a36..cb6764fe1 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 @@ -478,7 +478,8 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_TRUE(properties.Permissions.HasValue()); } - TEST_F(DataLakePathClientTest, GetPropertiesWithUserPrincipalName) + // Test account's aad tenant in pipeline may be not the same as UserPrincipalName aad tenant. + TEST_F(DataLakePathClientTest, GetPropertiesWithUserPrincipalName_PLAYBACKONLY_) { std::string userPrincipalName = "kat@microsoft.com"; std::string userObjectId = "72a3f86f-271f-439e-b031-25678907d381"; @@ -518,7 +519,8 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_NE(it, acls.end()); } - TEST_F(DataLakePathClientTest, GetAccessControlListWithUserPrincipalName) + // Test account's aad tenant in pipeline may be not the same as UserPrincipalName aad tenant. + TEST_F(DataLakePathClientTest, GetAccessControlListWithUserPrincipalName_PLAYBACKONLY_) { std::string userPrincipalName = "kat@microsoft.com"; std::string userObjectId = "72a3f86f-271f-439e-b031-25678907d381"; diff --git a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/rest_client.hpp b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/rest_client.hpp index 3e1b741de..d22fa7886 100644 --- a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/rest_client.hpp +++ b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/rest_client.hpp @@ -32,7 +32,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * The version used for the operations to Azure storage services. */ - constexpr static const char* ApiVersion = "2024-11-04"; + constexpr static const char* ApiVersion = "2025-01-05"; } // namespace _detail namespace Models { /** @@ -380,6 +380,24 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * support. Current maximum for a file share is 10,340 MiB/sec. */ Nullable PaidBurstingMaxBandwidthMibps; + /** + * Return the calculated burst IOPS of the share. + */ + Nullable IncludedBurstIops; + /** + * Return the calculated maximum burst credits. This is not the current burst credit level, + * but the maximum burst credits the share can have. + */ + Nullable MaxBurstCreditsForIops; + /** + * Return timestamp for provisioned IOPS following existing rules for provisioned storage GiB. + */ + Nullable NextAllowedProvisionedIopsDowngradeTime; + /** + * Return timestamp for provisioned throughput following existing rules for provisioned + * storage GiB. + */ + Nullable NextAllowedProvisionedBandwidthDowngradeTime; }; /** * @brief A listed Azure Storage share item. @@ -481,6 +499,26 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * not affect the last modified time of the share. */ DateTime LastModified; + /** + * Returns the current share quota in GB. + */ + Nullable Quota; + /** + * The provisioned IOPS of the share. + */ + Nullable ShareProvisionedIops; + /** + * The provisioned throughput of the share. + */ + Nullable ShareProvisionedBandwidthMibps; + /** + * Returns the calculated burst IOPS of the share. + */ + Nullable ShareIncludedBurstIops; + /** + * Returned the calculated maximum burst credits. + */ + Nullable MaxBurstCreditsForIops; }; /** * @brief Response type for #Azure::Storage::Files::Shares::ShareClient::GetProperties. @@ -526,7 +564,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { */ Nullable NextAllowedQuotaDowngradeTime; /** - * Returns the current share provisioned bandwidth in megabits per second. + * Returns the current share provisioned bandwidth in mebibytes per second. */ Nullable ProvisionedBandwidthMBps; /** @@ -577,6 +615,23 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * support. Current maximum for a file share is 10,340 MiB/sec. */ Nullable PaidBurstingMaxBandwidthMibps; + /** + * Return the calculated burst IOPS of the share. + */ + Nullable IncludedBurstIops; + /** + * Returned the calculated maximum burst credits. This is not the current burst credit level, + * but the maximum burst credits the share can have. + */ + Nullable MaxBurstCreditsForIops; + /** + * Returns the current share next allowed provisioned iops downgrade time. + */ + Nullable NextAllowedProvisionedIopsDowngradeTime; + /** + * Returns the current share next allowed provisioned bandwidth downgrade time. + */ + Nullable NextAllowedProvisionedBandwidthDowngradeTime; }; /** * @brief Specifies the option include to delete the base share and all of its snapshots. @@ -601,6 +656,16 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * Indicates if the share was successfully deleted by this operation. */ bool Deleted = true; + /** + * Returned only for provisioned v2 file shares. Returns an approximate used storage size of + * the share, in bytes. + */ + Nullable ShareUsageBytes; + /** + * Returned only for provisioned v2 file shares. Returns an approximate used snapshot storage + * size of the share, in bytes. + */ + Nullable ShareSnapshotUsageBytes; }; namespace _detail { /** @@ -793,6 +858,39 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * the last modified time of the share. */ DateTime LastModified; + /** + * Returns the current share quota in GB. + */ + Nullable Quota; + /** + * Returns the current share provisioned IOPS. + */ + Nullable ProvisionedIops; + /** + * Returns the current share provisioned bandwidth in mebibytes per second. + */ + Nullable ProvisionedBandwidthMibps; + /** + * Return the calculated burst IOPS of the share. + */ + Nullable IncludedBurstIops; + /** + * Returned the calculated maximum burst credits. This is not the current burst credit level, + * but the maximum burst credits the share can have. + */ + Nullable MaxBurstCreditsForIops; + /** + * Returns the current share next allowed quota downgrade time. + */ + Nullable NextAllowedQuotaDowngradeTime; + /** + * Returns the current share next allowed provisioned iops downgrade time. + */ + Nullable NextAllowedProvisionedIopsDowngradeTime; + /** + * Returns the current share next allowed provisioned bandwidth downgrade time. + */ + Nullable NextAllowedProvisionedBandwidthDowngradeTime; }; /** * @brief Response type for #Azure::Storage::Files::Shares::ShareClient::SetMetadata. @@ -2063,6 +2161,8 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Nullable PaidBurstingMaxBandwidthMibps; Nullable PaidBurstingMaxIops; Nullable FileRequestIntent; + Nullable ShareProvisionedIops; + Nullable ShareProvisionedBandwidthMibps; }; static Response Create( Core::Http::_internal::HttpPipeline& pipeline, @@ -2192,6 +2292,8 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Nullable PaidBurstingMaxBandwidthMibps; Nullable PaidBurstingMaxIops; Nullable FileRequestIntent; + Nullable ShareProvisionedIops; + Nullable ShareProvisionedBandwidthMibps; }; static Response SetProperties( Core::Http::_internal::HttpPipeline& pipeline, @@ -2583,6 +2685,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::map Metadata; std::string CopySource; Nullable FilePermission; + Nullable FilePermissionFormat; Nullable FilePermissionKey; Nullable FilePermissionCopyMode; Nullable IgnoreReadOnly; diff --git a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_options.hpp b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_options.hpp index d8fc0e6e1..d3fe917f0 100644 --- a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_options.hpp +++ b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_options.hpp @@ -199,6 +199,20 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * throughput the file share can support. Current maximum for a file share is 10,340 MiB/sec. */ Nullable PaidBurstingMaxBandwidthMibps; + + /** + * Optional. Integer. Version 2025-01-05 and newer. The provisioned IOPS of the share. For SSD, + * minimum IOPS is 3,000 and maximum is 100,000. For HDD, minimum IOPS is 500 and maximum is + * 50,000. + */ + Nullable ProvisionedMaxIops; + + /** + * Optional. Integer. Version 2025-01-05 and newer. The provisioned throughput of the share. For + * SSD, minimum throughput is 125 MiB/sec and maximum is 10,340 MiB/sec. For HDD, minimum + * throughput is 60 MiB/sec and maximum is 5,125 MiB/sec. + */ + Nullable ProvisionedMaxBandwidthMibps; }; /** @@ -276,6 +290,19 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * throughput the file share can support. Current maximum for a file share is 10,340 MiB/sec. */ Nullable PaidBurstingMaxBandwidthMibps; + + /** + * Optional. Boolean. Version 2025-01-05 and newer. Sets the max provisioned IOPs for a share. + * For SSD, min IOPs is 3,000 and max is 100,000. For HDD, min IOPs is 500 and max is 50,000. + */ + Nullable ProvisionedMaxIops; + + /** + * Optional. Boolean. Version 2025-01-05 and newer. Sets the max provisioned brandwith for a + * share. For SSD, min bandwidth is 125 MiB/sec and max is 10,340 MiB/sec. For HDD, min + * bandwidth is 60 MiB/sec and max is 5,120 MiB/sec. + */ + Nullable ProvisionedMaxBandwidthMibps; }; /** @@ -715,10 +742,19 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * This permission is the security descriptor for the file specified in the Security - * Descriptor Definition Language (SDDL). If not specified, 'inherit' is used. + * Descriptor Definition Language (SDDL) or base64 encoded + * binary format. If not specified, 'inherit' is used. */ Azure::Nullable Permission; + /** + * Optional. Available for version 2024-11-04 and later. Specifies + * the format in which the permission is returned.If FilePermissionFormat is unspecified or + * explicitly set to SDDL format format, the permission will be + * returned in SDDL format. + */ + Nullable FilePermissionFormat; + /** * SMB properties to set for the destination file. */ diff --git a/sdk/storage/azure-storage-files-shares/src/rest_client.cpp b/sdk/storage/azure-storage-files-shares/src/rest_client.cpp index c9939363a..adeea96d0 100644 --- a/sdk/storage/azure-storage-files-shares/src/rest_client.cpp +++ b/sdk/storage/azure-storage-files-shares/src/rest_client.cpp @@ -319,7 +319,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.SetHeader("Content-Length", std::to_string(requestBody.Length())); request.GetUrl().AppendQueryParameter("restype", "service"); request.GetUrl().AppendQueryParameter("comp", "properties"); - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.FileRequestIntent.HasValue() && !options.FileRequestIntent.Value().ToString().empty()) { @@ -344,7 +344,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); request.GetUrl().AppendQueryParameter("restype", "service"); request.GetUrl().AppendQueryParameter("comp", "properties"); - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.FileRequestIntent.HasValue() && !options.FileRequestIntent.Value().ToString().empty()) { @@ -580,7 +580,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { _internal::UrlEncodeQueryParameter( ListSharesIncludeFlagsToString(options.Include.Value()))); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.FileRequestIntent.HasValue() && !options.FileRequestIntent.Value().ToString().empty()) { @@ -634,6 +634,10 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { kPaidBurstingEnabled, kPaidBurstingMaxIops, kPaidBurstingMaxBandwidthMibps, + kIncludedBurstIops, + kMaxBurstCreditsForIops, + kNextAllowedProvisionedIopsDowngradeTime, + kNextAllowedProvisionedBandwidthDowngradeTime, kNextMarker, }; const std::unordered_map XmlTagEnumMap{ @@ -672,6 +676,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { {"PaidBurstingEnabled", XmlTagEnum::kPaidBurstingEnabled}, {"PaidBurstingMaxIops", XmlTagEnum::kPaidBurstingMaxIops}, {"PaidBurstingMaxBandwidthMibps", XmlTagEnum::kPaidBurstingMaxBandwidthMibps}, + {"IncludedBurstIops", XmlTagEnum::kIncludedBurstIops}, + {"MaxBurstCreditsForIops", XmlTagEnum::kMaxBurstCreditsForIops}, + {"NextAllowedProvisionedIopsDowngradeTime", + XmlTagEnum::kNextAllowedProvisionedIopsDowngradeTime}, + {"NextAllowedProvisionedBandwidthDowngradeTime", + XmlTagEnum::kNextAllowedProvisionedBandwidthDowngradeTime}, {"NextMarker", XmlTagEnum::kNextMarker}, }; std::vector xmlPath; @@ -923,6 +933,40 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { vectorElement1.Details.PaidBurstingMaxBandwidthMibps = std::stoll(node.Value); } + else if ( + xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare + && xmlPath[3] == XmlTagEnum::kProperties + && xmlPath[4] == XmlTagEnum::kIncludedBurstIops) + { + vectorElement1.Details.IncludedBurstIops = std::stoll(node.Value); + } + else if ( + xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare + && xmlPath[3] == XmlTagEnum::kProperties + && xmlPath[4] == XmlTagEnum::kMaxBurstCreditsForIops) + { + vectorElement1.Details.MaxBurstCreditsForIops = std::stoll(node.Value); + } + else if ( + xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare + && xmlPath[3] == XmlTagEnum::kProperties + && xmlPath[4] == XmlTagEnum::kNextAllowedProvisionedIopsDowngradeTime) + { + vectorElement1.Details.NextAllowedProvisionedIopsDowngradeTime + = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + else if ( + xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare + && xmlPath[3] == XmlTagEnum::kProperties + && xmlPath[4] == XmlTagEnum::kNextAllowedProvisionedBandwidthDowngradeTime) + { + vectorElement1.Details.NextAllowedProvisionedBandwidthDowngradeTime + = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } else if ( xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults && xmlPath[1] == XmlTagEnum::kNextMarker) @@ -980,7 +1024,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-access-tier", options.AccessTier.Value().ToString()); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.EnabledProtocols.HasValue() && !options.EnabledProtocols.Value().ToString().empty()) { @@ -1019,6 +1063,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); } + if (options.ShareProvisionedIops.HasValue()) + { + request.SetHeader( + "x-ms-share-provisioned-iops", std::to_string(options.ShareProvisionedIops.Value())); + } + if (options.ShareProvisionedBandwidthMibps.HasValue()) + { + request.SetHeader( + "x-ms-share-provisioned-bandwidth-mibps", + std::to_string(options.ShareProvisionedBandwidthMibps.Value())); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Created) @@ -1029,6 +1084,30 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); response.LastModified = DateTime::Parse( pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("x-ms-share-quota") != 0) + { + response.Quota = std::stoll(pRawResponse->GetHeaders().at("x-ms-share-quota")); + } + if (pRawResponse->GetHeaders().count("x-ms-share-provisioned-iops") != 0) + { + response.ShareProvisionedIops + = std::stoll(pRawResponse->GetHeaders().at("x-ms-share-provisioned-iops")); + } + if (pRawResponse->GetHeaders().count("x-ms-share-provisioned-bandwidth-mibps") != 0) + { + response.ShareProvisionedBandwidthMibps + = std::stoll(pRawResponse->GetHeaders().at("x-ms-share-provisioned-bandwidth-mibps")); + } + if (pRawResponse->GetHeaders().count("x-ms-share-included-burst-iops") != 0) + { + response.ShareIncludedBurstIops + = std::stoll(pRawResponse->GetHeaders().at("x-ms-share-included-burst-iops")); + } + if (pRawResponse->GetHeaders().count("x-ms-share-max-burst-credits-for-iops") != 0) + { + response.MaxBurstCreditsForIops + = std::stoll(pRawResponse->GetHeaders().at("x-ms-share-max-burst-credits-for-iops")); + } return Response(std::move(response), std::move(pRawResponse)); } Response ShareClient::GetProperties( @@ -1044,7 +1123,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.GetUrl().AppendQueryParameter( "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value())); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -1158,6 +1237,34 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { response.PaidBurstingMaxBandwidthMibps = std::stoll( pRawResponse->GetHeaders().at("x-ms-share-paid-bursting-max-bandwidth-mibps")); } + if (pRawResponse->GetHeaders().count("x-ms-share-included-burst-iops") != 0) + { + response.IncludedBurstIops + = std::stoll(pRawResponse->GetHeaders().at("x-ms-share-included-burst-iops")); + } + if (pRawResponse->GetHeaders().count("x-ms-share-max-burst-credits-for-iops") != 0) + { + response.MaxBurstCreditsForIops + = std::stoll(pRawResponse->GetHeaders().at("x-ms-share-max-burst-credits-for-iops")); + } + if (pRawResponse->GetHeaders().count( + "x-ms-share-next-allowed-provisioned-iops-downgrade-time") + != 0) + { + response.NextAllowedProvisionedIopsDowngradeTime = DateTime::Parse( + pRawResponse->GetHeaders().at( + "x-ms-share-next-allowed-provisioned-iops-downgrade-time"), + Azure::DateTime::DateFormat::Rfc1123); + } + if (pRawResponse->GetHeaders().count( + "x-ms-share-next-allowed-provisioned-bandwidth-downgrade-time") + != 0) + { + response.NextAllowedProvisionedBandwidthDowngradeTime = DateTime::Parse( + pRawResponse->GetHeaders().at( + "x-ms-share-next-allowed-provisioned-bandwidth-downgrade-time"), + Azure::DateTime::DateFormat::Rfc1123); + } return Response(std::move(response), std::move(pRawResponse)); } Response ShareClient::Delete( @@ -1173,7 +1280,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.GetUrl().AppendQueryParameter( "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value())); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.DeleteSnapshots.HasValue() && !options.DeleteSnapshots.Value().ToString().empty()) { request.SetHeader("x-ms-delete-snapshots", options.DeleteSnapshots.Value().ToString()); @@ -1194,6 +1301,16 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { throw StorageException::CreateFromResponse(std::move(pRawResponse)); } Models::DeleteShareResult response; + if (pRawResponse->GetHeaders().count("x-ms-file-share-usage-bytes") != 0) + { + response.ShareUsageBytes + = std::stoll(pRawResponse->GetHeaders().at("x-ms-file-share-usage-bytes")); + } + if (pRawResponse->GetHeaders().count("x-ms-file-share-snapshot-usage-bytes") != 0) + { + response.ShareSnapshotUsageBytes + = std::stoll(pRawResponse->GetHeaders().at("x-ms-file-share-snapshot-usage-bytes")); + } return Response(std::move(response), std::move(pRawResponse)); } Response ShareClient::AcquireLease( @@ -1214,7 +1331,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId.Value()); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty()) { request.GetUrl().AppendQueryParameter( @@ -1253,7 +1370,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-lease-id", options.LeaseId); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty()) { request.GetUrl().AppendQueryParameter( @@ -1295,7 +1412,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId.Value()); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty()) { request.GetUrl().AppendQueryParameter( @@ -1334,7 +1451,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-lease-id", options.LeaseId); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty()) { request.GetUrl().AppendQueryParameter( @@ -1377,7 +1494,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty()) { request.GetUrl().AppendQueryParameter( @@ -1415,7 +1532,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-meta-" + p.first, p.second); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.FileRequestIntent.HasValue() && !options.FileRequestIntent.Value().ToString().empty()) { @@ -1458,7 +1575,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.SetHeader("Content-Length", std::to_string(requestBody.Length())); request.GetUrl().AppendQueryParameter("restype", "share"); request.GetUrl().AppendQueryParameter("comp", "filepermission"); - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.FileRequestIntent.HasValue() && !options.FileRequestIntent.Value().ToString().empty()) { @@ -1494,7 +1611,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.SetHeader( "x-ms-file-permission-format", options.FilePermissionFormat.Value().ToString()); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.FileRequestIntent.HasValue() && !options.FileRequestIntent.Value().ToString().empty()) { @@ -1529,7 +1646,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); request.GetUrl().AppendQueryParameter("restype", "share"); request.GetUrl().AppendQueryParameter("comp", "properties"); - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.Quota.HasValue()) { request.SetHeader("x-ms-share-quota", std::to_string(options.Quota.Value())); @@ -1575,6 +1692,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); } + if (options.ShareProvisionedIops.HasValue()) + { + request.SetHeader( + "x-ms-share-provisioned-iops", std::to_string(options.ShareProvisionedIops.Value())); + } + if (options.ShareProvisionedBandwidthMibps.HasValue()) + { + request.SetHeader( + "x-ms-share-provisioned-bandwidth-mibps", + std::to_string(options.ShareProvisionedBandwidthMibps.Value())); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -1585,6 +1713,54 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { response.ETag = ETag(pRawResponse->GetHeaders().at("ETag")); response.LastModified = DateTime::Parse( pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123); + if (pRawResponse->GetHeaders().count("x-ms-share-quota") != 0) + { + response.Quota = std::stoll(pRawResponse->GetHeaders().at("x-ms-share-quota")); + } + if (pRawResponse->GetHeaders().count("x-ms-share-provisioned-iops") != 0) + { + response.ProvisionedIops + = std::stoll(pRawResponse->GetHeaders().at("x-ms-share-provisioned-iops")); + } + if (pRawResponse->GetHeaders().count("x-ms-share-provisioned-bandwidth-mibps") != 0) + { + response.ProvisionedBandwidthMibps + = std::stoll(pRawResponse->GetHeaders().at("x-ms-share-provisioned-bandwidth-mibps")); + } + if (pRawResponse->GetHeaders().count("x-ms-share-included-burst-iops") != 0) + { + response.IncludedBurstIops + = std::stoll(pRawResponse->GetHeaders().at("x-ms-share-included-burst-iops")); + } + if (pRawResponse->GetHeaders().count("x-ms-share-max-burst-credits-for-iops") != 0) + { + response.MaxBurstCreditsForIops + = std::stoll(pRawResponse->GetHeaders().at("x-ms-share-max-burst-credits-for-iops")); + } + if (pRawResponse->GetHeaders().count("x-ms-share-next-allowed-quota-downgrade-time") != 0) + { + response.NextAllowedQuotaDowngradeTime = DateTime::Parse( + pRawResponse->GetHeaders().at("x-ms-share-next-allowed-quota-downgrade-time"), + Azure::DateTime::DateFormat::Rfc1123); + } + if (pRawResponse->GetHeaders().count( + "x-ms-share-next-allowed-provisioned-iops-downgrade-time") + != 0) + { + response.NextAllowedProvisionedIopsDowngradeTime = DateTime::Parse( + pRawResponse->GetHeaders().at( + "x-ms-share-next-allowed-provisioned-iops-downgrade-time"), + Azure::DateTime::DateFormat::Rfc1123); + } + if (pRawResponse->GetHeaders().count( + "x-ms-share-next-allowed-provisioned-bandwidth-downgrade-time") + != 0) + { + response.NextAllowedProvisionedBandwidthDowngradeTime = DateTime::Parse( + pRawResponse->GetHeaders().at( + "x-ms-share-next-allowed-provisioned-bandwidth-downgrade-time"), + Azure::DateTime::DateFormat::Rfc1123); + } return Response( std::move(response), std::move(pRawResponse)); } @@ -1601,7 +1777,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-meta-" + p.first, p.second); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -1632,7 +1808,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); request.GetUrl().AppendQueryParameter("restype", "share"); request.GetUrl().AppendQueryParameter("comp", "acl"); - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -1784,7 +1960,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.SetHeader("Content-Length", std::to_string(requestBody.Length())); request.GetUrl().AppendQueryParameter("restype", "share"); request.GetUrl().AppendQueryParameter("comp", "acl"); - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -1816,7 +1992,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); request.GetUrl().AppendQueryParameter("restype", "share"); request.GetUrl().AppendQueryParameter("comp", "stats"); - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -1907,7 +2083,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-meta-" + p.first, p.second); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.FilePermission.HasValue() && !options.FilePermission.Value().empty()) { request.SetHeader("x-ms-file-permission", options.FilePermission.Value()); @@ -2002,7 +2178,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.GetUrl().AppendQueryParameter( "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value())); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.FileRequestIntent.HasValue() && !options.FileRequestIntent.Value().ToString().empty()) { @@ -2068,7 +2244,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.SetHeader( "x-ms-allow-trailing-dot", options.AllowTrailingDot.Value() ? "true" : "false"); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.FileRequestIntent.HasValue() && !options.FileRequestIntent.Value().ToString().empty()) { @@ -2092,7 +2268,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); request.GetUrl().AppendQueryParameter("restype", "directory"); request.GetUrl().AppendQueryParameter("comp", "properties"); - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.FilePermission.HasValue() && !options.FilePermission.Value().empty()) { request.SetHeader("x-ms-file-permission", options.FilePermission.Value()); @@ -2188,7 +2364,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-meta-" + p.first, p.second); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -2242,7 +2418,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.GetUrl().AppendQueryParameter( "maxresults", std::to_string(options.MaxResults.Value())); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.Include.HasValue() && !ListFilesIncludeFlagsToString(options.Include.Value()).empty()) { @@ -2635,7 +2811,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-recursive", options.Recursive.Value() ? "true" : "false"); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -2848,7 +3024,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-recursive", options.Recursive.Value() ? "true" : "false"); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -2886,7 +3062,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); request.GetUrl().AppendQueryParameter("restype", "directory"); request.GetUrl().AppendQueryParameter("comp", "rename"); - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (!options.RenameSource.empty()) { request.SetHeader("x-ms-file-rename-source", options.RenameSource); @@ -3000,7 +3176,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.SetHeader( "x-ms-allow-trailing-dot", options.AllowTrailingDot.Value() ? "true" : "false"); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); request.SetHeader("x-ms-content-length", std::to_string(options.FileContentLength)); request.SetHeader("x-ms-type", "file"); if (options.FileContentType.HasValue() && !options.FileContentType.Value().empty()) @@ -3126,7 +3302,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.SetHeader( "x-ms-allow-trailing-dot", options.AllowTrailingDot.Value() ? "true" : "false"); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.Range.HasValue() && !options.Range.Value().empty()) { request.SetHeader("x-ms-range", options.Range.Value()); @@ -3311,7 +3487,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.GetUrl().AppendQueryParameter( "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value())); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -3449,7 +3625,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.SetHeader( "x-ms-allow-trailing-dot", options.AllowTrailingDot.Value() ? "true" : "false"); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -3476,7 +3652,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); request.GetUrl().AppendQueryParameter("comp", "properties"); - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.FileContentLength.HasValue()) { request.SetHeader("x-ms-content-length", std::to_string(options.FileContentLength.Value())); @@ -3606,7 +3782,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-meta-" + p.first, p.second); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -3650,7 +3826,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId.Value()); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -3688,7 +3864,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-lease-id", options.LeaseId); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -3729,7 +3905,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId.Value()); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -3767,7 +3943,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -3814,7 +3990,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("Content-MD5", Core::Convert::Base64Encode(options.ContentMD5.Value())); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -3901,7 +4077,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { "x-ms-source-if-none-match-crc64", Core::Convert::Base64Encode(options.SourceIfNoneMatchCrc64.Value())); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -3977,7 +4153,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { "prevsharesnapshot", _internal::UrlEncodeQueryParameter(options.Prevsharesnapshot.Value())); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.Range.HasValue() && !options.Range.Value().empty()) { request.SetHeader("x-ms-range", options.Range.Value()); @@ -4106,7 +4282,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const Core::Context& context) { auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); for (const auto& p : options.Metadata) { request.SetHeader("x-ms-meta-" + p.first, p.second); @@ -4119,6 +4295,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-file-permission", options.FilePermission.Value()); } + if (options.FilePermissionFormat.HasValue() + && !options.FilePermissionFormat.Value().ToString().empty()) + { + request.SetHeader( + "x-ms-file-permission-format", options.FilePermissionFormat.Value().ToString()); + } if (options.FilePermissionKey.HasValue() && !options.FilePermissionKey.Value().empty()) { request.SetHeader("x-ms-file-permission-key", options.FilePermissionKey.Value()); @@ -4204,7 +4386,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { "copyid", _internal::UrlEncodeQueryParameter(options.CopyId)); } request.SetHeader("x-ms-copy-action", "abort"); - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -4251,7 +4433,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.GetUrl().AppendQueryParameter( "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value())); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -4460,7 +4642,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-handle-id", options.HandleId); } - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -4497,7 +4679,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); request.GetUrl().AppendQueryParameter("comp", "rename"); - request.SetHeader("x-ms-version", "2024-11-04"); + request.SetHeader("x-ms-version", "2025-01-05"); if (!options.RenameSource.empty()) { request.SetHeader("x-ms-file-rename-source", options.RenameSource); diff --git a/sdk/storage/azure-storage-files-shares/src/share_client.cpp b/sdk/storage/azure-storage-files-shares/src/share_client.cpp index 01f3660e5..d40f8ece2 100644 --- a/sdk/storage/azure-storage-files-shares/src/share_client.cpp +++ b/sdk/storage/azure-storage-files-shares/src/share_client.cpp @@ -155,12 +155,19 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.PaidBurstingEnabled = options.EnablePaidBursting; protocolLayerOptions.PaidBurstingMaxIops = options.PaidBurstingMaxIops; protocolLayerOptions.PaidBurstingMaxBandwidthMibps = options.PaidBurstingMaxBandwidthMibps; + protocolLayerOptions.ShareProvisionedIops = options.ProvisionedMaxIops; + protocolLayerOptions.ShareProvisionedBandwidthMibps = options.ProvisionedMaxBandwidthMibps; auto result = _detail::ShareClient::Create(*m_pipeline, m_shareUrl, protocolLayerOptions, context); Models::CreateShareResult ret; ret.Created = true; ret.ETag = std::move(result.Value.ETag); ret.LastModified = std::move(result.Value.LastModified); + ret.ShareProvisionedIops = std::move(result.Value.ShareProvisionedIops); + ret.ShareProvisionedBandwidthMibps = std::move(result.Value.ShareProvisionedBandwidthMibps); + ret.ShareIncludedBurstIops = std::move(result.Value.ShareIncludedBurstIops); + ret.MaxBurstCreditsForIops = std::move(result.Value.MaxBurstCreditsForIops); + ret.Quota = std::move(result.Value.Quota); return Azure::Response( std::move(ret), std::move(result.RawResponse)); } @@ -199,6 +206,8 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { = _detail::ShareClient::Delete(*m_pipeline, m_shareUrl, protocolLayerOptions, context); Models::DeleteShareResult ret; ret.Deleted = true; + ret.ShareUsageBytes = std::move(result.Value.ShareUsageBytes); + ret.ShareSnapshotUsageBytes = std::move(result.Value.ShareSnapshotUsageBytes); return Azure::Response( std::move(ret), std::move(result.RawResponse)); } @@ -260,6 +269,8 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.PaidBurstingEnabled = options.EnablePaidBursting; protocolLayerOptions.PaidBurstingMaxIops = options.PaidBurstingMaxIops; protocolLayerOptions.PaidBurstingMaxBandwidthMibps = options.PaidBurstingMaxBandwidthMibps; + protocolLayerOptions.ShareProvisionedIops = options.ProvisionedMaxIops; + protocolLayerOptions.ShareProvisionedBandwidthMibps = options.ProvisionedMaxBandwidthMibps; return _detail::ShareClient::SetProperties( *m_pipeline, m_shareUrl, protocolLayerOptions, context); } diff --git a/sdk/storage/azure-storage-files-shares/src/share_file_client.cpp b/sdk/storage/azure-storage-files-shares/src/share_file_client.cpp index 1e5490950..b1ac59a99 100644 --- a/sdk/storage/azure-storage-files-shares/src/share_file_client.cpp +++ b/sdk/storage/azure-storage-files-shares/src/share_file_client.cpp @@ -414,6 +414,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { if (options.Permission.HasValue()) { protocolLayerOptions.FilePermission = options.Permission; + protocolLayerOptions.FilePermissionFormat = options.FilePermissionFormat; } else if (options.SmbProperties.PermissionKey.HasValue()) { diff --git a/sdk/storage/azure-storage-files-shares/swagger/README.md b/sdk/storage/azure-storage-files-shares/swagger/README.md index d0fe69848..699ed5d1a 100644 --- a/sdk/storage/azure-storage-files-shares/swagger/README.md +++ b/sdk/storage/azure-storage-files-shares/swagger/README.md @@ -9,7 +9,7 @@ package-name: azure-storage-files-shares namespace: Azure::Storage::Files::Shares output-folder: generated clear-output-folder: true -input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/storage/data-plane/Microsoft.FileStorage/stable/2024-11-04/file.json +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/storage/data-plane/Microsoft.FileStorage/stable/2025-01-05/file.json ``` ## ModelFour Options @@ -79,12 +79,12 @@ directive: "name": "ApiVersion", "modelAsString": false }, - "enum": ["2024-11-04"] + "enum": ["2025-01-05"] }; - from: swagger-document where: $.parameters transform: > - $.ApiVersionParameter.enum[0] = "2024-11-04"; + $.ApiVersionParameter.enum[0] = "2025-01-05"; ``` ### Rename Operations @@ -214,7 +214,6 @@ directive: transform: > $.ListSharesInclude.items["x-ms-enum"].name = "ListSharesIncludeFlags"; $.ListFilesInclude.items["x-ms-enum"].name = "ListFilesIncludeFlags"; - $.AccessTierOptional.enum.push("Premium"); $.AccessTierOptional["x-ms-enum"].name = "AccessTier"; $.AccessTierOptional["x-ms-enum"].modelAsString = false; $.DeleteSnapshots["x-ms-enum"].name = "DeleteSnapshotsOption"; @@ -229,6 +228,7 @@ directive: delete $.FileChangeTime.format; $.FileLastWriteTimeMode["x-ms-enum"]["values"] = [{"value": "now", "name": "Now"},{"value": "preserve", "name": "Preserve"}]; $.FileRequestIntent["x-ms-enum"]["values"] = [{"value": "__placeHolder", "name": "__placeHolder"}, {"value": "backup", "name": "Backup"}]; + $.FilePermissionFormat["enum"] = ["sddl", "binary"]; - from: swagger-document where: $.definitions transform: > @@ -306,6 +306,7 @@ directive: } }; $.SharePermission["x-namespace"] = "_detail"; + $.SharePermission["properties"]["format"]["enum"] = ["sddl", "binary"]; $.ShareEnabledProtocols["enum"] = ["Smb", "Nfs"]; $.ShareEnabledProtocols["x-ms-enum"] = {"name": "ShareProtocols", "modelAsString": false}; $.ShareEnabledProtocols["x-ms-enum"]["values"] = [{"value": "SMB", "name": "Smb"},{"value": "NFS", "name": "Nfs"}]; @@ -434,6 +435,11 @@ directive: - from: swagger-document where: $["x-ms-paths"]["/{shareName}?restype=share"].put.responses["201"] transform: > + $.headers["x-ms-share-quota"]["x-nullable"] = true; + $.headers["x-ms-share-provisioned-iops"]["x-nullable"] = true; + $.headers["x-ms-share-provisioned-bandwidth-mibps"]["x-nullable"] = true; + $.headers["x-ms-share-included-burst-iops"]["x-nullable"] = true; + $.headers["x-ms-share-max-burst-credits-for-iops"]["x-nullable"] = true; $.schema = { "type": "object", "x-ms-client-name": "CreateShareResult", @@ -444,6 +450,23 @@ directive: }; ``` +### SetShareProperties + +```yaml +directive: + - from: swagger-document + where: $["x-ms-paths"]["/{shareName}?restype=share&comp=properties"].put.responses["200"] + transform: > + $.headers["x-ms-share-quota"]["x-nullable"] = true; + $.headers["x-ms-share-provisioned-iops"]["x-nullable"] = true; + $.headers["x-ms-share-provisioned-bandwidth-mibps"]["x-nullable"] = true; + $.headers["x-ms-share-included-burst-iops"]["x-nullable"] = true; + $.headers["x-ms-share-max-burst-credits-for-iops"]["x-nullable"] = true; + $.headers["x-ms-share-next-allowed-quota-downgrade-time"]["x-nullable"] = true; + $.headers["x-ms-share-next-allowed-provisioned-iops-downgrade-time"]["x-nullable"] = true; + $.headers["x-ms-share-next-allowed-provisioned-bandwidth-downgrade-time"]["x-nullable"] = true; +``` + ### GetShareProperties ```yaml @@ -473,6 +496,10 @@ directive: $["x-ms-share-paid-bursting-enabled"]["x-nullable"] = true; $["x-ms-share-paid-bursting-max-iops"]["x-nullable"] = true; $["x-ms-share-paid-bursting-max-bandwidth-mibps"]["x-nullable"] = true; + $["x-ms-share-included-burst-iops"]["x-nullable"] = true; + $["x-ms-share-max-burst-credits-for-iops"]["x-nullable"] = true; + $["x-ms-share-next-allowed-provisioned-iops-downgrade-time"]["x-nullable"] = true; + $["x-ms-share-next-allowed-provisioned-bandwidth-downgrade-time"]["x-nullable"] = true; - from: swagger-document where: $["x-ms-paths"]["/{shareName}?restype=share"].get.responses["200"] transform: > @@ -520,6 +547,10 @@ directive: - from: swagger-document where: $["x-ms-paths"]["/{shareName}?restype=share"].delete.responses["202"] transform: > + $.headers["x-ms-file-share-usage-bytes"]["x-ms-client-name"] = "ShareUsageBytes"; + $.headers["x-ms-file-share-usage-bytes"]["x-nullable"] = true; + $.headers["x-ms-file-share-snapshot-usage-bytes"]["x-ms-client-name"] = "ShareSnapshotUsageBytes"; + $.headers["x-ms-file-share-snapshot-usage-bytes"]["x-nullable"] = true; $.schema = { "type": "object", "x-ms-client-name": "DeleteShareResult", @@ -1075,6 +1106,10 @@ directive: $.ShareItemDetails.properties["PaidBurstingEnabled"].description = "Optional. Boolean. Default if not specified is false. This property enables paid bursting."; $.ShareItemDetails.properties["PaidBurstingMaxIops"].description = "Optional. Integer. Default if not specified is the maximum IOPS the file share can support. Current maximum for a file share is 102,400 IOPS."; $.ShareItemDetails.properties["PaidBurstingMaxBandwidthMibps"].description = "Optional. Integer. Default if not specified is the maximum throughput the file share can support. Current maximum for a file share is 10,340 MiB/sec."; + $.ShareItemDetails.properties["IncludedBurstIops"].description = "Return the calculated burst IOPS of the share."; + $.ShareItemDetails.properties["MaxBurstCreditsForIops"].description = "Return the calculated maximum burst credits. This is not the current burst credit level, but the maximum burst credits the share can have."; + $.ShareItemDetails.properties["NextAllowedProvisionedIopsDowngradeTime"].description = "Return timestamp for provisioned IOPS following existing rules for provisioned storage GiB."; + $.ShareItemDetails.properties["NextAllowedProvisionedBandwidthDowngradeTime"].description = "Return timestamp for provisioned throughput following existing rules for provisioned storage GiB."; $.ShareItemInternal.properties["Name"].description = "The name of the share."; $.ShareItemInternal.properties["Snapshot"].description = "The snapshot of the share."; $.ShareItemInternal.properties["Deleted"].description = "True if the share is deleted."; @@ -1149,4 +1184,8 @@ directive: where: $["x-ms-paths"]["/{shareName}/{directory}/{fileName}?comp=rangelist"].get.responses["200"] transform: > $.schema.description = "Response type for #Azure::Storage::Files::Shares::ShareFileClient::GetRangeList."; + - from: swagger-document + where: $["x-ms-paths"]["/{shareName}?restype=share&comp=properties"].put.responses["200"] + transform: > + $.headers["x-ms-share-provisioned-iops"].description = "Returns the current share provisioned IOPS."; ``` diff --git a/sdk/storage/azure-storage-files-shares/test/ut/share_client_test.cpp b/sdk/storage/azure-storage-files-shares/test/ut/share_client_test.cpp index 0c61e3b0b..40b0d38e4 100644 --- a/sdk/storage/azure-storage-files-shares/test/ut/share_client_test.cpp +++ b/sdk/storage/azure-storage-files-shares/test/ut/share_client_test.cpp @@ -822,4 +822,67 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_EQ(sddlPermission, permission); } } + + TEST_F(FileShareClientTest, ProvisionedBilling_PLAYBACKONLY_) + { + auto shareServiceClient = *m_shareServiceClient; + auto shareName = LowercaseRandomString(); + auto shareClient = shareServiceClient.GetShareClient(shareName); + + // Create + Files::Shares::CreateShareOptions options; + options.ProvisionedMaxIops = 10240; + options.ProvisionedMaxBandwidthMibps = 125; + options.ShareQuotaInGiB = 32; + Files::Shares::Models::CreateShareResult result; + EXPECT_NO_THROW(result = shareClient.Create(options).Value); + EXPECT_TRUE(result.ShareProvisionedIops.HasValue()); + EXPECT_EQ(options.ProvisionedMaxIops.Value(), result.ShareProvisionedIops.Value()); + EXPECT_TRUE(result.ShareProvisionedBandwidthMibps.HasValue()); + EXPECT_EQ( + options.ProvisionedMaxBandwidthMibps.Value(), + result.ShareProvisionedBandwidthMibps.Value()); + EXPECT_TRUE(result.ShareIncludedBurstIops.HasValue()); + EXPECT_TRUE(result.MaxBurstCreditsForIops.HasValue()); + EXPECT_TRUE(result.Quota.HasValue()); + EXPECT_EQ(options.ShareQuotaInGiB.Value(), result.Quota.Value()); + + // GetProperties + Files::Shares::Models::ShareProperties properties; + EXPECT_NO_THROW(properties = shareClient.GetProperties().Value); + EXPECT_TRUE(properties.ProvisionedIops.HasValue()); + EXPECT_EQ(options.ProvisionedMaxIops.Value(), properties.ProvisionedIops.Value()); + EXPECT_TRUE(properties.ProvisionedBandwidthMBps.HasValue()); + EXPECT_EQ( + options.ProvisionedMaxBandwidthMibps.Value(), properties.ProvisionedBandwidthMBps.Value()); + EXPECT_TRUE(properties.IncludedBurstIops.HasValue()); + EXPECT_TRUE(properties.MaxBurstCreditsForIops.HasValue()); + EXPECT_TRUE(properties.NextAllowedProvisionedIopsDowngradeTime.HasValue()); + EXPECT_TRUE(properties.NextAllowedProvisionedBandwidthDowngradeTime.HasValue()); + + // SetProperties + Files::Shares::SetSharePropertiesOptions setOptions; + setOptions.ProvisionedMaxIops = 20480; + setOptions.ProvisionedMaxBandwidthMibps = 125; + Files::Shares::Models::SetSharePropertiesResult setResult; + EXPECT_NO_THROW(setResult = shareClient.SetProperties(setOptions).Value); + EXPECT_TRUE(setResult.ProvisionedIops.HasValue()); + EXPECT_EQ(setOptions.ProvisionedMaxIops.Value(), setResult.ProvisionedIops.Value()); + EXPECT_TRUE(setResult.ProvisionedBandwidthMibps.HasValue()); + EXPECT_EQ( + setOptions.ProvisionedMaxBandwidthMibps.Value(), + setResult.ProvisionedBandwidthMibps.Value()); + EXPECT_TRUE(setResult.IncludedBurstIops.HasValue()); + EXPECT_TRUE(setResult.Quota.HasValue()); + EXPECT_TRUE(setResult.MaxBurstCreditsForIops.HasValue()); + EXPECT_TRUE(setResult.NextAllowedProvisionedIopsDowngradeTime.HasValue()); + EXPECT_TRUE(setResult.NextAllowedProvisionedBandwidthDowngradeTime.HasValue()); + + // Delete (Due to inconsistent between swagger and server, pending response for this test case) + Files::Shares::Models::DeleteShareResult deleteResult; + EXPECT_NO_THROW(deleteResult = shareClient.Delete().Value); + EXPECT_TRUE(deleteResult.Deleted); + EXPECT_TRUE(deleteResult.ShareUsageBytes.HasValue()); + EXPECT_TRUE(deleteResult.ShareSnapshotUsageBytes.HasValue()); + } }}} // namespace Azure::Storage::Test diff --git a/sdk/storage/azure-storage-files-shares/test/ut/share_file_client_test.cpp b/sdk/storage/azure-storage-files-shares/test/ut/share_file_client_test.cpp index c009f2b7d..77834a4f3 100644 --- a/sdk/storage/azure-storage-files-shares/test/ut/share_file_client_test.cpp +++ b/sdk/storage/azure-storage-files-shares/test/ut/share_file_client_test.cpp @@ -1993,4 +1993,98 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_EQ(binaryPermissionNoControlFlag, permission); } } + + TEST_F(FileShareFileClientTest, FilePermissionFormatForCopy_PLAYBACKONLY_) + { + auto sddlPermission + = "O:S-1-5-21-2127521184-1604012920-1887927527-21560751G:S-1-5-21-2127521184-1604012920-" + "1887927527-513D:AI(A;;FA;;;SY)(A;;FA;;;BA)(A;;0x1200a9;;;S-1-5-21-397955417-626881126-" + "188441444-3053964)S:NO_ACCESS_CONTROL"; + auto sddlPermissionNoControlFlag + = "O:S-1-5-21-2127521184-1604012920-1887927527-21560751G:S-1-5-21-2127521184-1604012920-" + "1887927527-513D:(A;;FA;;;SY)(A;;FA;;;BA)(A;;0x1200a9;;;S-1-5-21-397955417-626881126-" + "188441444-3053964)"; + auto binaryPermission + = "AQAEgIgAAACUAAAAAAAAABQAAAACAHQABQAAAAAAGAD/AR8AAQIAAAAAAAUgAAAAIAIAAAAAFAD/" + "AR8AAQEAAAAAAAUSAAAAAAAYAKkAEgABAgAAAAAABSAAAAAhAgAAAAAUAL8BEwABAQAAAAAABQsAAAAAABQA/" + "wEfAAEBAAAAAAAFEgAAAAEBAAAAAAAFEgAAAAEBAAAAAAAFEgAAAA=="; + auto binaryPermissionNoControlFlag + = "AQAEgGwAAACIAAAAAAAAABQAAAACAFgAAwAAAAAAFAD/" + "AR8AAQEAAAAAAAUSAAAAAAAYAP8BHwABAgAAAAAABSAAAAAgAgAAAAAkAKkAEgABBQAAAAAABRUAAABZUbgXZnJd" + "JWRjOwuMmS4AAQUAAAAAAAUVAAAAoGXPfnhLm1/nfIdwr/" + "1IAQEFAAAAAAAFFQAAAKBlz354S5tf53yHcAECAAA="; + + size_t fileSize = 128; + // source client + auto sourceClient = m_shareClient->GetRootDirectoryClient().GetFileClient(RandomString() + "1"); + sourceClient.Create(fileSize); + + // sddl format + { + auto permissionFormat = Files::Shares::Models::FilePermissionFormat::Sddl; + auto fileClient + = m_shareClient->GetRootDirectoryClient().GetFileClient(LowercaseRandomString()); + + Files::Shares::StartFileCopyOptions options; + options.FilePermissionFormat = permissionFormat; + options.Permission = sddlPermission; + options.PermissionCopyMode = Files::Shares::Models::PermissionCopyMode::Override; + auto copyOperation = fileClient.StartCopy(sourceClient.GetUrl(), options); + EXPECT_EQ( + copyOperation.GetRawResponse().GetStatusCode(), + Azure::Core::Http::HttpStatusCode::Accepted); + auto fileProperties = copyOperation.PollUntilDone(std::chrono::milliseconds(1000)).Value; + EXPECT_EQ(fileProperties.CopyStatus.Value(), Files::Shares::Models::CopyStatus::Success); + auto permissionKey = fileProperties.SmbProperties.PermissionKey.Value(); + Files::Shares::GetSharePermissionOptions getOptions; + getOptions.FilePermissionFormat = permissionFormat; + auto permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(sddlPermissionNoControlFlag, permission); + } + // binary format + { + auto permissionFormat = Files::Shares::Models::FilePermissionFormat::Binary; + auto fileClient = m_shareClient->GetRootDirectoryClient().GetFileClient(RandomString()); + + Files::Shares::StartFileCopyOptions options; + options.FilePermissionFormat = permissionFormat; + options.Permission = binaryPermissionNoControlFlag; + options.PermissionCopyMode = Files::Shares::Models::PermissionCopyMode::Override; + auto copyOperation = fileClient.StartCopy(sourceClient.GetUrl(), options); + EXPECT_EQ( + copyOperation.GetRawResponse().GetStatusCode(), + Azure::Core::Http::HttpStatusCode::Accepted); + auto fileProperties = copyOperation.PollUntilDone(std::chrono::milliseconds(1000)).Value; + EXPECT_EQ(fileProperties.CopyStatus.Value(), Files::Shares::Models::CopyStatus::Success); + auto permissionKey = fileProperties.SmbProperties.PermissionKey.Value(); + Files::Shares::GetSharePermissionOptions getOptions; + getOptions.FilePermissionFormat = permissionFormat; + auto permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(binaryPermissionNoControlFlag, permission); + } + + // source mode + std::string permissionKey; + { + auto permissionFormat = Files::Shares::Models::FilePermissionFormat::Binary; + auto fileClient = m_shareClient->GetRootDirectoryClient().GetFileClient(RandomString()); + + Files::Shares::StartFileCopyOptions options; + options.FilePermissionFormat = permissionFormat; + // Permission and PermissionFormat are ignored when PermissionCopyMode is Source. + options.Permission = binaryPermission; + options.PermissionCopyMode = Files::Shares::Models::PermissionCopyMode::Source; + auto copyOperation = fileClient.StartCopy(sourceClient.GetUrl(), options); + EXPECT_EQ( + copyOperation.GetRawResponse().GetStatusCode(), + Azure::Core::Http::HttpStatusCode::Accepted); + auto fileProperties = copyOperation.PollUntilDone(std::chrono::milliseconds(1000)).Value; + EXPECT_EQ(fileProperties.CopyStatus.Value(), Files::Shares::Models::CopyStatus::Success); + permissionKey = fileProperties.SmbProperties.PermissionKey.Value(); + Files::Shares::GetSharePermissionOptions getOptions; + getOptions.FilePermissionFormat = permissionFormat; + auto permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(binaryPermission, permission); + } + } }}} // namespace Azure::Storage::Test diff --git a/sdk/storage/azure-storage-files-shares/test/ut/share_service_client_test.cpp b/sdk/storage/azure-storage-files-shares/test/ut/share_service_client_test.cpp index 27942c8b5..7dbdad6b2 100644 --- a/sdk/storage/azure-storage-files-shares/test/ut/share_service_client_test.cpp +++ b/sdk/storage/azure-storage-files-shares/test/ut/share_service_client_test.cpp @@ -497,4 +497,34 @@ namespace Azure { namespace Storage { namespace Test { shareClient.DeleteIfExists(); } + + TEST_F(FileShareServiceClientTest, ListShares_ProvisionedBilling_PLAYBACKONLY_) + { + auto shareServiceClient = *m_shareServiceClient; + auto shareName = LowercaseRandomString(); + auto shareClient = shareServiceClient.GetShareClient(shareName); + + // Create + shareClient.Create(); + + // List Shares + Azure::Nullable shareItem; + for (auto page = shareServiceClient.ListShares(); page.HasPage(); page.MoveToNextPage()) + { + for (const auto& share : page.Shares) + { + if (share.Name == shareName) + { + shareItem = share; + } + } + } + ASSERT_TRUE(shareItem.HasValue()); + EXPECT_TRUE(shareItem.Value().Details.IncludedBurstIops.HasValue()); + EXPECT_TRUE(shareItem.Value().Details.MaxBurstCreditsForIops.HasValue()); + EXPECT_TRUE(shareItem.Value().Details.NextAllowedProvisionedIopsDowngradeTime.HasValue()); + EXPECT_TRUE(shareItem.Value().Details.NextAllowedProvisionedBandwidthDowngradeTime.HasValue()); + + EXPECT_NO_THROW(shareClient.Delete()); + } }}} // namespace Azure::Storage::Test