Storage/STG94 features (#5667)

* update to stable (#5541)

* Storage/ Merge main to unblock pipeline failure (#5561)

* Sync eng/common directory with azure-sdk-tools for PR 8110 (#5540)

* Show review link in logs and set DevOps project name based on the pipeline run

* Handle the failures when package work item is unassigned (#5551)

Co-authored-by: Praveen Kuttappan <prmarott@microsoft.com>

* Revert win2022 image back to latest and add msvc version mitigation (#5539)

* Revert win2022 image back to latest
* Workaround fix for MSVC SxS issue

* Fix Policheck step indention (#5553)

Co-authored-by: Wes Haggard <weshaggard@users.noreply.github.com>

* Sync .github/workflows directory with azure-sdk-tools for PR 8131 (#5555)

* Update to azure/login@v2

* Remove the unnecessary setting of enable-AzPSSession. We don't need it.

---------

Co-authored-by: James Suplizio <jasupliz@microsoft.com>

* Update sorting algorithm used in storage shared-key signing (#5547)

* Remove Windows upgrade of cmake (windows image now uses working version of cmake) (#5558)

* Revert "Update sorting algorithm used in storage shared-key signing (#5547)" (#5560)

This reverts commit b6e04fd035.

---------

Co-authored-by: Azure SDK Bot <53356347+azure-sdk@users.noreply.github.com>
Co-authored-by: Praveen Kuttappan <prmarott@microsoft.com>
Co-authored-by: Daniel Jurek <djurek@microsoft.com>
Co-authored-by: Wes Haggard <weshaggard@users.noreply.github.com>
Co-authored-by: James Suplizio <jasupliz@microsoft.com>
Co-authored-by: JinmingHu <jinmhu@microsoft.com>

* Storage/STG94 Snapshot management support via REST for NFS shares (#5543)

* add nfs support (#5267)

* add test recordinhg

* Storage/STG94 GetAccountInfo() for container and blob (#5550)

* add getaccountinfo

* update record

* Storage/STG94 Add Queues bearer challenge test case (#5556)

* Add test for queue bearer challenge

* update test case

* update var name

* update test case

* fix clang format

* Update sorting algorithm used in storage shared-key signing (#5611)

* Storage/Stg94 Support for authorization ExtendedErrorDetail (#5633)

* Support for authorization ExtendedErrorDetail

* fix clang format

* fix build error

* make tests live only

* Update change log

* remove additional changes

* update changelog

* update error detail liveonly

* Update live test

---------

Co-authored-by: Azure SDK Bot <53356347+azure-sdk@users.noreply.github.com>
Co-authored-by: Praveen Kuttappan <prmarott@microsoft.com>
Co-authored-by: Daniel Jurek <djurek@microsoft.com>
Co-authored-by: Wes Haggard <weshaggard@users.noreply.github.com>
Co-authored-by: James Suplizio <jasupliz@microsoft.com>
Co-authored-by: JinmingHu <jinmhu@microsoft.com>
This commit is contained in:
microzchang 2024-05-28 11:21:17 +08:00 committed by GitHub
parent 72e8b78617
commit ffbf094b89
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 927 additions and 233 deletions

View File

@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "cpp",
"TagPrefix": "cpp/storage",
"Tag": "cpp/storage_fc81ec148a"
"Tag": "cpp/storage_604485c00a"
}

View File

@ -4,11 +4,9 @@
### Features Added
### Breaking Changes
### Bugs Fixed
### Other Changes
- Bumped up API version to `2024-08-04`.
- Added `BlobContainerClient::GetAccountInfo()` and `BlobClient::GetAccountInfo` APIs.
- Added more detailed messaging for authorization failure cases.
## 12.11.0 (2024-05-07)

View File

@ -414,6 +414,17 @@ namespace Azure { namespace Storage { namespace Blobs {
const SetBlobLegalHoldOptions& options = SetBlobLegalHoldOptions(),
const Azure::Core::Context& context = Azure::Core::Context()) const;
/**
* @brief Returns the sku name and account kind for the specified account.
*
* @param options Optional parameters to execute this function.
* @param context Context for cancelling long running operations.
* @return AccountInfo describing the account.
*/
Azure::Response<Models::AccountInfo> GetAccountInfo(
const GetAccountInfoOptions& options = GetAccountInfoOptions(),
const Azure::Core::Context& context = Azure::Core::Context()) const;
protected:
/** @brief Blob Url */
Azure::Core::Url m_blobUrl;

View File

@ -326,6 +326,17 @@ namespace Azure { namespace Storage { namespace Blobs {
const SubmitBlobBatchOptions& options = SubmitBlobBatchOptions(),
const Core::Context& context = Core::Context()) const;
/**
* @brief Returns the sku name and account kind for the specified account.
*
* @param options Optional parameters to execute this function.
* @param context Context for cancelling long running operations.
* @return AccountInfo describing the account.
*/
Azure::Response<Models::AccountInfo> GetAccountInfo(
const GetAccountInfoOptions& options = GetAccountInfoOptions(),
const Azure::Core::Context& context = Azure::Core::Context()) const;
private:
Azure::Core::Url m_blobContainerUrl;
std::shared_ptr<Azure::Core::Http::_internal::HttpPipeline> m_pipeline;

View File

@ -31,7 +31,7 @@ namespace Azure { namespace Storage { namespace Blobs {
/**
* The version used for the operations to Azure storage services.
*/
constexpr static const char* ApiVersion = "2023-11-03";
constexpr static const char* ApiVersion = "2024-08-04";
} // namespace _detail
namespace Models {
/**
@ -655,25 +655,6 @@ namespace Azure { namespace Storage { namespace Blobs {
private:
std::string m_value;
};
/**
* @brief Response type for #Azure::Storage::Blobs::BlobServiceClient::GetAccountInfo.
*/
struct AccountInfo final
{
/**
* Identifies the sku name of the account.
*/
Models::SkuName SkuName;
/**
* Identifies the account kind.
*/
Models::AccountKind AccountKind;
/**
* Version 2019-07-07 and newer. Indicates if the account has a hierarchical namespace
* enabled.
*/
bool IsHierarchicalNamespaceEnabled = bool();
};
/**
* @brief Blob info from a Filter Blobs API call.
*/
@ -2400,6 +2381,25 @@ namespace Azure { namespace Storage { namespace Blobs {
struct SetBlobAccessTierResult final
{
};
/**
* @brief Response type for #Azure::Storage::Blobs::BlobServiceClient::GetAccountInfo.
*/
struct AccountInfo final
{
/**
* Identifies the sku name of the account.
*/
Models::SkuName SkuName;
/**
* Identifies the account kind.
*/
Models::AccountKind AccountKind;
/**
* Version 2019-07-07 and newer. Indicates if the account has a hierarchical namespace
* enabled.
*/
bool IsHierarchicalNamespaceEnabled = bool();
};
namespace _detail {
/**
* @brief Required. The type of the provided query expression.
@ -3664,6 +3664,14 @@ namespace Azure { namespace Storage { namespace Blobs {
const Core::Url& url,
const ListBlobContainerBlobsByHierarchyOptions& options,
const Core::Context& context);
struct GetBlobContainerAccountInfoOptions final
{
};
static Response<Models::AccountInfo> GetAccountInfo(
Core::Http::_internal::HttpPipeline& pipeline,
const Core::Url& url,
const GetBlobContainerAccountInfoOptions& options,
const Core::Context& context);
};
class BlobClient final {
public:
@ -3986,6 +3994,14 @@ namespace Azure { namespace Storage { namespace Blobs {
const Core::Url& url,
const SetBlobTierOptions& options,
const Core::Context& context);
struct GetBlobAccountInfoOptions final
{
};
static Response<Models::AccountInfo> GetAccountInfo(
Core::Http::_internal::HttpPipeline& pipeline,
const Core::Url& url,
const GetBlobAccountInfoOptions& options,
const Core::Context& context);
struct QueryBlobOptions final
{
Models::_detail::QueryRequest QueryRequest;

View File

@ -896,4 +896,14 @@ namespace Azure { namespace Storage { namespace Blobs {
return _detail::BlobClient::SetLegalHold(*m_pipeline, m_blobUrl, protocolLayerOptions, context);
}
Azure::Response<Models::AccountInfo> BlobClient::GetAccountInfo(
const GetAccountInfoOptions& options,
const Azure::Core::Context& context) const
{
(void)options;
_detail::BlobClient::GetBlobAccountInfoOptions protocolLayerOptions;
return _detail::BlobClient::GetAccountInfo(
*m_pipeline, m_blobUrl, protocolLayerOptions, _internal::WithReplicaStatus(context));
}
}}} // namespace Azure::Storage::Blobs

View File

@ -516,4 +516,17 @@ namespace Azure { namespace Storage { namespace Blobs {
return Azure::Response<Models::SubmitBlobBatchResult>(
Models::SubmitBlobBatchResult(), std::move(response.RawResponse));
}
Azure::Response<Models::AccountInfo> BlobContainerClient::GetAccountInfo(
const GetAccountInfoOptions& options,
const Azure::Core::Context& context) const
{
(void)options;
_detail::BlobContainerClient::GetBlobContainerAccountInfoOptions protocolLayerOptions;
return _detail::BlobContainerClient::GetAccountInfo(
*m_pipeline,
m_blobContainerUrl,
protocolLayerOptions,
_internal::WithReplicaStatus(context));
}
}}} // namespace Azure::Storage::Blobs

View File

@ -377,7 +377,7 @@ namespace Azure { namespace Storage { namespace Blobs {
request.SetHeader("Content-Length", std::to_string(requestBody.Length()));
request.GetUrl().AppendQueryParameter("restype", "service");
request.GetUrl().AppendQueryParameter("comp", "properties");
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
@ -397,7 +397,7 @@ namespace Azure { namespace Storage { namespace Blobs {
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", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
(void)options;
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
@ -693,7 +693,7 @@ namespace Azure { namespace Storage { namespace Blobs {
auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
request.GetUrl().AppendQueryParameter("restype", "service");
request.GetUrl().AppendQueryParameter("comp", "stats");
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
(void)options;
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
@ -793,7 +793,7 @@ namespace Azure { namespace Storage { namespace Blobs {
_internal::UrlEncodeQueryParameter(
ListBlobContainersIncludeFlagsToString(options.Include.Value())));
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -1078,7 +1078,7 @@ namespace Azure { namespace Storage { namespace Blobs {
request.SetHeader("Content-Length", std::to_string(requestBody.Length()));
request.GetUrl().AppendQueryParameter("restype", "service");
request.GetUrl().AppendQueryParameter("comp", "userdelegationkey");
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -1193,7 +1193,7 @@ namespace Azure { namespace Storage { namespace Blobs {
auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
request.GetUrl().AppendQueryParameter("restype", "account");
request.GetUrl().AppendQueryParameter("comp", "properties");
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
(void)options;
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
@ -1223,7 +1223,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("Content-Type", options.MultipartContentType);
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
@ -1244,7 +1244,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
request.GetUrl().AppendQueryParameter("comp", "blobs");
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.Where.HasValue() && !options.Where.Value().empty())
{
request.GetUrl().AppendQueryParameter(
@ -1400,7 +1400,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-blob-public-access", options.Access.ToString());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.DefaultEncryptionScope.HasValue()
&& !options.DefaultEncryptionScope.Value().empty())
{
@ -1437,7 +1437,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -1515,7 +1515,7 @@ namespace Azure { namespace Storage { namespace Blobs {
"If-Unmodified-Since",
options.IfUnmodifiedSince.Value().ToString(Azure::DateTime::DateFormat::Rfc1123));
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
@ -1549,7 +1549,7 @@ namespace Azure { namespace Storage { namespace Blobs {
"If-Modified-Since",
options.IfModifiedSince.Value().ToString(Azure::DateTime::DateFormat::Rfc1123));
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -1576,7 +1576,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -1745,7 +1745,7 @@ namespace Azure { namespace Storage { namespace Blobs {
"If-Unmodified-Since",
options.IfUnmodifiedSince.Value().ToString(Azure::DateTime::DateFormat::Rfc1123));
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -1768,7 +1768,7 @@ namespace Azure { namespace Storage { namespace Blobs {
auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
request.GetUrl().AppendQueryParameter("restype", "container");
request.GetUrl().AppendQueryParameter("comp", "undelete");
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.DeletedContainerName.HasValue() && !options.DeletedContainerName.Value().empty())
{
request.SetHeader("x-ms-deleted-container-name", options.DeletedContainerName.Value());
@ -1798,7 +1798,7 @@ namespace Azure { namespace Storage { namespace Blobs {
auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
request.GetUrl().AppendQueryParameter("restype", "container");
request.GetUrl().AppendQueryParameter("comp", "rename");
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (!options.SourceContainerName.empty())
{
request.SetHeader("x-ms-source-container-name", options.SourceContainerName);
@ -1832,7 +1832,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("Content-Type", options.MultipartContentType);
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
@ -1854,7 +1854,7 @@ namespace Azure { namespace Storage { namespace Blobs {
auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
request.GetUrl().AppendQueryParameter("restype", "container");
request.GetUrl().AppendQueryParameter("comp", "blobs");
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.Where.HasValue() && !options.Where.Value().empty())
{
request.GetUrl().AppendQueryParameter(
@ -2024,7 +2024,7 @@ namespace Azure { namespace Storage { namespace Blobs {
"If-Unmodified-Since",
options.IfUnmodifiedSince.Value().ToString(Azure::DateTime::DateFormat::Rfc1123));
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Created)
@ -2065,7 +2065,7 @@ namespace Azure { namespace Storage { namespace Blobs {
"If-Unmodified-Since",
options.IfUnmodifiedSince.Value().ToString(Azure::DateTime::DateFormat::Rfc1123));
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -2105,7 +2105,7 @@ namespace Azure { namespace Storage { namespace Blobs {
"If-Unmodified-Since",
options.IfUnmodifiedSince.Value().ToString(Azure::DateTime::DateFormat::Rfc1123));
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -2146,7 +2146,7 @@ namespace Azure { namespace Storage { namespace Blobs {
"If-Unmodified-Since",
options.IfUnmodifiedSince.Value().ToString(Azure::DateTime::DateFormat::Rfc1123));
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
@ -2191,7 +2191,7 @@ namespace Azure { namespace Storage { namespace Blobs {
"If-Unmodified-Since",
options.IfUnmodifiedSince.Value().ToString(Azure::DateTime::DateFormat::Rfc1123));
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -2238,7 +2238,7 @@ namespace Azure { namespace Storage { namespace Blobs {
_internal::UrlEncodeQueryParameter(
ListBlobsIncludeFlagsToString(options.Include.Value())));
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -2917,7 +2917,7 @@ namespace Azure { namespace Storage { namespace Blobs {
_internal::UrlEncodeQueryParameter(
ListBlobsIncludeFlagsToString(options.Include.Value())));
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.ShowOnly.HasValue() && !options.ShowOnly.Value().empty())
{
request.GetUrl().AppendQueryParameter(
@ -3597,6 +3597,31 @@ namespace Azure { namespace Storage { namespace Blobs {
return Response<Models::_detail::ListBlobsByHierarchyResult>(
std::move(response), std::move(pRawResponse));
}
Response<Models::AccountInfo> BlobContainerClient::GetAccountInfo(
Core::Http::_internal::HttpPipeline& pipeline,
const Core::Url& url,
const GetBlobContainerAccountInfoOptions& options,
const Core::Context& context)
{
auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
request.GetUrl().AppendQueryParameter("restype", "account");
request.GetUrl().AppendQueryParameter("comp", "properties");
request.SetHeader("x-ms-version", "2024-08-04");
(void)options;
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
{
throw StorageException::CreateFromResponse(std::move(pRawResponse));
}
Models::AccountInfo response;
response.SkuName = Models::SkuName(pRawResponse->GetHeaders().at("x-ms-sku-name"));
response.AccountKind
= Models::AccountKind(pRawResponse->GetHeaders().at("x-ms-account-kind"));
response.IsHierarchicalNamespaceEnabled
= pRawResponse->GetHeaders().at("x-ms-is-hns-enabled") == std::string("true");
return Response<Models::AccountInfo>(std::move(response), std::move(pRawResponse));
}
Response<Models::DownloadBlobResult> BlobClient::Download(
Core::Http::_internal::HttpPipeline& pipeline,
const Core::Url& url,
@ -3672,7 +3697,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.UserPrincipalName.HasValue())
{
request.SetHeader("x-ms-upn", options.UserPrincipalName.Value() ? "true" : "false");
@ -3952,7 +3977,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.UserPrincipalName.HasValue())
{
request.SetHeader("x-ms-upn", options.UserPrincipalName.Value() ? "true" : "false");
@ -4218,7 +4243,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
@ -4236,7 +4261,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
request.GetUrl().AppendQueryParameter("comp", "undelete");
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
(void)options;
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
@ -4255,7 +4280,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
request.GetUrl().AppendQueryParameter("comp", "expiry");
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (!options.ExpiryOptions.ToString().empty())
{
request.SetHeader("x-ms-expiry-option", options.ExpiryOptions.ToString());
@ -4343,7 +4368,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-blob-content-disposition", options.BlobContentDisposition);
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -4376,7 +4401,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
request.GetUrl().AppendQueryParameter("comp", "immutabilityPolicies");
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.IfUnmodifiedSince.HasValue())
{
request.SetHeader(
@ -4419,7 +4444,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
auto request = Core::Http::Request(Core::Http::HttpMethod::Delete, url);
request.GetUrl().AppendQueryParameter("comp", "immutabilityPolicies");
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
(void)options;
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
@ -4439,7 +4464,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
request.GetUrl().AppendQueryParameter("comp", "legalhold");
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
request.SetHeader("x-ms-legal-hold", options.LegalHold ? "true" : "false");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
@ -4511,7 +4536,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -4586,7 +4611,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Created)
@ -4644,7 +4669,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -4701,7 +4726,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -4763,7 +4788,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -4821,7 +4846,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
@ -4901,7 +4926,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Created)
@ -5008,7 +5033,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.BlobTagsString.HasValue() && !options.BlobTagsString.Value().empty())
{
request.SetHeader("x-ms-tags", options.BlobTagsString.Value());
@ -5127,7 +5152,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.SourceContentMD5.HasValue()
&& !Core::Convert::Base64Encode(options.SourceContentMD5.Value()).empty())
{
@ -5237,7 +5262,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::NoContent)
@ -5275,7 +5300,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-rehydrate-priority", options.RehydratePriority.Value().ToString());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
@ -5295,6 +5320,31 @@ namespace Azure { namespace Storage { namespace Blobs {
return Response<Models::SetBlobAccessTierResult>(
std::move(response), std::move(pRawResponse));
}
Response<Models::AccountInfo> BlobClient::GetAccountInfo(
Core::Http::_internal::HttpPipeline& pipeline,
const Core::Url& url,
const GetBlobAccountInfoOptions& options,
const Core::Context& context)
{
auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
request.GetUrl().AppendQueryParameter("restype", "account");
request.GetUrl().AppendQueryParameter("comp", "properties");
request.SetHeader("x-ms-version", "2024-08-04");
(void)options;
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
{
throw StorageException::CreateFromResponse(std::move(pRawResponse));
}
Models::AccountInfo response;
response.SkuName = Models::SkuName(pRawResponse->GetHeaders().at("x-ms-sku-name"));
response.AccountKind
= Models::AccountKind(pRawResponse->GetHeaders().at("x-ms-account-kind"));
response.IsHierarchicalNamespaceEnabled
= pRawResponse->GetHeaders().at("x-ms-is-hns-enabled") == std::string("true");
return Response<Models::AccountInfo>(std::move(response), std::move(pRawResponse));
}
Response<Models::QueryBlobResult> BlobClient::Query(
Core::Http::_internal::HttpPipeline& pipeline,
const Core::Url& url,
@ -5577,7 +5627,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.EncryptionScope.HasValue() && !options.EncryptionScope.Value().empty())
{
request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value());
@ -5626,7 +5676,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
request.GetUrl().AppendQueryParameter("comp", "tags");
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.Snapshot.HasValue() && !options.Snapshot.Value().empty())
{
request.GetUrl().AppendQueryParameter(
@ -5753,7 +5803,7 @@ namespace Azure { namespace Storage { namespace Blobs {
request.SetHeader("Content-Type", "application/xml; charset=UTF-8");
request.SetHeader("Content-Length", std::to_string(requestBody.Length()));
request.GetUrl().AppendQueryParameter("comp", "tags");
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.VersionId.HasValue() && !options.VersionId.Value().empty())
{
request.GetUrl().AppendQueryParameter(
@ -5884,7 +5934,7 @@ namespace Azure { namespace Storage { namespace Blobs {
request.SetHeader(
"x-ms-blob-sequence-number", std::to_string(options.BlobSequenceNumber.Value()));
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.BlobTagsString.HasValue() && !options.BlobTagsString.Value().empty())
{
request.SetHeader("x-ms-tags", options.BlobTagsString.Value());
@ -6030,7 +6080,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Created)
@ -6156,7 +6206,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Created)
@ -6299,7 +6349,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-source-if-none-match", options.SourceIfNoneMatch.ToString());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.CopySourceAuthorization.HasValue()
&& !options.CopySourceAuthorization.Value().empty())
{
@ -6400,7 +6450,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.Marker.HasValue() && !options.Marker.Value().empty())
{
request.GetUrl().AppendQueryParameter(
@ -6578,7 +6628,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.Marker.HasValue() && !options.Marker.Value().empty())
{
request.GetUrl().AppendQueryParameter(
@ -6758,7 +6808,7 @@ namespace Azure { namespace Storage { namespace Blobs {
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-blob-content-length", std::to_string(options.BlobContentLength));
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -6824,7 +6874,7 @@ namespace Azure { namespace Storage { namespace Blobs {
request.SetHeader(
"x-ms-blob-sequence-number", std::to_string(options.BlobSequenceNumber.Value()));
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -6882,7 +6932,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-copy-source", options.CopySource);
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
@ -6993,7 +7043,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.BlobTagsString.HasValue() && !options.BlobTagsString.Value().empty())
{
request.SetHeader("x-ms-tags", options.BlobTagsString.Value());
@ -7121,7 +7171,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Created)
@ -7275,7 +7325,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-source-if-none-match", options.SourceIfNoneMatch.ToString());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.CopySourceAuthorization.HasValue()
&& !options.CopySourceAuthorization.Value().empty())
{
@ -7331,7 +7381,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
request.GetUrl().AppendQueryParameter("comp", "seal");
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
@ -7470,7 +7520,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.BlobTagsString.HasValue() && !options.BlobTagsString.Value().empty())
{
request.SetHeader("x-ms-tags", options.BlobTagsString.Value());
@ -7653,7 +7703,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-source-if-tags", options.SourceIfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.SourceContentMD5.HasValue()
&& !Core::Convert::Base64Encode(options.SourceContentMD5.Value()).empty())
{
@ -7785,7 +7835,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-encryption-scope", options.EncryptionScope.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Created)
@ -7899,7 +7949,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-source-if-none-match", options.SourceIfNoneMatch.ToString());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.CopySourceAuthorization.HasValue()
&& !options.CopySourceAuthorization.Value().empty())
{
@ -8066,7 +8116,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.BlobTagsString.HasValue() && !options.BlobTagsString.Value().empty())
{
request.SetHeader("x-ms-tags", options.BlobTagsString.Value());
@ -8155,7 +8205,7 @@ namespace Azure { namespace Storage { namespace Blobs {
{
request.SetHeader("x-ms-if-tags", options.IfTags.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)

View File

@ -9,7 +9,7 @@ package-name: azure-storage-blobs
namespace: Azure::Storage::Blobs
output-folder: generated
clear-output-folder: true
input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/storage/data-plane/Microsoft.BlobStorage/preview/2021-12-02/blob.json
input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/storage/data-plane/Microsoft.BlobStorage/stable/2021-12-02/blob.json
```
## ModelFour Options
@ -70,8 +70,6 @@ directive:
- from: swagger-document
where: $["x-ms-paths"]
transform: >
delete $["/{containerName}?restype=account&comp=properties"];
delete $["/{containerName}/{blob}?restype=account&comp=properties"];
delete $["/{filesystem}/{path}?action=setAccessControl&blob"];
delete $["/{filesystem}/{path}?action=getAccessControl&blob"];
delete $["/{filesystem}/{path}?FileRename"];
@ -102,12 +100,12 @@ directive:
"name": "ApiVersion",
"modelAsString": false
},
"enum": ["2023-11-03"]
"enum": ["2024-08-04"]
};
- from: swagger-document
where: $.parameters
transform: >
$.ApiVersionParameter.enum[0] = "2023-11-03";
$.ApiVersionParameter.enum[0] = "2024-08-04";
```
### Rename Operations
@ -673,22 +671,30 @@ directive:
```yaml
directive:
- from: swagger-document
where: $["x-ms-paths"]["/?restype=account&comp=properties"].get.responses["200"]
where: $
transform: >
$.schema = {"$ref": "#/definitions/AccountInfo"};
- from: swagger-document
where: $["x-ms-paths"]["/?restype=account&comp=properties"].get.responses["200"].headers["x-ms-sku-name"]
transform: >
$["x-ms-enum"]["values"] = [
{"value": "Standard_LRS", "name":"Standard_Lrs"},
{"value": "Standard_GRS", "name":"StandardGrs"},
{"value": "Standard_RAGRS", "name":"StandardRagrs"},
{"value": "Standard_ZRS", "name":"StandardZrs"},
{"value": "Premium_LRS", "name":"PremiumLrs"},
{"value": "Premium_ZRS", "name":"PremiumZrs"},
{"value": "Standard_GZRS", "name":"StandardGzrs"},
{"value": "Standard_RAGZRS", "name":"StandardRagzrs"}
const operations = [
"Service_GetAccountInfo",
"BlobContainer_GetAccountInfo",
"Blob_GetAccountInfo",
];
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];
operation.responses["200"].schema = {"$ref": "#/definitions/AccountInfo"};
operation.responses["200"].headers["x-ms-sku-name"]["x-ms-enum"]["values"] = [
{"value": "Standard_LRS", "name":"Standard_Lrs"},
{"value": "Standard_GRS", "name":"StandardGrs"},
{"value": "Standard_RAGRS", "name":"StandardRagrs"},
{"value": "Standard_ZRS", "name":"StandardZrs"},
{"value": "Premium_LRS", "name":"PremiumLrs"},
{"value": "Premium_ZRS", "name":"PremiumZrs"},
{"value": "Standard_GZRS", "name":"StandardGzrs"},
{"value": "Standard_RAGZRS", "name":"StandardRagzrs"}
];
}
}
```
### FindBlobsByTags

View File

@ -1493,4 +1493,14 @@ namespace Azure { namespace Storage { namespace Test {
EXPECT_EQ(e.ErrorCode, "BlobNotFound");
}
}
TEST_F(BlobContainerClientTest, AccountInfo)
{
auto containerClient = *m_blobContainerClient;
auto accountInfo = containerClient.GetAccountInfo().Value;
EXPECT_FALSE(accountInfo.SkuName.ToString().empty());
EXPECT_FALSE(accountInfo.AccountKind.ToString().empty());
EXPECT_FALSE(accountInfo.IsHierarchicalNamespaceEnabled);
}
}}} // namespace Azure::Storage::Test

View File

@ -741,4 +741,36 @@ namespace Azure { namespace Storage { namespace Test {
EXPECT_NO_THROW(blobClient1.Delete());
}
TEST_F(BlobSasTest, AccountSasAuthorizationErrorDetail_LIVEONLY_)
{
auto sasStartsOn = std::chrono::system_clock::now() - std::chrono::minutes(5);
auto sasExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(60);
auto keyCredential
= _internal::ParseConnectionString(StandardStorageConnectionString()).KeyCredential;
auto accountName = keyCredential->AccountName;
auto blobContainerClient = *m_blobContainerClient;
auto blobClient = *m_blockBlobClient;
const std::string blobName = m_blobName;
Sas::AccountSasBuilder accountSasBuilder;
accountSasBuilder.Protocol = Sas::SasProtocol::HttpsAndHttp;
accountSasBuilder.StartsOn = sasStartsOn;
accountSasBuilder.ExpiresOn = sasExpiresOn;
accountSasBuilder.Services = Sas::AccountSasServices::Blobs;
accountSasBuilder.ResourceTypes = Sas::AccountSasResource::Service;
accountSasBuilder.SetPermissions(Sas::AccountSasPermissions::All);
auto sasToken = accountSasBuilder.GenerateSasToken(*keyCredential);
auto unauthorizedBlobClient = GetSasAuthenticatedClient(blobClient, sasToken);
try
{
unauthorizedBlobClient.Download();
}
catch (StorageException& e)
{
EXPECT_EQ("AuthorizationResourceTypeMismatch", e.ErrorCode);
EXPECT_TRUE(e.AdditionalInformation.count("ExtendedErrorDetail") != 0);
}
}
}}} // namespace Azure::Storage::Test

View File

@ -2074,4 +2074,85 @@ namespace Azure { namespace Storage { namespace Test {
= Blobs::BlockBlobClient(m_blockBlobClient->GetUrl(), credential, clientOptions);
EXPECT_THROW(blockBlobClient.GetProperties(), StorageException);
}
TEST_F(BlockBlobClientTest, AccountInfo)
{
auto blobClient = *m_blockBlobClient;
auto accountInfo = blobClient.GetAccountInfo().Value;
EXPECT_FALSE(accountInfo.SkuName.ToString().empty());
EXPECT_FALSE(accountInfo.AccountKind.ToString().empty());
EXPECT_FALSE(accountInfo.IsHierarchicalNamespaceEnabled);
}
TEST_F(BlockBlobClientTest, SharedKeySigningHeaderWithSymbols)
{
class AdditionalHeaderPolicy final : public Azure::Core::Http::Policies::HttpPolicy {
public:
~AdditionalHeaderPolicy() override {}
std::unique_ptr<HttpPolicy> Clone() const override
{
return std::make_unique<AdditionalHeaderPolicy>(*this);
}
std::unique_ptr<Azure::Core::Http::RawResponse> Send(
Azure::Core::Http::Request& request,
Azure::Core::Http::Policies::NextHttpPolicy nextPolicy,
Azure::Core::Context const& context) const override
{
// cSpell:disable
request.SetHeader("x-ms-test", "val");
request.SetHeader("x-ms-test-", "val");
request.SetHeader("x-ms-test-a", "val");
request.SetHeader("x-ms-test-g", "val");
request.SetHeader("x-ms-test-Z", "val");
request.SetHeader("x-ms-testa", "val");
request.SetHeader("x-ms-testd", "val");
request.SetHeader("x-ms-testx", "val");
request.SetHeader("x-ms-test--", "val");
request.SetHeader("x-ms-test-_", "val");
request.SetHeader("x-ms-test_-", "val");
request.SetHeader("x-ms-test__", "val");
request.SetHeader("x-ms-test-a", "val");
request.SetHeader("x-ms-test-A", "val");
request.SetHeader("x-ms-test-_A", "val");
request.SetHeader("x-ms-test_a", "val");
request.SetHeader("x-ms-test_Z", "val");
request.SetHeader("x-ms-test_a_", "val");
request.SetHeader("x-ms-test_a-", "val");
request.SetHeader("x-ms-test_a-_", "val");
request.SetHeader("x-ms-testa--", "val");
request.SetHeader("x-ms-test-a-", "val");
request.SetHeader("x-ms-test--a", "val");
request.SetHeader("x-ms-testaa-", "val");
request.SetHeader("x-ms-testa-a", "val");
request.SetHeader("x-ms-test-aa", "val");
request.SetHeader("x-ms-test-!", "val");
request.SetHeader("x-ms-test-#", "val");
request.SetHeader("x-ms-test-$", "val");
request.SetHeader("x-ms-test-%", "val");
request.SetHeader("x-ms-test-&", "val");
request.SetHeader("x-ms-test-*", "val");
request.SetHeader("x-ms-test-+", "val");
request.SetHeader("x-ms-test-.", "val");
request.SetHeader("x-ms-test-^", "val");
request.SetHeader("x-ms-test-_", "val");
request.SetHeader("x-ms-test-`", "val");
request.SetHeader("x-ms-test-|", "val");
request.SetHeader("x-ms-test-~", "val");
// cSpell:enable
return nextPolicy.Send(request, context);
}
};
auto clientOptions = InitStorageClientOptions<Blobs::BlobClientOptions>();
clientOptions.PerOperationPolicies.push_back(std::make_unique<AdditionalHeaderPolicy>());
auto keyCredential
= _internal::ParseConnectionString(StandardStorageConnectionString()).KeyCredential;
auto blockBlobClient
= Blobs::BlockBlobClient(m_blockBlobClient->GetUrl(), keyCredential, clientOptions);
EXPECT_NO_THROW(blockBlobClient.GetProperties());
}
}}} // namespace Azure::Storage::Test

View File

@ -714,5 +714,75 @@ namespace Azure { namespace Storage { namespace Test {
}
}
}
TEST_F(PageBlobClientTest, SharedKeySigningHeaderWithSymbols)
{
class AdditionalHeaderPolicy final : public Azure::Core::Http::Policies::HttpPolicy {
public:
~AdditionalHeaderPolicy() override {}
std::unique_ptr<HttpPolicy> Clone() const override
{
return std::make_unique<AdditionalHeaderPolicy>(*this);
}
std::unique_ptr<Azure::Core::Http::RawResponse> Send(
Azure::Core::Http::Request& request,
Azure::Core::Http::Policies::NextHttpPolicy nextPolicy,
Azure::Core::Context const& context) const override
{
// cSpell:disable
request.SetHeader("x-ms-test", "val");
request.SetHeader("x-ms-test-", "val");
request.SetHeader("x-ms-test-a", "val");
request.SetHeader("x-ms-test-g", "val");
request.SetHeader("x-ms-test-Z", "val");
request.SetHeader("x-ms-testa", "val");
request.SetHeader("x-ms-testd", "val");
request.SetHeader("x-ms-testx", "val");
request.SetHeader("x-ms-test--", "val");
request.SetHeader("x-ms-test-_", "val");
request.SetHeader("x-ms-test_-", "val");
request.SetHeader("x-ms-test__", "val");
request.SetHeader("x-ms-test-a", "val");
request.SetHeader("x-ms-test-A", "val");
request.SetHeader("x-ms-test-_A", "val");
request.SetHeader("x-ms-test_a", "val");
request.SetHeader("x-ms-test_Z", "val");
request.SetHeader("x-ms-test_a_", "val");
request.SetHeader("x-ms-test_a-", "val");
request.SetHeader("x-ms-test_a-_", "val");
request.SetHeader("x-ms-testa--", "val");
request.SetHeader("x-ms-test-a-", "val");
request.SetHeader("x-ms-test--a", "val");
request.SetHeader("x-ms-testaa-", "val");
request.SetHeader("x-ms-testa-a", "val");
request.SetHeader("x-ms-test-aa", "val");
request.SetHeader("x-ms-test-!", "val");
request.SetHeader("x-ms-test-#", "val");
request.SetHeader("x-ms-test-$", "val");
request.SetHeader("x-ms-test-%", "val");
request.SetHeader("x-ms-test-&", "val");
request.SetHeader("x-ms-test-*", "val");
request.SetHeader("x-ms-test-+", "val");
request.SetHeader("x-ms-test-.", "val");
request.SetHeader("x-ms-test-^", "val");
request.SetHeader("x-ms-test-_", "val");
request.SetHeader("x-ms-test-`", "val");
request.SetHeader("x-ms-test-|", "val");
request.SetHeader("x-ms-test-~", "val");
// cSpell:enable
return nextPolicy.Send(request, context);
}
};
auto clientOptions = InitStorageClientOptions<Blobs::BlobClientOptions>();
clientOptions.PerOperationPolicies.push_back(std::make_unique<AdditionalHeaderPolicy>());
auto keyCredential
= _internal::ParseConnectionString(StandardStorageConnectionString()).KeyCredential;
auto blockBlobClient
= Blobs::BlockBlobClient(m_pageBlobClient->GetUrl(), keyCredential, clientOptions);
EXPECT_NO_THROW(blockBlobClient.GetProperties());
}
}}} // namespace Azure::Storage::Test

View File

@ -4,11 +4,7 @@
### Features Added
### Breaking Changes
### Bugs Fixed
### Other Changes
- Bumped up Account SAS version to `2024-08-04`.
## 12.6.0 (2024-05-07)

View File

@ -9,7 +9,7 @@
namespace Azure { namespace Storage { namespace Sas {
namespace {
constexpr static const char* SasVersion = "2024-05-04";
constexpr static const char* SasVersion = "2024-08-04";
}
void AccountSasBuilder::SetPermissions(AccountSasPermissions permissions)

View File

@ -10,6 +10,86 @@
#include <algorithm>
namespace {
/*
* We need to imitate .Net culture-aware sorting, which is used in storage service.
* Below tables contain sort-keys for en-US culture.
*/
const static int table_lv0[128] = {
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71c, 0x0, 0x71f, 0x721, 0x723, 0x725,
0x0, 0x0, 0x0, 0x72d, 0x803, 0x0, 0x0, 0x733, 0x0, 0xd03, 0xd1a, 0xd1c, 0xd1e,
0xd20, 0xd22, 0xd24, 0xd26, 0xd28, 0xd2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0xe02, 0xe09, 0xe0a, 0xe1a, 0xe21, 0xe23, 0xe25, 0xe2c, 0xe32, 0xe35, 0xe36, 0xe48, 0xe51,
0xe70, 0xe7c, 0xe7e, 0xe89, 0xe8a, 0xe91, 0xe99, 0xe9f, 0xea2, 0xea4, 0xea6, 0xea7, 0xea9,
0x0, 0x0, 0x0, 0x743, 0x744, 0x748, 0xe02, 0xe09, 0xe0a, 0xe1a, 0xe21, 0xe23, 0xe25,
0xe2c, 0xe32, 0xe35, 0xe36, 0xe48, 0xe51, 0xe70, 0xe7c, 0xe7e, 0xe89, 0xe8a, 0xe91, 0xe99,
0xe9f, 0xea2, 0xea4, 0xea6, 0xea7, 0xea9, 0x0, 0x74c, 0x0, 0x750, 0x0,
};
const static int table_lv2[128] = {
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
};
const static int table_lv4[128] = {
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8012, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8212, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
};
bool comparator(const std::string& lhs, const std::string& rhs)
{
const static std::array<const int*, 3> tables{table_lv0, table_lv2, table_lv4};
size_t curr_level = 0;
size_t i = 0;
size_t j = 0;
while (curr_level < tables.size())
{
if (curr_level == tables.size() - 1 && i != j)
{
return i > j;
}
const int weight1 = i < lhs.size() ? tables[curr_level][static_cast<uint8_t>(lhs[i])] : 0x1;
const int weight2 = j < rhs.size() ? tables[curr_level][static_cast<uint8_t>(rhs[j])] : 0x1;
if (weight1 == 0x1 && weight2 == 0x1)
{
i = 0;
j = 0;
++curr_level;
}
else if (weight1 == weight2)
{
++i;
++j;
}
else if (weight1 == 0)
{
++i;
}
else if (weight2 == 0)
{
++j;
}
else
{
return weight1 < weight2;
}
}
return false;
}
} // namespace
namespace Azure { namespace Storage { namespace _internal {
std::string SharedKeyPolicy::GetSignature(const Core::Http::Request& request) const
@ -56,7 +136,9 @@ namespace Azure { namespace Storage { namespace _internal {
std::string key = Azure::Core::_internal::StringExtensions::ToLower(ite->first);
ordered_kv.emplace_back(std::make_pair(std::move(key), ite->second));
}
std::sort(ordered_kv.begin(), ordered_kv.end());
std::sort(ordered_kv.begin(), ordered_kv.end(), [](const auto& lhs, const auto& rhs) {
return comparator(lhs.first, rhs.first);
});
for (const auto& p : ordered_kv)
{
string_to_sign += p.first + ":" + p.second + "\n";

View File

@ -4,11 +4,8 @@
### Features Added
### Breaking Changes
### Bugs Fixed
### Other Changes
- Bumped up API version to `2024-08-04`.
- Added more detailed messaging for authorization failure cases.
## 12.10.0 (2024-05-07)

View File

@ -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 = "2023-11-03";
constexpr static const char* ApiVersion = "2024-08-04";
} // namespace _detail
namespace Models {
namespace _detail {

View File

@ -61,7 +61,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
{
request.GetUrl().AppendQueryParameter("timeout", std::to_string(options.Timeout.Value()));
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.ContinuationToken.HasValue() && !options.ContinuationToken.Value().empty())
{
request.GetUrl().AppendQueryParameter(
@ -157,7 +157,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
{
request.GetUrl().AppendQueryParameter("timeout", std::to_string(options.Timeout.Value()));
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.Resource.HasValue() && !options.Resource.Value().ToString().empty())
{
request.GetUrl().AppendQueryParameter(
@ -345,7 +345,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
{
request.GetUrl().AppendQueryParameter("timeout", std::to_string(options.Timeout.Value()));
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.Recursive.HasValue())
{
request.GetUrl().AppendQueryParameter(
@ -443,7 +443,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", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -490,7 +490,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
{
request.SetHeader("x-ms-acl", options.Acl.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -543,7 +543,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
{
request.SetHeader("x-ms-undelete-source", options.UndeleteSource.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -594,7 +594,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", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -693,7 +693,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", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.EncryptionKey.HasValue() && !options.EncryptionKey.Value().empty())
{
request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value());
@ -777,7 +777,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
{
request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId.Value());
}
request.SetHeader("x-ms-version", "2023-11-03");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.EncryptionKey.HasValue() && !options.EncryptionKey.Value().empty())
{
request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value());

View File

@ -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/main/specification/storage/data-plane/Azure.Storage.Files.DataLake/preview/2023-05-03/DataLakeStorage.json
input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/storage/data-plane/Azure.Storage.Files.DataLake/stable/2023-05-03/DataLakeStorage.json
```
## ModelFour Options
@ -88,12 +88,12 @@ directive:
"name": "ApiVersion",
"modelAsString": false
},
"enum": ["2023-11-03"]
"enum": ["2024-08-04"]
};
- from: swagger-document
where: $.parameters
transform: >
$.ApiVersionParameter.enum[0] = "2023-11-03";
$.ApiVersionParameter.enum[0] = "2024-08-04";
```
### Rename Operations

View File

@ -786,4 +786,41 @@ namespace Azure { namespace Storage { namespace Test {
ASSERT_TRUE(properties.EncryptionScope.HasValue());
EXPECT_EQ(properties.EncryptionScope.Value(), encryptionScope);
}
TEST_F(DataLakeSasTest, AccountSasAuthorizationErrorDetail_LIVEONLY_)
{
auto sasStartsOn = std::chrono::system_clock::now() - std::chrono::minutes(5);
auto sasExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(60);
Sas::AccountSasBuilder accountSasBuilder;
accountSasBuilder.Protocol = Sas::SasProtocol::HttpsAndHttp;
accountSasBuilder.StartsOn = sasStartsOn;
accountSasBuilder.ExpiresOn = sasExpiresOn;
accountSasBuilder.Services = Sas::AccountSasServices::Blobs;
accountSasBuilder.ResourceTypes = Sas::AccountSasResource::Service;
accountSasBuilder.SetPermissions(Sas::AccountSasPermissions::All);
auto keyCredential = _internal::ParseConnectionString(AdlsGen2ConnectionString()).KeyCredential;
std::string directoryName = RandomString();
std::string fileName = RandomString();
auto dataLakeFileSystemClient = *m_fileSystemClient;
auto dataLakeDirectoryClient = dataLakeFileSystemClient.GetDirectoryClient(directoryName);
dataLakeDirectoryClient.Create();
auto dataLakeFileClient = dataLakeFileSystemClient.GetFileClient(fileName);
dataLakeFileClient.Create();
auto sasToken = accountSasBuilder.GenerateSasToken(*keyCredential);
auto unauthorizedFileClient = GetSasAuthenticatedClient(dataLakeFileClient, sasToken);
try
{
unauthorizedFileClient.Download();
}
catch (StorageException& e)
{
EXPECT_EQ("AuthorizationResourceTypeMismatch", e.ErrorCode);
EXPECT_TRUE(e.AdditionalInformation.count("ExtendedErrorDetail") != 0);
}
}
}}} // namespace Azure::Storage::Test

View File

@ -4,11 +4,9 @@
### Features Added
### Breaking Changes
### Bugs Fixed
### Other Changes
- Bumped up API version to `2024-08-04`.
- Added more detailed messaging for authorization failure cases.
- Added support for snapshot management on NFS shares.
## 12.9.0 (2024-05-07)

View File

@ -31,7 +31,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-05-04";
constexpr static const char* ApiVersion = "2024-08-04";
} // namespace _detail
namespace Models {
/**
@ -393,6 +393,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
* Root squash to set on the share. Only valid for NFS shares.
*/
Nullable<ShareRootSquash> RootSquash;
/**
* Version 2023-08-03 and newer. Specifies whether the snapshot virtual directory should be
* accessible at the root of share mount point when NFS is enabled. This header is only
* returned for shares, not for snapshots.
*/
Nullable<bool> EnableSnapshotVirtualDirectoryAccess;
};
/**
* @brief A listed Azure Storage share item.
@ -570,6 +576,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
* Valid for NFS shares only.
*/
Nullable<ShareRootSquash> RootSquash;
/**
* Version 2023-08-03 and newer. Specifies whether the snapshot virtual directory should be
* accessible at the root of share mount point when NFS is enabled. This header is only
* returned for shares, not for snapshots.
*/
Nullable<bool> EnableSnapshotVirtualDirectoryAccess;
};
/**
* @brief Specifies the option include to delete the base share and all of its snapshots.
@ -2085,6 +2097,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
Nullable<Models::AccessTier> AccessTier;
Nullable<Models::ShareProtocols> EnabledProtocols;
Nullable<Models::ShareRootSquash> RootSquash;
Nullable<bool> EnableSnapshotVirtualDirectoryAccess;
};
static Response<Models::CreateShareResult> Create(
Core::Http::_internal::HttpPipeline& pipeline,
@ -2200,6 +2213,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
Nullable<Models::AccessTier> AccessTier;
Nullable<std::string> LeaseId;
Nullable<Models::ShareRootSquash> RootSquash;
Nullable<bool> EnableSnapshotVirtualDirectoryAccess;
};
static Response<Models::SetSharePropertiesResult> SetProperties(
Core::Http::_internal::HttpPipeline& pipeline,

View File

@ -174,6 +174,13 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
* specified, the default is NoRootSquash.
*/
Azure::Nullable<Models::ShareRootSquash> RootSquash;
/**
* Version 2023-08-03 and newer. Specifies whether the snapshot virtual directory should be
* accessible at the root of share mount point when NFS is enabled. This header is only
* returned for shares, not for snapshots.
*/
Nullable<bool> EnableSnapshotVirtualDirectoryAccess;
};
/**
@ -226,6 +233,13 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
* specified, the default is NoRootSquash.
*/
Azure::Nullable<Models::ShareRootSquash> RootSquash;
/**
* Version 2023-08-03 and newer. Specifies whether the snapshot virtual directory should be
* accessible at the root of share mount point when NFS is enabled. This header is only
* returned for shares, not for snapshots.
*/
Nullable<bool> EnableSnapshotVirtualDirectoryAccess;
};
/**

View File

@ -317,7 +317,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
@ -337,7 +337,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
(void)options;
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
@ -569,7 +569,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
_internal::UrlEncodeQueryParameter(
ListSharesIncludeFlagsToString(options.Include.Value())));
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -614,6 +614,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
kLeaseDuration,
kEnabledProtocols,
kRootSquash,
kEnableSnapshotVirtualDirectoryAccess,
kNextMarker,
};
const std::unordered_map<std::string, XmlTagEnum> XmlTagEnumMap{
@ -647,6 +648,8 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
{"LeaseDuration", XmlTagEnum::kLeaseDuration},
{"EnabledProtocols", XmlTagEnum::kEnabledProtocols},
{"RootSquash", XmlTagEnum::kRootSquash},
{"EnableSnapshotVirtualDirectoryAccess",
XmlTagEnum::kEnableSnapshotVirtualDirectoryAccess},
{"NextMarker", XmlTagEnum::kNextMarker},
};
std::vector<XmlTagEnum> xmlPath;
@ -865,6 +868,15 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
{
vectorElement1.Details.RootSquash = Models::ShareRootSquash(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::kEnableSnapshotVirtualDirectoryAccess)
{
vectorElement1.Details.EnableSnapshotVirtualDirectoryAccess
= node.Value == std::string("true");
}
else if (
xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults
&& xmlPath[1] == XmlTagEnum::kNextMarker)
@ -922,7 +934,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.EnabledProtocols.HasValue()
&& !options.EnabledProtocols.Value().ToString().empty())
{
@ -932,6 +944,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
{
request.SetHeader("x-ms-root-squash", options.RootSquash.Value().ToString());
}
if (options.EnableSnapshotVirtualDirectoryAccess.HasValue())
{
request.SetHeader(
"x-ms-enable-snapshot-virtual-directory-access",
options.EnableSnapshotVirtualDirectoryAccess.Value() ? "true" : "false");
}
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Created)
@ -957,7 +975,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
request.GetUrl().AppendQueryParameter(
"sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
@ -1044,6 +1062,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
response.RootSquash
= Models::ShareRootSquash(pRawResponse->GetHeaders().at("x-ms-root-squash"));
}
if (pRawResponse->GetHeaders().count("x-ms-enable-snapshot-virtual-directory-access") != 0)
{
response.EnableSnapshotVirtualDirectoryAccess
= pRawResponse->GetHeaders().at("x-ms-enable-snapshot-virtual-directory-access")
== std::string("true");
}
return Response<Models::ShareProperties>(std::move(response), std::move(pRawResponse));
}
Response<Models::DeleteShareResult> ShareClient::Delete(
@ -1059,7 +1083,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
request.GetUrl().AppendQueryParameter(
"sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.DeleteSnapshots.HasValue() && !options.DeleteSnapshots.Value().ToString().empty())
{
request.SetHeader("x-ms-delete-snapshots", options.DeleteSnapshots.Value().ToString());
@ -1095,7 +1119,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
{
request.GetUrl().AppendQueryParameter(
@ -1129,7 +1153,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
{
request.SetHeader("x-ms-lease-id", options.LeaseId);
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
{
request.GetUrl().AppendQueryParameter(
@ -1166,7 +1190,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
{
request.GetUrl().AppendQueryParameter(
@ -1200,7 +1224,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
{
request.SetHeader("x-ms-lease-id", options.LeaseId);
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
{
request.GetUrl().AppendQueryParameter(
@ -1238,7 +1262,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
{
request.GetUrl().AppendQueryParameter(
@ -1271,7 +1295,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
{
request.SetHeader("x-ms-meta-" + p.first, p.second);
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Created)
@ -1305,7 +1329,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.FileRequestIntent.HasValue()
&& !options.FileRequestIntent.Value().ToString().empty())
{
@ -1335,7 +1359,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
{
request.SetHeader("x-ms-file-permission-key", options.FilePermissionKey);
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.FileRequestIntent.HasValue()
&& !options.FileRequestIntent.Value().ToString().empty())
{
@ -1366,7 +1390,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.Quota.HasValue())
{
request.SetHeader("x-ms-share-quota", std::to_string(options.Quota.Value()));
@ -1383,6 +1407,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
{
request.SetHeader("x-ms-root-squash", options.RootSquash.Value().ToString());
}
if (options.EnableSnapshotVirtualDirectoryAccess.HasValue())
{
request.SetHeader(
"x-ms-enable-snapshot-virtual-directory-access",
options.EnableSnapshotVirtualDirectoryAccess.Value() ? "true" : "false");
}
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -1409,7 +1439,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
{
request.SetHeader("x-ms-meta-" + p.first, p.second);
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
@ -1435,7 +1465,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
@ -1582,7 +1612,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
@ -1609,7 +1639,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
@ -1695,7 +1725,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
{
request.SetHeader("x-ms-meta-" + p.first, p.second);
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.FilePermission.HasValue() && !options.FilePermission.Value().empty())
{
request.SetHeader("x-ms-file-permission", options.FilePermission.Value());
@ -1784,7 +1814,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
request.GetUrl().AppendQueryParameter(
"sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.FileRequestIntent.HasValue()
&& !options.FileRequestIntent.Value().ToString().empty())
{
@ -1850,7 +1880,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.FileRequestIntent.HasValue()
&& !options.FileRequestIntent.Value().ToString().empty())
{
@ -1874,7 +1904,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.FilePermission.HasValue() && !options.FilePermission.Value().empty())
{
request.SetHeader("x-ms-file-permission", options.FilePermission.Value());
@ -1964,7 +1994,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
{
request.SetHeader("x-ms-meta-" + p.first, p.second);
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.AllowTrailingDot.HasValue())
{
request.SetHeader(
@ -2018,7 +2048,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.Include.HasValue()
&& !ListFilesIncludeFlagsToString(options.Include.Value()).empty())
{
@ -2411,7 +2441,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.AllowTrailingDot.HasValue())
{
request.SetHeader(
@ -2624,7 +2654,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.AllowTrailingDot.HasValue())
{
request.SetHeader(
@ -2662,7 +2692,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (!options.RenameSource.empty())
{
request.SetHeader("x-ms-file-rename-source", options.RenameSource);
@ -2770,7 +2800,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
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())
@ -2890,7 +2920,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.Range.HasValue() && !options.Range.Value().empty())
{
request.SetHeader("x-ms-range", options.Range.Value());
@ -3075,7 +3105,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
request.GetUrl().AppendQueryParameter(
"sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
@ -3213,7 +3243,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
@ -3240,7 +3270,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.FileContentLength.HasValue())
{
request.SetHeader("x-ms-content-length", std::to_string(options.FileContentLength.Value()));
@ -3364,7 +3394,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
{
request.SetHeader("x-ms-meta-" + p.first, p.second);
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
@ -3408,7 +3438,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.AllowTrailingDot.HasValue())
{
request.SetHeader(
@ -3446,7 +3476,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
{
request.SetHeader("x-ms-lease-id", options.LeaseId);
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.AllowTrailingDot.HasValue())
{
request.SetHeader(
@ -3487,7 +3517,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.AllowTrailingDot.HasValue())
{
request.SetHeader(
@ -3525,7 +3555,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.AllowTrailingDot.HasValue())
{
request.SetHeader(
@ -3572,7 +3602,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
@ -3659,7 +3689,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
@ -3735,7 +3765,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
"prevsharesnapshot",
_internal::UrlEncodeQueryParameter(options.Prevsharesnapshot.Value()));
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.Range.HasValue() && !options.Range.Value().empty())
{
request.SetHeader("x-ms-range", options.Range.Value());
@ -3864,7 +3894,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
for (const auto& p : options.Metadata)
{
request.SetHeader("x-ms-meta-" + p.first, p.second);
@ -3962,7 +3992,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
{
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
@ -4009,7 +4039,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
request.GetUrl().AppendQueryParameter(
"sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.AllowTrailingDot.HasValue())
{
request.SetHeader(
@ -4218,7 +4248,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
{
request.SetHeader("x-ms-handle-id", options.HandleId);
}
request.SetHeader("x-ms-version", "2024-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (options.AllowTrailingDot.HasValue())
{
request.SetHeader(
@ -4255,7 +4285,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-05-04");
request.SetHeader("x-ms-version", "2024-08-04");
if (!options.RenameSource.empty())
{
request.SetHeader("x-ms-file-rename-source", options.RenameSource);

View File

@ -149,6 +149,8 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
protocolLayerOptions.AccessTier = options.AccessTier;
protocolLayerOptions.EnabledProtocols = options.EnabledProtocols;
protocolLayerOptions.RootSquash = options.RootSquash;
protocolLayerOptions.EnableSnapshotVirtualDirectoryAccess
= options.EnableSnapshotVirtualDirectoryAccess;
auto result
= _detail::ShareClient::Create(*m_pipeline, m_shareUrl, protocolLayerOptions, context);
Models::CreateShareResult ret;
@ -245,6 +247,8 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
protocolLayerOptions.Quota = options.ShareQuotaInGiB;
protocolLayerOptions.AccessTier = options.AccessTier;
protocolLayerOptions.RootSquash = options.RootSquash;
protocolLayerOptions.EnableSnapshotVirtualDirectoryAccess
= options.EnableSnapshotVirtualDirectoryAccess;
return _detail::ShareClient::SetProperties(
*m_pipeline, m_shareUrl, protocolLayerOptions, context);
}

View File

@ -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/preview/2024-05-04/file.json
input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/storage/data-plane/Microsoft.FileStorage/stable/2024-08-04/file.json
```
## ModelFour Options
@ -79,12 +79,12 @@ directive:
"name": "ApiVersion",
"modelAsString": false
},
"enum": ["2024-05-04"]
"enum": ["2024-08-04"]
};
- from: swagger-document
where: $.parameters
transform: >
$.ApiVersionParameter.enum[0] = "2024-05-04";
$.ApiVersionParameter.enum[0] = "2024-08-04";
```
### Rename Operations
@ -469,6 +469,7 @@ directive:
$["x-ms-enabled-protocols"]["enum"] = ["Smb", "Nfs"];
$["x-ms-enabled-protocols"]["x-ms-enum"] = {"name": "ShareProtocols", "modelAsString": false};
$["x-ms-enabled-protocols"]["x-ms-enum"]["values"] = [{"value": "SMB", "name": "Smb"},{"value": "NFS", "name": "Nfs"}];
$["x-ms-enable-snapshot-virtual-directory-access"]["x-nullable"] = true;
- from: swagger-document
where: $["x-ms-paths"]["/{shareName}?restype=share"].get.responses["200"]
transform: >
@ -1067,6 +1068,7 @@ directive:
$.ShareItemDetails.properties["EnabledProtocols"].description = "The protocols which have been enabled on the share.";
$.ShareItemDetails.properties["RootSquash"].description = "Root squash to set on the share. Only valid for NFS shares.";
$.ShareItemDetails.properties["Last-Modified"].description = "The date and time the share was last modified.";
$.ShareItemDetails.properties["EnableSnapshotVirtualDirectoryAccess"].description = "Version 2023-08-03 and newer. Specifies whether the snapshot virtual directory should be accessible at the root of share mount point when NFS is enabled. This header is only returned for shares, not for snapshots.";
$.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.";

View File

@ -79,18 +79,6 @@ namespace Azure { namespace Storage { namespace Test {
return shareClient;
}
Files::Shares::ShareClient FileShareClientTest::GetPremiumShareClientForTest(
const std::string& shareName,
Files::Shares::ShareClientOptions clientOptions)
{
InitStorageClientOptions(clientOptions);
auto shareClient = Files::Shares::ShareClient::CreateFromConnectionString(
PremiumFileConnectionString(), shareName, clientOptions);
m_resourceCleanupFunctions.push_back([shareClient]() { shareClient.DeleteIfExists(); });
return shareClient;
}
TEST_F(FileShareClientTest, CreateDeleteShares)
{
{
@ -729,4 +717,30 @@ namespace Azure { namespace Storage { namespace Test {
shareClient = Files::Shares::ShareClient(m_shareClient->GetUrl(), credential, clientOptions);
EXPECT_THROW(shareClient.GetPermission(created.FilePermissionKey), StorageException);
}
TEST_F(FileShareClientTest, EnableSnapshotVirtualDirectoryAccess_PLAYBACKONLY_)
{
std::string shareName = LowercaseRandomString();
auto shareClient = GetPremiumShareClientForTest(shareName);
Files::Shares::CreateShareOptions createOptions;
createOptions.EnabledProtocols = Files::Shares::Models::ShareProtocols::Nfs;
shareClient.Create(createOptions);
Files::Shares::SetSharePropertiesOptions setPropertiesOptions;
// EnableSnapshotVirtualDirectoryAccess = true
setPropertiesOptions.EnableSnapshotVirtualDirectoryAccess = true;
shareClient.SetProperties(setPropertiesOptions);
auto properties = shareClient.GetProperties().Value;
EXPECT_TRUE(
properties.EnableSnapshotVirtualDirectoryAccess.HasValue()
&& properties.EnableSnapshotVirtualDirectoryAccess.Value());
// EnableSnapshotVirtualDirectoryAccess = false
setPropertiesOptions.EnableSnapshotVirtualDirectoryAccess = false;
shareClient.SetProperties(setPropertiesOptions);
properties = shareClient.GetProperties().Value;
EXPECT_TRUE(
properties.EnableSnapshotVirtualDirectoryAccess.HasValue()
&& !properties.EnableSnapshotVirtualDirectoryAccess.Value());
}
}}} // namespace Azure::Storage::Test

View File

@ -14,9 +14,6 @@ namespace Azure { namespace Storage { namespace Test {
Files::Shares::ShareClient GetShareClientForTest(
const std::string& shareName,
Files::Shares::ShareClientOptions clientOptions = Files::Shares::ShareClientOptions());
Files::Shares::ShareClient GetPremiumShareClientForTest(
const std::string& shareName,
Files::Shares::ShareClientOptions clientOptions = Files::Shares::ShareClientOptions());
protected:
std::shared_ptr<Files::Shares::ShareClient> m_shareClient;

View File

@ -493,4 +493,39 @@ namespace Azure { namespace Storage { namespace Test {
EXPECT_EQ(properties.Value.HttpHeaders.CacheControl, fileSasBuilder.CacheControl);
EXPECT_EQ(properties.Value.HttpHeaders.ContentEncoding, fileSasBuilder.ContentEncoding);
}
TEST_F(ShareSasTest, AccountSasAuthorizationErrorDetail_LIVEONLY_)
{
auto sasStartsOn = std::chrono::system_clock::now() - std::chrono::minutes(5);
auto sasExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(60);
auto keyCredential
= _internal::ParseConnectionString(StandardStorageConnectionString()).KeyCredential;
auto accountName = keyCredential->AccountName;
std::string fileName = RandomString();
auto shareClient = *m_shareClient;
auto fileClient = shareClient.GetRootDirectoryClient().GetFileClient(fileName);
fileClient.Create(1);
Sas::AccountSasBuilder accountSasBuilder;
accountSasBuilder.Protocol = Sas::SasProtocol::HttpsAndHttp;
accountSasBuilder.StartsOn = sasStartsOn;
accountSasBuilder.ExpiresOn = sasExpiresOn;
accountSasBuilder.Services = Sas::AccountSasServices::Files;
accountSasBuilder.ResourceTypes = Sas::AccountSasResource::Service;
accountSasBuilder.SetPermissions(Sas::AccountSasPermissions::All);
auto sasToken = accountSasBuilder.GenerateSasToken(*keyCredential);
auto unauthorizedFileClient = GetSasAuthenticatedClient(fileClient, sasToken);
try
{
unauthorizedFileClient.Download();
}
catch (StorageException& e)
{
EXPECT_EQ("AuthorizationResourceTypeMismatch", e.ErrorCode);
EXPECT_TRUE(e.AdditionalInformation.count("ExtendedErrorDetail") != 0);
}
}
}}} // namespace Azure::Storage::Test

View File

@ -26,6 +26,18 @@ namespace Azure { namespace Storage { namespace Test {
StandardStorageConnectionString(), options));
}
Files::Shares::ShareClient FileShareServiceClientTest::GetPremiumShareClientForTest(
const std::string& shareName,
Files::Shares::ShareClientOptions clientOptions)
{
InitStorageClientOptions(clientOptions);
auto shareClient = Files::Shares::ShareClient::CreateFromConnectionString(
PremiumFileConnectionString(), shareName, clientOptions);
m_resourceCleanupFunctions.push_back([shareClient]() { shareClient.DeleteIfExists(); });
return shareClient;
}
TEST_F(FileShareServiceClientTest, Constructors)
{
auto clientOptions = InitStorageClientOptions<Files::Shares::ShareClientOptions>();
@ -132,6 +144,53 @@ namespace Azure { namespace Storage { namespace Test {
}
}
TEST_F(FileShareServiceClientTest, ListSharesEnableSnapshotVirtualDirectoryAccess_PLAYBACKONLY_)
{
auto premiumFileShareServiceClient
= Files::Shares::ShareServiceClient::CreateFromConnectionString(
PremiumFileConnectionString(),
InitStorageClientOptions<Files::Shares::ShareClientOptions>());
std::string shareName1 = LowercaseRandomString();
std::string shareName2 = LowercaseRandomString();
auto shareClient1 = GetPremiumShareClientForTest(shareName1);
auto shareClient2 = GetPremiumShareClientForTest(shareName2);
Files::Shares::CreateShareOptions createOptions;
createOptions.EnabledProtocols = Files::Shares::Models::ShareProtocols::Nfs;
shareClient1.Create(createOptions);
shareClient2.Create(createOptions);
Files::Shares::SetSharePropertiesOptions setPropertiesOptions;
setPropertiesOptions.EnableSnapshotVirtualDirectoryAccess = true;
shareClient1.SetProperties(setPropertiesOptions);
setPropertiesOptions.EnableSnapshotVirtualDirectoryAccess = false;
shareClient2.SetProperties(setPropertiesOptions);
Azure::Nullable<Files::Shares::Models::ShareItem> share1;
Azure::Nullable<Files::Shares::Models::ShareItem> share2;
for (auto page = premiumFileShareServiceClient.ListShares(); page.HasPage();
page.MoveToNextPage())
{
for (const auto& share : page.Shares)
{
if (share.Name == shareName1)
{
share1 = share;
}
else if (share.Name == shareName2)
{
share2 = share;
}
}
}
ASSERT_TRUE(share1.HasValue() && share2.HasValue());
EXPECT_TRUE(
share1.Value().Details.EnableSnapshotVirtualDirectoryAccess.HasValue()
&& share1.Value().Details.EnableSnapshotVirtualDirectoryAccess.Value());
EXPECT_TRUE(
share2.Value().Details.EnableSnapshotVirtualDirectoryAccess.HasValue()
&& !share2.Value().Details.EnableSnapshotVirtualDirectoryAccess.Value());
}
TEST_F(FileShareServiceClientTest, GetProperties)
{
auto ret = m_shareServiceClient->GetProperties();

View File

@ -11,6 +11,10 @@ namespace Azure { namespace Storage { namespace Test {
protected:
void SetUp() override;
Files::Shares::ShareClient GetPremiumShareClientForTest(
const std::string& shareName,
Files::Shares::ShareClientOptions clientOptions = Files::Shares::ShareClientOptions());
protected:
std::shared_ptr<Files::Shares::ShareServiceClient> m_shareServiceClient;
};

View File

@ -4,11 +4,8 @@
### Features Added
### Breaking Changes
### Bugs Fixed
### Other Changes
- Bumped up API version to `2024-08-04`.
- Added more detailed messaging for authorization failure cases.
## 12.2.0 (2023-11-07)

View File

@ -101,6 +101,12 @@ namespace Azure { namespace Storage { namespace Queues {
*/
AZ_STORAGE_QUEUES_DLLEXPORT const static ServiceVersion V2019_12_12;
/**
* @brief API version 2024-08-04.
*
*/
AZ_STORAGE_QUEUES_DLLEXPORT const static ServiceVersion V2024_08_04;
private:
std::string m_version;
};

View File

@ -26,7 +26,7 @@ namespace Azure { namespace Storage { namespace Queues {
/**
* The version used for the operations to Azure storage services.
*/
constexpr static const char* ApiVersion = "2019-12-12";
constexpr static const char* ApiVersion = "2024-08-04";
} // namespace _detail
namespace Models {
/**

View File

@ -9,6 +9,7 @@ namespace Azure { namespace Storage { namespace Queues {
const ServiceVersion ServiceVersion::V2018_03_28(std::string("2018-03-28"));
const ServiceVersion ServiceVersion::V2019_12_12(std::string("2019-12-12"));
const ServiceVersion ServiceVersion::V2024_08_04(std::string("2024-08-04"));
const std::chrono::seconds EnqueueMessageOptions::MessageNeverExpires{-1};
}}} // namespace Azure::Storage::Queues

View File

@ -189,7 +189,7 @@ namespace Azure { namespace Storage { namespace Queues {
request.SetHeader("Content-Length", std::to_string(requestBody.Length()));
request.GetUrl().AppendQueryParameter("restype", "service");
request.GetUrl().AppendQueryParameter("comp", "properties");
request.SetHeader("x-ms-version", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
@ -209,7 +209,7 @@ namespace Azure { namespace Storage { namespace Queues {
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", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
(void)options;
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
@ -446,7 +446,7 @@ namespace Azure { namespace Storage { namespace Queues {
auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
request.GetUrl().AppendQueryParameter("restype", "service");
request.GetUrl().AppendQueryParameter("comp", "stats");
request.SetHeader("x-ms-version", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
(void)options;
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
@ -546,7 +546,7 @@ namespace Azure { namespace Storage { namespace Queues {
_internal::UrlEncodeQueryParameter(
ListQueuesIncludeFlagsToString(options.Include.Value())));
}
request.SetHeader("x-ms-version", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -669,7 +669,7 @@ namespace Azure { namespace Storage { namespace Queues {
{
request.SetHeader("x-ms-meta-" + p.first, p.second);
}
request.SetHeader("x-ms-version", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (!(httpStatusCode == Core::Http::HttpStatusCode::Created
@ -687,7 +687,7 @@ namespace Azure { namespace Storage { namespace Queues {
const Core::Context& context)
{
auto request = Core::Http::Request(Core::Http::HttpMethod::Delete, url);
request.SetHeader("x-ms-version", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
(void)options;
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
@ -706,7 +706,7 @@ namespace Azure { namespace Storage { namespace Queues {
{
auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
request.GetUrl().AppendQueryParameter("comp", "metadata");
request.SetHeader("x-ms-version", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
(void)options;
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
@ -737,7 +737,7 @@ namespace Azure { namespace Storage { namespace Queues {
{
request.SetHeader("x-ms-meta-" + p.first, p.second);
}
request.SetHeader("x-ms-version", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::NoContent)
@ -755,7 +755,7 @@ namespace Azure { namespace Storage { namespace Queues {
{
auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
request.GetUrl().AppendQueryParameter("comp", "acl");
request.SetHeader("x-ms-version", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
(void)options;
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
@ -898,7 +898,7 @@ namespace Azure { namespace Storage { namespace Queues {
request.SetHeader("Content-Type", "application/xml; charset=UTF-8");
request.SetHeader("Content-Length", std::to_string(requestBody.Length()));
request.GetUrl().AppendQueryParameter("comp", "acl");
request.SetHeader("x-ms-version", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::NoContent)
@ -926,7 +926,7 @@ namespace Azure { namespace Storage { namespace Queues {
request.GetUrl().AppendQueryParameter(
"visibilitytimeout", std::to_string(options.Visibilitytimeout.Value()));
}
request.SetHeader("x-ms-version", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -1052,7 +1052,7 @@ namespace Azure { namespace Storage { namespace Queues {
const Core::Context& context)
{
auto request = Core::Http::Request(Core::Http::HttpMethod::Delete, url);
request.SetHeader("x-ms-version", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
(void)options;
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
@ -1094,7 +1094,7 @@ namespace Azure { namespace Storage { namespace Queues {
request.GetUrl().AppendQueryParameter(
"messagettl", std::to_string(options.MessageTimeToLive.Value()));
}
request.SetHeader("x-ms-version", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Created)
@ -1203,7 +1203,7 @@ namespace Azure { namespace Storage { namespace Queues {
request.GetUrl().AppendQueryParameter(
"numofmessages", std::to_string(options.NumberOfMessages.Value()));
}
request.SetHeader("x-ms-version", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
@ -1332,7 +1332,7 @@ namespace Azure { namespace Storage { namespace Queues {
}
request.GetUrl().AppendQueryParameter(
"visibilitytimeout", std::to_string(options.Visibilitytimeout));
request.SetHeader("x-ms-version", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::NoContent)
@ -1358,7 +1358,7 @@ namespace Azure { namespace Storage { namespace Queues {
request.GetUrl().AppendQueryParameter(
"popreceipt", _internal::UrlEncodeQueryParameter(options.PopReceipt));
}
request.SetHeader("x-ms-version", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::NoContent)
@ -1382,7 +1382,7 @@ namespace Azure { namespace Storage { namespace Queues {
}
request.GetUrl().AppendQueryParameter(
"visibilitytimeout", std::to_string(options.Visibilitytimeout));
request.SetHeader("x-ms-version", "2019-12-12");
request.SetHeader("x-ms-version", "2024-08-04");
auto pRawResponse = pipeline.Send(request, context);
auto httpStatusCode = pRawResponse->GetStatusCode();
if (httpStatusCode != Core::Http::HttpStatusCode::NoContent)

View File

@ -9,7 +9,7 @@ package-name: azure-storage-queues
namespace: Azure::Storage::Queues
output-folder: generated
clear-output-folder: true
input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/storage/data-plane/Microsoft.QueueStorage/preview/2018-03-28/queue.json
input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/storage/data-plane/Microsoft.QueueStorage/stable/2018-03-28/queue.json
```
## ModelFour Options
@ -77,13 +77,13 @@ directive:
"name": "ApiVersion",
"modelAsString": false
},
"enum": ["2019-12-12"],
"enum": ["2024-08-04"],
"description": "The version used for the operations to Azure storage services."
};
- from: swagger-document
where: $.parameters
transform: >
$.ApiVersionParameter.enum[0] = "2019-12-12";
$.ApiVersionParameter.enum[0] = "2024-08-04";
```
### Rename Operations

View File

@ -317,4 +317,34 @@ namespace Azure { namespace Storage { namespace Test {
VerifyQueueSasRead(queueClient, sasToken);
}
TEST_F(QueueSasTest, AccountSasAuthorizationErrorDetail_LIVEONLY_)
{
auto sasStartsOn = std::chrono::system_clock::now() - std::chrono::minutes(5);
auto sasExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(60);
Sas::AccountSasBuilder accountSasBuilder;
accountSasBuilder.Protocol = Sas::SasProtocol::HttpsAndHttp;
accountSasBuilder.StartsOn = sasStartsOn;
accountSasBuilder.ExpiresOn = sasExpiresOn;
accountSasBuilder.Services = Sas::AccountSasServices::Queue;
accountSasBuilder.ResourceTypes = Sas::AccountSasResource::Object;
accountSasBuilder.SetPermissions(Sas::AccountSasPermissions::All);
auto keyCredential
= _internal::ParseConnectionString(StandardStorageConnectionString()).KeyCredential;
auto queueServiceClient = *m_queueServiceClient;
auto sasToken = accountSasBuilder.GenerateSasToken(*keyCredential);
auto unauthorizedQueueServiceClient = GetSasAuthenticatedClient(queueServiceClient, sasToken);
try
{
unauthorizedQueueServiceClient.ListQueues();
}
catch (StorageException& e)
{
EXPECT_EQ("AuthorizationResourceTypeMismatch", e.ErrorCode);
EXPECT_TRUE(e.AdditionalInformation.count("ExtendedErrorDetail") != 0);
}
}
}}} // namespace Azure::Storage::Test

View File

@ -342,4 +342,73 @@ namespace Azure { namespace Storage { namespace Test {
= Queues::QueueServiceClient(m_queueServiceClient->GetUrl(), credential, clientOptions);
EXPECT_THROW(queueServiceClient.GetProperties(), StorageException);
}
TEST_F(QueueServiceClientTest, BearerChallengeWorks)
{
auto clientOptions = InitStorageClientOptions<Queues::QueueClientOptions>();
auto options = InitStorageClientOptions<Azure::Identity::ClientSecretCredentialOptions>();
// With tenantId
clientOptions.EnableTenantDiscovery = true;
options.AdditionallyAllowedTenants = {"*"};
auto queueServiceClient = Queues::QueueServiceClient(
m_queueServiceClient->GetUrl(),
std::make_shared<Azure::Identity::ClientSecretCredential>(
AadTenantId(), AadClientId(), AadClientSecret(), options),
clientOptions);
EXPECT_NO_THROW(queueServiceClient.GetProperties());
// Without tenantId
clientOptions.EnableTenantDiscovery = true;
options.AdditionallyAllowedTenants = {"*"};
queueServiceClient = Queues::QueueServiceClient(
m_queueServiceClient->GetUrl(),
std::make_shared<Azure::Identity::ClientSecretCredential>(
"", AadClientId(), AadClientSecret(), options),
clientOptions);
EXPECT_NO_THROW(queueServiceClient.GetProperties());
// With custom audience
auto queueUrl = Azure::Core::Url(m_queueServiceClient->GetUrl());
clientOptions.Audience
= Queues::QueueAudience(queueUrl.GetScheme() + "://" + queueUrl.GetHost());
queueServiceClient = Queues::QueueServiceClient(
m_queueServiceClient->GetUrl(),
std::make_shared<Azure::Identity::ClientSecretCredential>(
"", AadClientId(), AadClientSecret(), options),
clientOptions);
EXPECT_NO_THROW(queueServiceClient.GetProperties());
clientOptions.Audience.Reset();
// With error tenantId
clientOptions.EnableTenantDiscovery = true;
options.AdditionallyAllowedTenants = {"*"};
queueServiceClient = Queues::QueueServiceClient(
m_queueServiceClient->GetUrl(),
std::make_shared<Azure::Identity::ClientSecretCredential>(
"test", AadClientId(), AadClientSecret(), options),
clientOptions);
EXPECT_NO_THROW(queueServiceClient.GetProperties());
// Disable Tenant Discovery and without tenantId
clientOptions.EnableTenantDiscovery = false;
queueServiceClient = Queues::QueueServiceClient(
m_queueServiceClient->GetUrl(),
std::make_shared<Azure::Identity::ClientSecretCredential>(
"", AadClientId(), AadClientSecret(), options),
clientOptions);
EXPECT_THROW(
queueServiceClient.GetProperties(), Azure::Core::Credentials::AuthenticationException);
// Don't allow additional tenants
clientOptions.EnableTenantDiscovery = true;
options.AdditionallyAllowedTenants = {};
queueServiceClient = Queues::QueueServiceClient(
m_queueServiceClient->GetUrl(),
std::make_shared<Azure::Identity::ClientSecretCredential>(
"", AadClientId(), AadClientSecret(), options),
clientOptions);
EXPECT_THROW(
queueServiceClient.GetProperties(), Azure::Core::Credentials::AuthenticationException);
}
}}} // namespace Azure::Storage::Test