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:
JinmingHu 2021-07-16 15:43:51 +08:00 committed by GitHub
parent b4037ee591
commit c4b88f933e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 127 additions and 42 deletions

View File

@ -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

View File

@ -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(

View File

@ -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;

View File

@ -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