Storage STG99 Features (#6622)
* Changed QueueProperties.ApproximateMessagesCount from int to long (#6584) * Storage/STG99 Added ShareSnapshotNotFound in ShareErrorCode (#6612) * Share SnapshotNotFound error code support * add test record * Storage/STG99 Made error message for invalid x-ms-version more user-friendly (#6613) * add invalid version erorr message support * Update find logic * Stg99/Add test records and update change logs (#6620) * Update test records and change logs * update change log
This commit is contained in:
parent
d9eacda722
commit
17563c7c01
@ -2,5 +2,5 @@
|
||||
"AssetsRepo": "Azure/azure-sdk-assets",
|
||||
"AssetsRepoPrefixPath": "cpp",
|
||||
"TagPrefix": "cpp/storage",
|
||||
"Tag": "cpp/storage_7bea1dff90"
|
||||
"Tag": "cpp/storage_7f9ca72801"
|
||||
}
|
||||
|
||||
@ -1,14 +1,10 @@
|
||||
# Release History
|
||||
|
||||
## 12.14.0-beta.2 (Unreleased)
|
||||
## 12.15.0-beta.1 (2025-06-11)
|
||||
|
||||
### Features Added
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
### Other Changes
|
||||
- Added more useful error message when the SDK encounters an x-ms-version mis-match issue.
|
||||
|
||||
## 12.14.0-beta.1 (2025-05-13)
|
||||
|
||||
|
||||
@ -2264,4 +2264,20 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
blobProperties = versionClient.GetProperties().Value;
|
||||
EXPECT_TRUE(blobProperties.HasLegalHold);
|
||||
}
|
||||
|
||||
TEST_F(BlockBlobClientTest, InvalidVersionMessage)
|
||||
{
|
||||
Blobs::BlobClientOptions options;
|
||||
options.ApiVersion = "3015-11-11";
|
||||
auto blobClient = GetBlockBlobClientForTest(LowercaseRandomString(), options);
|
||||
try
|
||||
{
|
||||
blobClient.Download();
|
||||
}
|
||||
catch (const StorageException& e)
|
||||
{
|
||||
EXPECT_EQ(e.ErrorCode, _internal::InvalidHeaderValueErrorCode);
|
||||
EXPECT_EQ(e.Message, _internal::InvalidVersionHeaderMessage);
|
||||
}
|
||||
}
|
||||
}}} // namespace Azure::Storage::Test
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
# Release History
|
||||
|
||||
## 12.11.0-beta.1 (Unreleased)
|
||||
## 12.12.0-beta.1 (2025-06-11)
|
||||
|
||||
### Features Added
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
### Bugs Fixed
|
||||
- Added more useful error message when the SDK encounters an x-ms-version mis-match issue.
|
||||
|
||||
### Other Changes
|
||||
|
||||
|
||||
@ -21,6 +21,11 @@ namespace Azure { namespace Storage { namespace _internal {
|
||||
constexpr static const char* HttpHeaderContentType = "content-type";
|
||||
constexpr static const char* HttpHeaderContentLength = "content-length";
|
||||
constexpr static const char* HttpHeaderContentRange = "content-range";
|
||||
constexpr static const char* InvalidHeaderValueErrorCode = "InvalidHeaderValue";
|
||||
constexpr static const char* InvalidVersionHeaderMessage
|
||||
= "The provided service version is not enabled on this storage account. Please see "
|
||||
"https://learn.microsoft.com/rest/api/storageservices/"
|
||||
"versioning-for-the-azure-storage-services for additional information.";
|
||||
|
||||
constexpr int ReliableStreamRetryCount = 3;
|
||||
}}} // namespace Azure::Storage::_internal
|
||||
|
||||
@ -147,6 +147,14 @@ namespace Azure { namespace Storage {
|
||||
errorCode = response->GetHeaders().at("x-ms-error-code");
|
||||
}
|
||||
|
||||
// Optimize error messages
|
||||
const auto headerName = additionalInformation.find("HeaderName");
|
||||
if (errorCode == _internal::InvalidHeaderValueErrorCode
|
||||
&& headerName != additionalInformation.end() && headerName->second == "x-ms-version")
|
||||
{
|
||||
message = _internal::InvalidVersionHeaderMessage;
|
||||
}
|
||||
|
||||
StorageException result = StorageException(
|
||||
std::to_string(static_cast<std::underlying_type<Azure::Core::Http::HttpStatusCode>::type>(
|
||||
httpStatusCode))
|
||||
|
||||
@ -1,14 +1,10 @@
|
||||
# Release History
|
||||
|
||||
## 12.13.0-beta.1 (Unreleased)
|
||||
## 12.13.0-beta.1 (2025-06-11)
|
||||
|
||||
### Features Added
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
### Other Changes
|
||||
- Added more useful error message when the SDK encounters an x-ms-version mis-match issue.
|
||||
|
||||
## 12.12.0 (2024-09-17)
|
||||
|
||||
|
||||
@ -1,14 +1,11 @@
|
||||
# Release History
|
||||
|
||||
## 12.14.0-beta.2 (Unreleased)
|
||||
## 12.15.0-beta.1 (2025-06-11)
|
||||
|
||||
### Features Added
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
### Other Changes
|
||||
- `ShareClient::DeleteIfExists()` will return `false` when error code is `ShareSnapshotNotFound`.
|
||||
- Added more useful error message when the SDK encounters an x-ms-version mis-match issue.
|
||||
|
||||
## 12.14.0-beta.1 (2025-05-13)
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
|
||||
constexpr static const char* ResourceNotFound = "ResourceNotFound";
|
||||
constexpr static const char* ShareAlreadyExists = "ShareAlreadyExists";
|
||||
constexpr static const char* ShareNotFound = "ShareNotFound";
|
||||
constexpr static const char* ShareSnapshotNotFound = "ShareSnapshotNotFound";
|
||||
constexpr static const char* ResourceAlreadyExists = "ResourceAlreadyExists";
|
||||
} // namespace _detail
|
||||
|
||||
|
||||
@ -222,7 +222,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
|
||||
}
|
||||
catch (StorageException& e)
|
||||
{
|
||||
if (e.ErrorCode == _detail::ShareNotFound)
|
||||
if (e.ErrorCode == _detail::ShareNotFound || e.ErrorCode == _detail::ShareSnapshotNotFound)
|
||||
{
|
||||
Models::DeleteShareResult ret;
|
||||
ret.Deleted = false;
|
||||
|
||||
@ -124,6 +124,15 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(FileShareClientTest, SnapshotNotFoundErrorCode)
|
||||
{
|
||||
auto shareSnapshot = m_shareClient->WithSnapshot("2025-02-04T10:17:47.0000000Z");
|
||||
|
||||
Files::Shares::Models::DeleteShareResult deleteResult;
|
||||
EXPECT_NO_THROW(deleteResult = shareSnapshot.DeleteIfExists().Value);
|
||||
EXPECT_FALSE(deleteResult.Deleted);
|
||||
}
|
||||
|
||||
TEST_F(FileShareClientTest, ShareMetadata)
|
||||
{
|
||||
auto metadata1 = RandomMetadata();
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
# Release History
|
||||
|
||||
## 12.5.0-beta.1 (Unreleased)
|
||||
## 12.5.0-beta.1 (2025-06-11)
|
||||
|
||||
### Features Added
|
||||
|
||||
- Added more useful error message when the SDK encounters an x-ms-version mis-match issue.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
### Other Changes
|
||||
- `QueueProperties.ApproximateMessageCount` is deprecated. The value is `-1` if the value exceeds `INT32_MAX`. Use `QueueProperties.ApproximateMessageCountLong` instead.
|
||||
|
||||
## 12.4.0 (2024-09-17)
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "azure/storage/queues/queue_options.hpp"
|
||||
#include "azure/storage/queues/queue_responses.hpp"
|
||||
|
||||
#include <azure/core/credentials/credentials.hpp>
|
||||
#include <azure/storage/common/storage_credential.hpp>
|
||||
|
||||
@ -20,6 +20,32 @@ namespace Azure { namespace Storage { namespace Queues {
|
||||
|
||||
class QueueServiceClient;
|
||||
|
||||
namespace Models {
|
||||
/**
|
||||
* @brief Response type for #Azure::Storage::Queues::QueueClient::GetProperties.
|
||||
*/
|
||||
struct QueueProperties final
|
||||
{
|
||||
/**
|
||||
* A set of name-value pairs associated with this queue.
|
||||
*/
|
||||
Core::CaseInsensitiveMap Metadata;
|
||||
/**
|
||||
* The approximate number of messages in the queue. This number is not lower than the actual
|
||||
* number of messages in the queue, but could be higher.
|
||||
*
|
||||
* This field is deprecated. The value is -1 if the value exceeds
|
||||
* INT32_MAX.Use ApproximateMessageCountLong instead.
|
||||
*/
|
||||
std::int32_t ApproximateMessageCount = std::int32_t();
|
||||
/**
|
||||
* The approximate number of messages in the queue. This number is not lower than the actual
|
||||
* number of messages in the queue, but could be higher.
|
||||
*/
|
||||
std::int64_t ApproximateMessageCountLong = std::int64_t();
|
||||
};
|
||||
} // namespace Models
|
||||
|
||||
/**
|
||||
* @brief Response type for #Azure::Storage::Queues::QueueServiceClient::ListQueues.
|
||||
*/
|
||||
|
||||
@ -283,21 +283,23 @@ namespace Azure { namespace Storage { namespace Queues {
|
||||
*/
|
||||
bool Deleted = true;
|
||||
};
|
||||
/**
|
||||
* @brief Response type for #Azure::Storage::Queues::QueueClient::GetProperties.
|
||||
*/
|
||||
struct QueueProperties final
|
||||
{
|
||||
namespace _detail {
|
||||
/**
|
||||
* A set of name-value pairs associated with this queue.
|
||||
* @brief Response type for #Azure::Storage::Queues::QueueClient::GetProperties.
|
||||
*/
|
||||
Core::CaseInsensitiveMap Metadata;
|
||||
/**
|
||||
* The approximate number of messages in the queue. This number is not lower than the actual
|
||||
* number of messages in the queue, but could be higher.
|
||||
*/
|
||||
std::int32_t ApproximateMessageCount = std::int32_t();
|
||||
};
|
||||
struct QueueProperties final
|
||||
{
|
||||
/**
|
||||
* A set of name-value pairs associated with this queue.
|
||||
*/
|
||||
Core::CaseInsensitiveMap Metadata;
|
||||
/**
|
||||
* The approximate number of messages in the queue. This number is not lower than the actual
|
||||
* number of messages in the queue, but could be higher.
|
||||
*/
|
||||
std::int64_t ApproximateMessageCount = std::int64_t();
|
||||
};
|
||||
} // namespace _detail
|
||||
/**
|
||||
* @brief Response type for #Azure::Storage::Queues::QueueClient::SetMetadata.
|
||||
*/
|
||||
@ -554,7 +556,7 @@ namespace Azure { namespace Storage { namespace Queues {
|
||||
struct GetQueuePropertiesOptions final
|
||||
{
|
||||
};
|
||||
static Response<Models::QueueProperties> GetProperties(
|
||||
static Response<Models::_detail::QueueProperties> GetProperties(
|
||||
Core::Http::_internal::HttpPipeline& pipeline,
|
||||
const Core::Url& url,
|
||||
const GetQueuePropertiesOptions& options,
|
||||
|
||||
@ -165,8 +165,22 @@ namespace Azure { namespace Storage { namespace Queues {
|
||||
{
|
||||
(void)options;
|
||||
_detail::QueueClient::GetQueuePropertiesOptions protocolLayerOptions;
|
||||
return _detail::QueueClient::GetProperties(
|
||||
auto ret = _detail::QueueClient::GetProperties(
|
||||
*m_pipeline, m_queueUrl, protocolLayerOptions, context);
|
||||
Models::QueueProperties queueProperties;
|
||||
queueProperties.Metadata = std::move(ret.Value.Metadata);
|
||||
if (ret.Value.ApproximateMessageCount > static_cast<int64_t>(INT32_MAX))
|
||||
{
|
||||
queueProperties.ApproximateMessageCount = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
queueProperties.ApproximateMessageCount
|
||||
= static_cast<std::int32_t>(ret.Value.ApproximateMessageCount);
|
||||
}
|
||||
queueProperties.ApproximateMessageCountLong = ret.Value.ApproximateMessageCount;
|
||||
return Azure::Response<Models::QueueProperties>(
|
||||
std::move(queueProperties), std::move(ret.RawResponse));
|
||||
}
|
||||
|
||||
Azure::Response<Models::SetQueueMetadataResult> QueueClient::SetMetadata(
|
||||
|
||||
@ -698,7 +698,7 @@ namespace Azure { namespace Storage { namespace Queues {
|
||||
Models::DeleteQueueResult response;
|
||||
return Response<Models::DeleteQueueResult>(std::move(response), std::move(pRawResponse));
|
||||
}
|
||||
Response<Models::QueueProperties> QueueClient::GetProperties(
|
||||
Response<Models::_detail::QueueProperties> QueueClient::GetProperties(
|
||||
Core::Http::_internal::HttpPipeline& pipeline,
|
||||
const Core::Url& url,
|
||||
const GetQueuePropertiesOptions& options,
|
||||
@ -714,7 +714,7 @@ namespace Azure { namespace Storage { namespace Queues {
|
||||
{
|
||||
throw StorageException::CreateFromResponse(std::move(pRawResponse));
|
||||
}
|
||||
Models::QueueProperties response;
|
||||
Models::_detail::QueueProperties response;
|
||||
for (auto i = pRawResponse->GetHeaders().lower_bound("x-ms-meta-");
|
||||
i != pRawResponse->GetHeaders().end() && i->first.substr(0, 10) == "x-ms-meta-";
|
||||
++i)
|
||||
@ -722,8 +722,9 @@ namespace Azure { namespace Storage { namespace Queues {
|
||||
response.Metadata.emplace(i->first.substr(10), i->second);
|
||||
}
|
||||
response.ApproximateMessageCount
|
||||
= std::stoi(pRawResponse->GetHeaders().at("x-ms-approximate-messages-count"));
|
||||
return Response<Models::QueueProperties>(std::move(response), std::move(pRawResponse));
|
||||
= std::stoll(pRawResponse->GetHeaders().at("x-ms-approximate-messages-count"));
|
||||
return Response<Models::_detail::QueueProperties>(
|
||||
std::move(response), std::move(pRawResponse));
|
||||
}
|
||||
Response<Models::SetQueueMetadataResult> QueueClient::SetMetadata(
|
||||
Core::Http::_internal::HttpPipeline& pipeline,
|
||||
|
||||
@ -278,6 +278,7 @@ directive:
|
||||
"type": "object",
|
||||
"x-ms-client-name": "QueueProperties",
|
||||
"x-ms-sealed": false,
|
||||
"x-namespace": "_detail",
|
||||
"properties": {"__placeHolder": {"type": "integer"}}
|
||||
};
|
||||
```
|
||||
|
||||
@ -185,6 +185,39 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
EXPECT_TRUE(properties.Metadata.empty());
|
||||
}
|
||||
|
||||
TEST_F(QueueClientTest, ApproximateMessageCount)
|
||||
{
|
||||
int messageCount = 0;
|
||||
m_queueClient->EnqueueMessage("test");
|
||||
++messageCount;
|
||||
auto res = m_queueClient->GetProperties();
|
||||
EXPECT_EQ(res.Value.ApproximateMessageCount, messageCount);
|
||||
EXPECT_EQ(res.Value.ApproximateMessageCountLong, messageCount);
|
||||
|
||||
for (; messageCount < 10; ++messageCount)
|
||||
{
|
||||
m_queueClient->EnqueueMessage("test");
|
||||
}
|
||||
res = m_queueClient->GetProperties();
|
||||
EXPECT_EQ(res.Value.ApproximateMessageCount, messageCount);
|
||||
EXPECT_EQ(res.Value.ApproximateMessageCountLong, messageCount);
|
||||
}
|
||||
|
||||
TEST_F(QueueClientTest, ApproximateMessageCountLong_PLAYBACKONLY_)
|
||||
{
|
||||
// Hardcode the x-ms-approximate-messages-count header to INT32_MAX in recording file.
|
||||
m_queueClient->EnqueueMessage("test");
|
||||
// Mock the recording file to INT32_MAX
|
||||
auto res = m_queueClient->GetProperties();
|
||||
EXPECT_EQ(res.Value.ApproximateMessageCount, INT32_MAX);
|
||||
EXPECT_EQ(res.Value.ApproximateMessageCountLong, INT32_MAX);
|
||||
|
||||
// Hardcode the x-ms-approximate-messages-count header to INT64_MAX in recording file.
|
||||
res = m_queueClient->GetProperties();
|
||||
EXPECT_EQ(res.Value.ApproximateMessageCount, -1);
|
||||
EXPECT_EQ(res.Value.ApproximateMessageCountLong, INT64_MAX);
|
||||
}
|
||||
|
||||
TEST_F(QueueClientTest, AccessControlList_LIVEONLY_)
|
||||
{
|
||||
auto clientOptions = InitStorageClientOptions<Queues::QueueClientOptions>();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user