parent
9067d8ac5d
commit
1dce74c642
@ -148,6 +148,19 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
Azure::Core::Response<DeleteContainerResult> Delete(
|
||||
const DeleteContainerOptions& options = DeleteContainerOptions()) const;
|
||||
|
||||
/**
|
||||
* @brief Restores a previously deleted container.
|
||||
*
|
||||
* @param deletedContainerName The name of the previously deleted container.
|
||||
* @param deletedContainerVersion The version of the previously deleted container.
|
||||
* @param options Optional parameters to execute this function.
|
||||
* @return An UndeleteContainerResult if successful.
|
||||
*/
|
||||
Azure::Core::Response<UndeleteContainerResult> UndeleteContainer(
|
||||
const std::string& deletedContainerName,
|
||||
const std::string& deletedContainerVersion,
|
||||
const UndeleteContainerOptions& options = UndeleteContainerOptions()) const;
|
||||
|
||||
/**
|
||||
* @brief Returns all user-defined metadata and system properties for the specified
|
||||
* container. The data returned does not include the container's list of blobs.
|
||||
|
||||
@ -123,7 +123,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
/**
|
||||
* @brief Specifies that the container's metadata be returned.
|
||||
*/
|
||||
ListBlobContainersIncludeOption Include = ListBlobContainersIncludeOption::None;
|
||||
ListBlobContainersIncludeItem Include = ListBlobContainersIncludeItem::None;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -280,6 +280,17 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
ContainerAccessConditions AccessConditions;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Optional parameters for BlobContainerClient::Undelete.
|
||||
*/
|
||||
struct UndeleteContainerOptions
|
||||
{
|
||||
/**
|
||||
* @brief Context for cancelling long running operations.
|
||||
*/
|
||||
Azure::Core::Context Context;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Optional parameters for BlobContainerClient::GetProperties.
|
||||
*/
|
||||
|
||||
@ -864,57 +864,59 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
std::string Value;
|
||||
}; // struct GetUserDelegationKeyResult
|
||||
|
||||
enum class ListBlobContainersIncludeOption
|
||||
enum class ListBlobContainersIncludeItem
|
||||
{
|
||||
None = 0,
|
||||
Metadata = 1,
|
||||
}; // bitwise enum ListBlobContainersIncludeOption
|
||||
Deleted = 2,
|
||||
}; // bitwise enum ListBlobContainersIncludeItem
|
||||
|
||||
inline ListBlobContainersIncludeOption operator|(
|
||||
ListBlobContainersIncludeOption lhs,
|
||||
ListBlobContainersIncludeOption rhs)
|
||||
inline ListBlobContainersIncludeItem operator|(
|
||||
ListBlobContainersIncludeItem lhs,
|
||||
ListBlobContainersIncludeItem rhs)
|
||||
{
|
||||
using type = std::underlying_type_t<ListBlobContainersIncludeOption>;
|
||||
return static_cast<ListBlobContainersIncludeOption>(
|
||||
using type = std::underlying_type_t<ListBlobContainersIncludeItem>;
|
||||
return static_cast<ListBlobContainersIncludeItem>(
|
||||
static_cast<type>(lhs) | static_cast<type>(rhs));
|
||||
}
|
||||
|
||||
inline ListBlobContainersIncludeOption& operator|=(
|
||||
ListBlobContainersIncludeOption& lhs,
|
||||
ListBlobContainersIncludeOption rhs)
|
||||
inline ListBlobContainersIncludeItem& operator|=(
|
||||
ListBlobContainersIncludeItem& lhs,
|
||||
ListBlobContainersIncludeItem rhs)
|
||||
{
|
||||
lhs = lhs | rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline ListBlobContainersIncludeOption operator&(
|
||||
ListBlobContainersIncludeOption lhs,
|
||||
ListBlobContainersIncludeOption rhs)
|
||||
inline ListBlobContainersIncludeItem operator&(
|
||||
ListBlobContainersIncludeItem lhs,
|
||||
ListBlobContainersIncludeItem rhs)
|
||||
{
|
||||
using type = std::underlying_type_t<ListBlobContainersIncludeOption>;
|
||||
return static_cast<ListBlobContainersIncludeOption>(
|
||||
using type = std::underlying_type_t<ListBlobContainersIncludeItem>;
|
||||
return static_cast<ListBlobContainersIncludeItem>(
|
||||
static_cast<type>(lhs) & static_cast<type>(rhs));
|
||||
}
|
||||
|
||||
inline ListBlobContainersIncludeOption& operator&=(
|
||||
ListBlobContainersIncludeOption& lhs,
|
||||
ListBlobContainersIncludeOption rhs)
|
||||
inline ListBlobContainersIncludeItem& operator&=(
|
||||
ListBlobContainersIncludeItem& lhs,
|
||||
ListBlobContainersIncludeItem rhs)
|
||||
{
|
||||
lhs = lhs & rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline std::string ListBlobContainersIncludeOptionToString(
|
||||
const ListBlobContainersIncludeOption& val)
|
||||
inline std::string ListBlobContainersIncludeItemToString(const ListBlobContainersIncludeItem& val)
|
||||
{
|
||||
ListBlobContainersIncludeOption value_list[] = {
|
||||
ListBlobContainersIncludeOption::Metadata,
|
||||
ListBlobContainersIncludeItem value_list[] = {
|
||||
ListBlobContainersIncludeItem::Metadata,
|
||||
ListBlobContainersIncludeItem::Deleted,
|
||||
};
|
||||
const char* string_list[] = {
|
||||
"metadata",
|
||||
"deleted",
|
||||
};
|
||||
std::string ret;
|
||||
for (std::size_t i = 0; i < sizeof(value_list) / sizeof(ListBlobContainersIncludeOption); ++i)
|
||||
for (std::size_t i = 0; i < sizeof(value_list) / sizeof(ListBlobContainersIncludeItem); ++i)
|
||||
{
|
||||
if ((val & value_list[i]) == value_list[i])
|
||||
{
|
||||
@ -1245,6 +1247,10 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
{
|
||||
}; // struct UndeleteBlobResult
|
||||
|
||||
struct UndeleteContainerResult
|
||||
{
|
||||
}; // struct UndeleteContainerResult
|
||||
|
||||
struct UploadBlockBlobResult
|
||||
{
|
||||
std::string ETag;
|
||||
@ -1303,6 +1309,12 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
Azure::Core::Nullable<std::string> LeaseDuration;
|
||||
BlobLeaseState LeaseState = BlobLeaseState::Available;
|
||||
BlobLeaseStatus LeaseStatus = BlobLeaseStatus::Unlocked;
|
||||
std::string DefaultEncryptionScope;
|
||||
bool PreventEncryptionScopeOverride = false;
|
||||
bool IsDeleted = false;
|
||||
Azure::Core::Nullable<std::string> VersionId;
|
||||
Azure::Core::Nullable<std::string> DeletedOn;
|
||||
Azure::Core::Nullable<int32_t> RemainingRetentionDays;
|
||||
}; // struct BlobContainerItem
|
||||
|
||||
struct BlobGeoReplication
|
||||
@ -1427,6 +1439,8 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
Azure::Core::Nullable<std::string> LeaseDuration;
|
||||
BlobLeaseState LeaseState = BlobLeaseState::Available;
|
||||
BlobLeaseStatus LeaseStatus = BlobLeaseStatus::Unlocked;
|
||||
std::string DefaultEncryptionScope;
|
||||
bool PreventEncryptionScopeOverride = false;
|
||||
}; // struct GetContainerPropertiesResult
|
||||
|
||||
struct StartCopyBlobFromUriResult
|
||||
@ -1515,7 +1529,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
Azure::Core::Nullable<std::string> Prefix;
|
||||
Azure::Core::Nullable<std::string> Marker;
|
||||
Azure::Core::Nullable<int32_t> MaxResults;
|
||||
ListBlobContainersIncludeOption IncludeMetadata = ListBlobContainersIncludeOption::None;
|
||||
ListBlobContainersIncludeItem Include = ListBlobContainersIncludeItem::None;
|
||||
}; // struct ListContainersSegmentOptions
|
||||
|
||||
static Azure::Core::Response<ListContainersSegmentResult> ListBlobContainers(
|
||||
@ -1544,11 +1558,11 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
{
|
||||
request.AddQueryParameter("maxresults", std::to_string(options.MaxResults.GetValue()));
|
||||
}
|
||||
std::string list_blob_containers_include_option
|
||||
= ListBlobContainersIncludeOptionToString(options.IncludeMetadata);
|
||||
if (!list_blob_containers_include_option.empty())
|
||||
std::string list_blob_containers_include_item
|
||||
= ListBlobContainersIncludeItemToString(options.Include);
|
||||
if (!list_blob_containers_include_item.empty())
|
||||
{
|
||||
request.AddQueryParameter("include", list_blob_containers_include_option);
|
||||
request.AddQueryParameter("include", list_blob_containers_include_item);
|
||||
}
|
||||
auto pHttpResponse = pipeline.Send(context, request);
|
||||
Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse;
|
||||
@ -2297,7 +2311,13 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
k_LeaseStatus,
|
||||
k_LeaseState,
|
||||
k_LeaseDuration,
|
||||
k_DefaultEncryptionScope,
|
||||
k_DenyEncryptionScopeOverride,
|
||||
k_Metadata,
|
||||
k_Deleted,
|
||||
k_Version,
|
||||
k_DeletedTime,
|
||||
k_RemainingRetentionDays,
|
||||
k_Unknown,
|
||||
};
|
||||
std::vector<XmlTagName> path;
|
||||
@ -2361,10 +2381,34 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
{
|
||||
path.emplace_back(XmlTagName::k_LeaseDuration);
|
||||
}
|
||||
else if (std::strcmp(node.Name, "DefaultEncryptionScope") == 0)
|
||||
{
|
||||
path.emplace_back(XmlTagName::k_DefaultEncryptionScope);
|
||||
}
|
||||
else if (std::strcmp(node.Name, "DenyEncryptionScopeOverride") == 0)
|
||||
{
|
||||
path.emplace_back(XmlTagName::k_DenyEncryptionScopeOverride);
|
||||
}
|
||||
else if (std::strcmp(node.Name, "Metadata") == 0)
|
||||
{
|
||||
path.emplace_back(XmlTagName::k_Metadata);
|
||||
}
|
||||
else if (std::strcmp(node.Name, "Deleted") == 0)
|
||||
{
|
||||
path.emplace_back(XmlTagName::k_Deleted);
|
||||
}
|
||||
else if (std::strcmp(node.Name, "Version") == 0)
|
||||
{
|
||||
path.emplace_back(XmlTagName::k_Version);
|
||||
}
|
||||
else if (std::strcmp(node.Name, "DeletedTime") == 0)
|
||||
{
|
||||
path.emplace_back(XmlTagName::k_DeletedTime);
|
||||
}
|
||||
else if (std::strcmp(node.Name, "RemainingRetentionDays") == 0)
|
||||
{
|
||||
path.emplace_back(XmlTagName::k_RemainingRetentionDays);
|
||||
}
|
||||
else
|
||||
{
|
||||
path.emplace_back(XmlTagName::k_Unknown);
|
||||
@ -2429,6 +2473,38 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
{
|
||||
ret.LeaseDuration = node.Value;
|
||||
}
|
||||
else if (
|
||||
path.size() == 2 && path[0] == XmlTagName::k_Properties
|
||||
&& path[1] == XmlTagName::k_DefaultEncryptionScope)
|
||||
{
|
||||
ret.DefaultEncryptionScope = node.Value;
|
||||
}
|
||||
else if (
|
||||
path.size() == 2 && path[0] == XmlTagName::k_Properties
|
||||
&& path[1] == XmlTagName::k_DenyEncryptionScopeOverride)
|
||||
{
|
||||
ret.PreventEncryptionScopeOverride = std::strcmp(node.Value, "true") == 0;
|
||||
}
|
||||
else if (path.size() == 1 && path[0] == XmlTagName::k_Deleted)
|
||||
{
|
||||
ret.IsDeleted = std::strcmp(node.Value, "true") == 0;
|
||||
}
|
||||
else if (path.size() == 1 && path[0] == XmlTagName::k_Version)
|
||||
{
|
||||
ret.VersionId = node.Value;
|
||||
}
|
||||
else if (
|
||||
path.size() == 2 && path[0] == XmlTagName::k_Properties
|
||||
&& path[1] == XmlTagName::k_DeletedTime)
|
||||
{
|
||||
ret.DeletedOn = node.Value;
|
||||
}
|
||||
else if (
|
||||
path.size() == 2 && path[0] == XmlTagName::k_Properties
|
||||
&& path[1] == XmlTagName::k_RemainingRetentionDays)
|
||||
{
|
||||
ret.RemainingRetentionDays = std::stoi(node.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -3100,6 +3176,45 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
std::move(response), std::move(pHttpResponse));
|
||||
}
|
||||
|
||||
struct UndeleteContainerOptions
|
||||
{
|
||||
Azure::Core::Nullable<int32_t> Timeout;
|
||||
std::string DeletedContainerName;
|
||||
std::string DeletedContainerVersion;
|
||||
}; // struct UndeleteContainerOptions
|
||||
|
||||
static Azure::Core::Response<UndeleteContainerResult> Undelete(
|
||||
const Azure::Core::Context& context,
|
||||
Azure::Core::Http::HttpPipeline& pipeline,
|
||||
const std::string& url,
|
||||
const UndeleteContainerOptions& options)
|
||||
{
|
||||
unused(options);
|
||||
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url);
|
||||
request.AddHeader("Content-Length", "0");
|
||||
request.AddQueryParameter("restype", "container");
|
||||
request.AddQueryParameter("comp", "undelete");
|
||||
request.AddHeader("x-ms-version", c_ApiVersion);
|
||||
if (options.Timeout.HasValue())
|
||||
{
|
||||
request.AddQueryParameter("timeout", std::to_string(options.Timeout.GetValue()));
|
||||
}
|
||||
request.AddHeader("x-ms-deleted-container-name", options.DeletedContainerName);
|
||||
request.AddHeader("x-ms-deleted-container-version", options.DeletedContainerVersion);
|
||||
auto pHttpResponse = pipeline.Send(context, request);
|
||||
Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse;
|
||||
UndeleteContainerResult response;
|
||||
auto http_status_code
|
||||
= static_cast<std::underlying_type<Azure::Core::Http::HttpStatusCode>::type>(
|
||||
httpResponse.GetStatusCode());
|
||||
if (!(http_status_code == 201))
|
||||
{
|
||||
throw StorageError::CreateFromResponse(context, std::move(pHttpResponse));
|
||||
}
|
||||
return Azure::Core::Response<UndeleteContainerResult>(
|
||||
std::move(response), std::move(pHttpResponse));
|
||||
}
|
||||
|
||||
struct GetContainerPropertiesOptions
|
||||
{
|
||||
Azure::Core::Nullable<int32_t> Timeout;
|
||||
@ -3161,6 +3276,10 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
{
|
||||
response.LeaseDuration = response_lease_duration_iterator->second;
|
||||
}
|
||||
response.DefaultEncryptionScope
|
||||
= httpResponse.GetHeaders().at("x-ms-default-encryption-scope");
|
||||
response.PreventEncryptionScopeOverride
|
||||
= httpResponse.GetHeaders().at("x-ms-deny-encryption-scope-override") == "true";
|
||||
return Azure::Core::Response<GetContainerPropertiesResult>(
|
||||
std::move(response), std::move(pHttpResponse));
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ namespace Azure { namespace Storage {
|
||||
template <class... T> void unused(T&&...) {}
|
||||
|
||||
constexpr int32_t c_InfiniteLeaseDuration = -1;
|
||||
constexpr static const char* c_AccountEncryptionKey = "$account-encryption-key";
|
||||
|
||||
std::string CreateUniqueLeaseId();
|
||||
|
||||
|
||||
@ -163,6 +163,18 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
options.Context, *m_pipeline, m_containerUrl.ToString(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
Azure::Core::Response<UndeleteContainerResult> BlobContainerClient::UndeleteContainer(
|
||||
const std::string& deletedContainerName,
|
||||
const std::string& deletedContainerVersion,
|
||||
const UndeleteContainerOptions& options) const
|
||||
{
|
||||
BlobRestClient::Container::UndeleteContainerOptions protocolLayerOptions;
|
||||
protocolLayerOptions.DeletedContainerName = deletedContainerName;
|
||||
protocolLayerOptions.DeletedContainerVersion = deletedContainerVersion;
|
||||
return BlobRestClient::Container::Undelete(
|
||||
options.Context, *m_pipeline, m_containerUrl.ToString(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
Azure::Core::Response<GetContainerPropertiesResult> BlobContainerClient::GetProperties(
|
||||
const GetContainerPropertiesOptions& options) const
|
||||
{
|
||||
|
||||
@ -127,7 +127,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
protocolLayerOptions.Prefix = options.Prefix;
|
||||
protocolLayerOptions.Marker = options.Marker;
|
||||
protocolLayerOptions.MaxResults = options.MaxResults;
|
||||
protocolLayerOptions.IncludeMetadata = options.Include;
|
||||
protocolLayerOptions.Include = options.Include;
|
||||
return BlobRestClient::Service::ListBlobContainers(
|
||||
options.Context, *m_pipeline, m_serviceUrl.ToString(), protocolLayerOptions);
|
||||
}
|
||||
|
||||
@ -5,6 +5,9 @@
|
||||
#include "blobs/blob_sas_builder.hpp"
|
||||
#include "common/crypt.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
bool operator==(
|
||||
@ -396,6 +399,11 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
|
||||
TEST_F(BlobContainerClientTest, EncryptionScope)
|
||||
{
|
||||
{
|
||||
auto properties = *m_blobContainerClient->GetProperties();
|
||||
EXPECT_EQ(properties.DefaultEncryptionScope, c_AccountEncryptionKey);
|
||||
EXPECT_EQ(properties.PreventEncryptionScopeOverride, false);
|
||||
}
|
||||
{
|
||||
std::string containerName = LowercaseRandomString();
|
||||
std::string blobName = RandomString();
|
||||
@ -407,6 +415,11 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
createOptions.DefaultEncryptionScope = c_TestEncryptionScope;
|
||||
createOptions.PreventEncryptionScopeOverride = true;
|
||||
EXPECT_NO_THROW(containerClient.Create(createOptions));
|
||||
auto properties = *containerClient.GetProperties();
|
||||
EXPECT_EQ(properties.DefaultEncryptionScope, createOptions.DefaultEncryptionScope.GetValue());
|
||||
EXPECT_EQ(
|
||||
properties.PreventEncryptionScopeOverride,
|
||||
createOptions.PreventEncryptionScopeOverride.GetValue());
|
||||
auto appendBlobClient = containerClient.GetAppendBlobClient(blobName);
|
||||
auto blobContentInfo = appendBlobClient.Create();
|
||||
EXPECT_TRUE(blobContentInfo->EncryptionScope.HasValue());
|
||||
@ -622,4 +635,67 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
EXPECT_NO_THROW(containerClient.Delete(options));
|
||||
}
|
||||
|
||||
TEST_F(BlobContainerClientTest, DISABLED_Undelete)
|
||||
{
|
||||
auto serviceClient = Azure::Storage::Blobs::BlobServiceClient::CreateFromConnectionString(
|
||||
StandardStorageConnectionString());
|
||||
std::string containerName = LowercaseRandomString();
|
||||
auto containerClient = serviceClient.GetBlobContainerClient(containerName);
|
||||
containerClient.Create();
|
||||
containerClient.Delete();
|
||||
|
||||
Blobs::BlobContainerItem deletedContainerItem;
|
||||
{
|
||||
Azure::Storage::Blobs::ListContainersSegmentOptions options;
|
||||
options.Prefix = containerName;
|
||||
options.Include = Blobs::ListBlobContainersIncludeItem::Deleted;
|
||||
do
|
||||
{
|
||||
auto res = serviceClient.ListBlobContainersSegment(options);
|
||||
options.Marker = res->NextMarker;
|
||||
for (const auto& container : res->Items)
|
||||
{
|
||||
if (container.Name == containerName)
|
||||
{
|
||||
deletedContainerItem = container;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (!options.Marker.GetValue().empty());
|
||||
}
|
||||
EXPECT_EQ(deletedContainerItem.Name, containerName);
|
||||
EXPECT_TRUE(deletedContainerItem.IsDeleted);
|
||||
EXPECT_TRUE(deletedContainerItem.VersionId.HasValue());
|
||||
EXPECT_FALSE(deletedContainerItem.VersionId.GetValue().empty());
|
||||
EXPECT_TRUE(deletedContainerItem.DeletedOn.HasValue());
|
||||
EXPECT_FALSE(deletedContainerItem.DeletedOn.GetValue().empty());
|
||||
EXPECT_TRUE(deletedContainerItem.RemainingRetentionDays.HasValue());
|
||||
EXPECT_GE(deletedContainerItem.RemainingRetentionDays.GetValue(), 0);
|
||||
|
||||
std::string containerName2 = LowercaseRandomString();
|
||||
auto containerClient2 = serviceClient.GetBlobContainerClient(containerName2);
|
||||
for (int i = 0; i < 60; ++i)
|
||||
{
|
||||
try
|
||||
{
|
||||
containerClient2.UndeleteContainer(
|
||||
deletedContainerItem.Name, deletedContainerItem.VersionId.GetValue());
|
||||
break;
|
||||
}
|
||||
catch (StorageError& e)
|
||||
{
|
||||
if (e.StatusCode == Azure::Core::Http::HttpStatusCode::Conflict
|
||||
&& e.ReasonPhrase == "The specified container is being deleted.")
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPECT_NO_THROW(containerClient2.GetProperties());
|
||||
}
|
||||
|
||||
}}} // namespace Azure::Storage::Test
|
||||
|
||||
@ -150,6 +150,12 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
EXPECT_FALSE(container.Name.empty());
|
||||
EXPECT_FALSE(container.ETag.empty());
|
||||
EXPECT_FALSE(container.LastModified.empty());
|
||||
EXPECT_FALSE(container.IsDeleted);
|
||||
EXPECT_FALSE(container.VersionId.HasValue());
|
||||
EXPECT_FALSE(container.DeletedOn.HasValue());
|
||||
EXPECT_FALSE(container.RemainingRetentionDays.HasValue());
|
||||
EXPECT_EQ(container.DefaultEncryptionScope, c_AccountEncryptionKey);
|
||||
EXPECT_FALSE(container.PreventEncryptionScopeOverride);
|
||||
listContainers.insert(container.Name);
|
||||
}
|
||||
} while (!options.Marker.GetValue().empty());
|
||||
|
||||
Loading…
Reference in New Issue
Block a user