Fixed a bug where sequence number access conditions didn't work for page blob operations (#2643)
* PageBlobClient::Resize doesn't support sequence number access conditions * PageBlobClient::UpdateSequenceNumber doesn't support seq access conditions * Fixed a bug where sequence number access conditions didn't work for page blob operations
This commit is contained in:
parent
b4037ee591
commit
c4b88f933e
@ -16,6 +16,7 @@
|
||||
### Bugs Fixed
|
||||
|
||||
- Fixed a bug where lease ID didn't work for `BlobContainerClient::GetAccessPolicy()`.
|
||||
- Fixed a bug where sequence number access conditions didn't work for page blob operations.
|
||||
- Fixed a bug where `BlobItemDetails::EncryptionKeySha256` was always null because it wasn't correctly parsed from xml.
|
||||
|
||||
### Other Changes
|
||||
|
||||
@ -10270,9 +10270,6 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
Azure::Nullable<int32_t> Timeout;
|
||||
int64_t BlobSize = -1;
|
||||
Azure::Nullable<std::string> LeaseId;
|
||||
Azure::Nullable<int64_t> IfSequenceNumberLessThanOrEqualTo;
|
||||
Azure::Nullable<int64_t> IfSequenceNumberLessThan;
|
||||
Azure::Nullable<int64_t> IfSequenceNumberEqualTo;
|
||||
Azure::Nullable<Azure::DateTime> IfModifiedSince;
|
||||
Azure::Nullable<Azure::DateTime> IfUnmodifiedSince;
|
||||
Azure::ETag IfMatch;
|
||||
@ -10301,24 +10298,6 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
{
|
||||
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
|
||||
}
|
||||
if (options.IfSequenceNumberLessThanOrEqualTo.HasValue())
|
||||
{
|
||||
request.SetHeader(
|
||||
"x-ms-if-sequence-number-le",
|
||||
std::to_string(options.IfSequenceNumberLessThanOrEqualTo.Value()));
|
||||
}
|
||||
if (options.IfSequenceNumberLessThan.HasValue())
|
||||
{
|
||||
request.SetHeader(
|
||||
"x-ms-if-sequence-number-lt",
|
||||
std::to_string(options.IfSequenceNumberLessThan.Value()));
|
||||
}
|
||||
if (options.IfSequenceNumberEqualTo.HasValue())
|
||||
{
|
||||
request.SetHeader(
|
||||
"x-ms-if-sequence-number-eq",
|
||||
std::to_string(options.IfSequenceNumberEqualTo.Value()));
|
||||
}
|
||||
if (options.IfModifiedSince.HasValue())
|
||||
{
|
||||
request.SetHeader(
|
||||
@ -10368,9 +10347,6 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
SequenceNumberAction Action;
|
||||
Azure::Nullable<int64_t> SequenceNumber;
|
||||
Azure::Nullable<std::string> LeaseId;
|
||||
Azure::Nullable<int64_t> IfSequenceNumberLessThanOrEqualTo;
|
||||
Azure::Nullable<int64_t> IfSequenceNumberLessThan;
|
||||
Azure::Nullable<int64_t> IfSequenceNumberEqualTo;
|
||||
Azure::Nullable<Azure::DateTime> IfModifiedSince;
|
||||
Azure::Nullable<Azure::DateTime> IfUnmodifiedSince;
|
||||
Azure::ETag IfMatch;
|
||||
@ -10398,24 +10374,6 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
{
|
||||
request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
|
||||
}
|
||||
if (options.IfSequenceNumberLessThanOrEqualTo.HasValue())
|
||||
{
|
||||
request.SetHeader(
|
||||
"x-ms-if-sequence-number-le",
|
||||
std::to_string(options.IfSequenceNumberLessThanOrEqualTo.Value()));
|
||||
}
|
||||
if (options.IfSequenceNumberLessThan.HasValue())
|
||||
{
|
||||
request.SetHeader(
|
||||
"x-ms-if-sequence-number-lt",
|
||||
std::to_string(options.IfSequenceNumberLessThan.Value()));
|
||||
}
|
||||
if (options.IfSequenceNumberEqualTo.HasValue())
|
||||
{
|
||||
request.SetHeader(
|
||||
"x-ms-if-sequence-number-eq",
|
||||
std::to_string(options.IfSequenceNumberEqualTo.Value()));
|
||||
}
|
||||
if (options.IfModifiedSince.HasValue())
|
||||
{
|
||||
request.SetHeader(
|
||||
|
||||
@ -145,6 +145,11 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
protocolLayerOptions.IfMatch = options.AccessConditions.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.AccessConditions.IfNoneMatch;
|
||||
protocolLayerOptions.IfTags = options.AccessConditions.TagConditions;
|
||||
protocolLayerOptions.IfSequenceNumberLessThanOrEqualTo
|
||||
= options.AccessConditions.IfSequenceNumberLessThanOrEqual;
|
||||
protocolLayerOptions.IfSequenceNumberLessThan
|
||||
= options.AccessConditions.IfSequenceNumberLessThan;
|
||||
protocolLayerOptions.IfSequenceNumberEqualTo = options.AccessConditions.IfSequenceNumberEqual;
|
||||
if (m_customerProvidedKey.HasValue())
|
||||
{
|
||||
protocolLayerOptions.EncryptionKey = m_customerProvidedKey.Value().Key;
|
||||
@ -175,6 +180,11 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
protocolLayerOptions.IfMatch = options.AccessConditions.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.AccessConditions.IfNoneMatch;
|
||||
protocolLayerOptions.IfTags = options.AccessConditions.TagConditions;
|
||||
protocolLayerOptions.IfSequenceNumberLessThanOrEqualTo
|
||||
= options.AccessConditions.IfSequenceNumberLessThanOrEqual;
|
||||
protocolLayerOptions.IfSequenceNumberLessThan
|
||||
= options.AccessConditions.IfSequenceNumberLessThan;
|
||||
protocolLayerOptions.IfSequenceNumberEqualTo = options.AccessConditions.IfSequenceNumberEqual;
|
||||
protocolLayerOptions.SourceIfModifiedSince = options.SourceAccessConditions.IfModifiedSince;
|
||||
protocolLayerOptions.SourceIfUnmodifiedSince = options.SourceAccessConditions.IfUnmodifiedSince;
|
||||
protocolLayerOptions.SourceIfMatch = options.SourceAccessConditions.IfMatch;
|
||||
@ -203,6 +213,11 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
protocolLayerOptions.IfMatch = options.AccessConditions.IfMatch;
|
||||
protocolLayerOptions.IfNoneMatch = options.AccessConditions.IfNoneMatch;
|
||||
protocolLayerOptions.IfTags = options.AccessConditions.TagConditions;
|
||||
protocolLayerOptions.IfSequenceNumberLessThanOrEqualTo
|
||||
= options.AccessConditions.IfSequenceNumberLessThanOrEqual;
|
||||
protocolLayerOptions.IfSequenceNumberLessThan
|
||||
= options.AccessConditions.IfSequenceNumberLessThan;
|
||||
protocolLayerOptions.IfSequenceNumberEqualTo = options.AccessConditions.IfSequenceNumberEqual;
|
||||
if (m_customerProvidedKey.HasValue())
|
||||
{
|
||||
protocolLayerOptions.EncryptionKey = m_customerProvidedKey.Value().Key;
|
||||
|
||||
@ -442,4 +442,115 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
EXPECT_EQ(blobClient.GetProperties().Value.HttpHeaders.ContentType, headers.ContentType);
|
||||
}
|
||||
|
||||
TEST_F(PageBlobClientTest, PageBlobAccessConditions)
|
||||
{
|
||||
auto blobClient = Azure::Storage::Blobs::PageBlobClient::CreateFromConnectionString(
|
||||
StandardStorageConnectionString(), m_containerName, RandomString());
|
||||
blobClient.Create(1024);
|
||||
Blobs::UpdatePageBlobSequenceNumberOptions updateSequenceNumberOptions;
|
||||
updateSequenceNumberOptions.SequenceNumber = 100;
|
||||
blobClient.UpdateSequenceNumber(
|
||||
Blobs::Models::SequenceNumberAction::Update, updateSequenceNumberOptions);
|
||||
|
||||
enum class AccessConditionType
|
||||
{
|
||||
Eq,
|
||||
Lt,
|
||||
LtOrEq,
|
||||
};
|
||||
enum class Operation
|
||||
{
|
||||
Upload,
|
||||
UploadFromUri,
|
||||
Clear,
|
||||
};
|
||||
for (auto o : {Operation::Upload, Operation::UploadFromUri, Operation::Clear})
|
||||
{
|
||||
|
||||
for (auto willSuccess : {true, false})
|
||||
{
|
||||
for (auto t :
|
||||
{AccessConditionType::Eq, AccessConditionType::Lt, AccessConditionType::LtOrEq})
|
||||
{
|
||||
Blobs::PageBlobAccessConditions accessConditions;
|
||||
if (t == AccessConditionType::Eq)
|
||||
{
|
||||
accessConditions.IfSequenceNumberEqual
|
||||
= blobClient.GetProperties().Value.SequenceNumber.Value();
|
||||
if (!willSuccess)
|
||||
{
|
||||
accessConditions.IfSequenceNumberEqual.Value()++;
|
||||
}
|
||||
}
|
||||
else if (t == AccessConditionType::Lt)
|
||||
{
|
||||
accessConditions.IfSequenceNumberLessThan
|
||||
= blobClient.GetProperties().Value.SequenceNumber.Value();
|
||||
if (willSuccess)
|
||||
{
|
||||
accessConditions.IfSequenceNumberLessThan.Value()++;
|
||||
}
|
||||
}
|
||||
else if (t == AccessConditionType::LtOrEq)
|
||||
{
|
||||
accessConditions.IfSequenceNumberLessThanOrEqual
|
||||
= blobClient.GetProperties().Value.SequenceNumber.Value();
|
||||
if (!willSuccess)
|
||||
{
|
||||
accessConditions.IfSequenceNumberLessThanOrEqual.Value()--;
|
||||
}
|
||||
}
|
||||
|
||||
if (o == Operation::Upload)
|
||||
{
|
||||
std::vector<uint8_t> pageContent(512);
|
||||
auto pageContentStream
|
||||
= Azure::Core::IO::MemoryBodyStream(pageContent.data(), pageContent.size());
|
||||
|
||||
Blobs::UploadPagesOptions options;
|
||||
options.AccessConditions = accessConditions;
|
||||
if (willSuccess)
|
||||
{
|
||||
EXPECT_NO_THROW(blobClient.UploadPages(0, pageContentStream, options));
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_THROW(blobClient.UploadPages(0, pageContentStream, options), StorageException);
|
||||
}
|
||||
}
|
||||
else if (o == Operation::UploadFromUri)
|
||||
{
|
||||
Blobs::UploadPagesFromUriOptions options;
|
||||
options.AccessConditions = accessConditions;
|
||||
if (willSuccess)
|
||||
{
|
||||
EXPECT_NO_THROW(blobClient.UploadPagesFromUri(
|
||||
512, blobClient.GetUrl() + GetSas(), {0, 512}, options));
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_THROW(
|
||||
blobClient.UploadPagesFromUri(
|
||||
512, blobClient.GetUrl() + GetSas(), {0, 512}, options),
|
||||
StorageException);
|
||||
}
|
||||
}
|
||||
else if (o == Operation::Clear)
|
||||
{
|
||||
Blobs::ClearPagesOptions options;
|
||||
options.AccessConditions = accessConditions;
|
||||
if (willSuccess)
|
||||
{
|
||||
EXPECT_NO_THROW(blobClient.ClearPages({0, 512}, options));
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_THROW(blobClient.ClearPages({0, 512}, options), StorageException);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace Azure::Storage::Test
|
||||
|
||||
Loading…
Reference in New Issue
Block a user