Supported file tier and removed unwanted functions. (#1529)

* Supported file tier and removed unwanted functions.

* Resolve test issues.
This commit is contained in:
Kan Tang 2021-02-01 13:22:06 +08:00 committed by GitHub
parent e84b9eac50
commit 942bbeee38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 341 additions and 42 deletions

View File

@ -2,6 +2,11 @@
## 12.0.0-beta.7 (Unreleased)
### New Features
- Added support for `SetProperties` in share client. This API supports update share tier and adjusting share's quota.
- Added support to get share's tier status in `ListSharesSinglePage` and `GetProperties`.
### Breaking Changes
- Removed `GetDirectoryClient` and `GetFileClient` from `ShareClient`. `ShareDirectoryClient` and `ShareFileClient` now initializes with the name of the resource, not path, to indicate that no path parsing is done for the API
@ -18,6 +23,7 @@
- Removed `c_` for constants: `c_FileDefaultTimeValue`, `c_FileCopySourceTime`, `c_FileInheritPermission`, `FilePreserveSmbProperties` and `FileAllHandles`.
- `Concurrency`, `ChunkSize` and `InitialChunkSize` were moved into `DownloadShareFileToOptions::TansferOptions`.
- `Concurrency`, `ChunkSize` and `SingleUploadThreshold` were moved into `UploadShareFileFromOptions::TransferOptions`.
- Removed `SetQuota` related API, result and options. The functionality is moved into `SetProperties`.
### Other Changes and Improvements

View File

@ -39,6 +39,24 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
Storage::ContentHash ContentHash;
};
// Specifies the access tier of the share.
class ShareAccessTier {
public:
ShareAccessTier() = default;
explicit ShareAccessTier(std::string value) : m_value(std::move(value)) {}
bool operator==(const ShareAccessTier& other) const { return m_value == other.m_value; }
bool operator!=(const ShareAccessTier& other) const { return !(*this == other); }
const std::string& Get() const { return m_value; }
AZ_STORAGE_FILES_SHARES_DLLEXPORT const static ShareAccessTier TransactionOptimized;
AZ_STORAGE_FILES_SHARES_DLLEXPORT const static ShareAccessTier Hot;
AZ_STORAGE_FILES_SHARES_DLLEXPORT const static ShareAccessTier Cool;
AZ_STORAGE_FILES_SHARES_DLLEXPORT const static ShareAccessTier Premium;
private:
std::string m_value;
}; // extensible enum ShareAccessTier
// Specifies the option to copy file security descriptor from source file or to set it using the
// value which is defined by the header value of x-ms-file-permission or
// x-ms-file-permission-key.
@ -227,6 +245,9 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
Azure::Core::Nullable<Core::DateTime> NextAllowedQuotaDowngradeTime;
Azure::Core::Nullable<Core::DateTime> DeletedOn;
int32_t RemainingRetentionDays = int32_t();
Azure::Core::Nullable<ShareAccessTier> AccessTier; // The access tier of the share.
Azure::Core::Nullable<Core::DateTime> AccessTierChangeTime;
Azure::Core::Nullable<std::string> AccessTierTransitionState;
LeaseStatusType LeaseStatus;
LeaseStateType LeaseState;
LeaseDurationType LeaseDuration;
@ -467,6 +488,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
constexpr static const char* QueryRestype = "restype";
constexpr static const char* QueryComp = "comp";
constexpr static const char* HeaderVersion = "x-ms-version";
constexpr static const char* HeaderAccessTier = "x-ms-access-tier";
constexpr static const char* HeaderContentLength = "content-length";
constexpr static const char* HeaderContentHashMd5 = "content-md5";
constexpr static const char* HeaderCopyActionAbortConstant = "x-ms-copy-action";
@ -519,6 +541,9 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
constexpr static const char* HeaderLeaseDuration = "x-ms-lease-duration";
constexpr static const char* HeaderLeaseState = "x-ms-lease-state";
constexpr static const char* HeaderLeaseStatus = "x-ms-lease-status";
constexpr static const char* HeaderAccessTierChangeTime = "x-ms-access-tier-change-time";
constexpr static const char* HeaderAccessTierTransitionState
= "x-ms-access-tier-transition-state";
constexpr static const char* HeaderLeaseTime = "x-ms-lease-time";
constexpr static const char* HeaderClientRequestId = "x-ms-client-request-id";
constexpr static const char* HeaderAction = "x-ms-lease-action";
@ -634,6 +659,9 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
Azure::Core::Nullable<LeaseDurationType> LeaseDuration;
Azure::Core::Nullable<LeaseStateType> LeaseState;
Azure::Core::Nullable<LeaseStatusType> LeaseStatus;
Azure::Core::Nullable<ShareAccessTier> AccessTier;
Azure::Core::Nullable<Core::DateTime> AccessTierChangeTime;
Azure::Core::Nullable<std::string> AccessTierTransitionState;
};
struct ShareDeleteResult
@ -705,7 +733,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
std::string RequestId;
};
struct ShareSetQuotaResult
struct ShareSetPropertiesResult
{
Core::ETag ETag;
Core::DateTime LastModified;
@ -2081,6 +2109,9 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
auto result = ShareProperties();
enum class XmlTagName
{
AccessTier,
AccessTierChangeTime,
AccessTierTransitionState,
DeletedTime,
Etag,
LastModified,
@ -2118,7 +2149,19 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
else if (node.Type == Storage::Details::XmlNodeType::StartTag)
{
if (std::strcmp(node.Name, "DeletedTime") == 0)
if (std::strcmp(node.Name, "AccessTier") == 0)
{
path.emplace_back(XmlTagName::AccessTier);
}
else if (std::strcmp(node.Name, "AccessTierChangeTime") == 0)
{
path.emplace_back(XmlTagName::AccessTierChangeTime);
}
else if (std::strcmp(node.Name, "AccessTierTransitionState") == 0)
{
path.emplace_back(XmlTagName::AccessTierTransitionState);
}
else if (std::strcmp(node.Name, "DeletedTime") == 0)
{
path.emplace_back(XmlTagName::DeletedTime);
}
@ -2189,7 +2232,20 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
}
else if (node.Type == Storage::Details::XmlNodeType::Text)
{
if (path.size() == 1 && path[0] == XmlTagName::DeletedTime)
if (path.size() == 1 && path[0] == XmlTagName::AccessTier)
{
result.AccessTier = ShareAccessTier(node.Value);
}
else if (path.size() == 1 && path[0] == XmlTagName::AccessTierChangeTime)
{
result.AccessTierChangeTime
= Core::DateTime::Parse(node.Value, Core::DateTime::DateFormat::Rfc1123);
}
else if (path.size() == 1 && path[0] == XmlTagName::AccessTierTransitionState)
{
result.AccessTierTransitionState = node.Value;
}
else if (path.size() == 1 && path[0] == XmlTagName::DeletedTime)
{
result.DeletedOn
= Core::DateTime::Parse(node.Value, Core::DateTime::DateFormat::Rfc1123);
@ -2490,6 +2546,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
Azure::Core::Nullable<int32_t> Timeout;
Storage::Metadata Metadata;
Azure::Core::Nullable<int64_t> ShareQuota;
Azure::Core::Nullable<ShareAccessTier> XMsAccessTier;
std::string ApiVersionParameter = Details::DefaultServiceApiVersion;
};
@ -2518,6 +2575,11 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
request.AddHeader(
Details::HeaderQuota, std::to_string(createOptions.ShareQuota.GetValue()));
}
if (createOptions.XMsAccessTier.HasValue())
{
request.AddHeader(
Details::HeaderAccessTier, (createOptions.XMsAccessTier.GetValue().Get()));
}
request.AddHeader(Details::HeaderVersion, createOptions.ApiVersionParameter);
return CreateParseResult(context, pipeline.Send(context, request));
}
@ -2918,42 +2980,49 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
return GetPermissionParseResult(context, pipeline.Send(context, request));
}
struct SetQuotaOptions
struct SetPropertiesOptions
{
Azure::Core::Nullable<int32_t> Timeout;
std::string ApiVersionParameter = Details::DefaultServiceApiVersion;
Azure::Core::Nullable<int64_t> ShareQuota;
Azure::Core::Nullable<ShareAccessTier> XMsAccessTier;
Azure::Core::Nullable<std::string> LeaseIdOptional;
};
static Azure::Core::Response<ShareSetQuotaResult> SetQuota(
static Azure::Core::Response<ShareSetPropertiesResult> SetProperties(
const Azure::Core::Http::Url& url,
Azure::Core::Http::HttpPipeline& pipeline,
Azure::Core::Context context,
const SetQuotaOptions& setQuotaOptions)
const SetPropertiesOptions& setPropertiesOptions)
{
Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Put, url);
request.AddHeader(Details::HeaderContentLength, "0");
request.GetUrl().AppendQueryParameter(Details::QueryRestype, "share");
request.GetUrl().AppendQueryParameter(Details::QueryComp, "properties");
if (setQuotaOptions.Timeout.HasValue())
if (setPropertiesOptions.Timeout.HasValue())
{
request.GetUrl().AppendQueryParameter(
Details::QueryTimeout,
Storage::Details::UrlEncodeQueryParameter(
std::to_string(setQuotaOptions.Timeout.GetValue())));
std::to_string(setPropertiesOptions.Timeout.GetValue())));
}
request.AddHeader(Details::HeaderVersion, setQuotaOptions.ApiVersionParameter);
if (setQuotaOptions.ShareQuota.HasValue())
request.AddHeader(Details::HeaderVersion, setPropertiesOptions.ApiVersionParameter);
if (setPropertiesOptions.ShareQuota.HasValue())
{
request.AddHeader(
Details::HeaderQuota, std::to_string(setQuotaOptions.ShareQuota.GetValue()));
Details::HeaderQuota, std::to_string(setPropertiesOptions.ShareQuota.GetValue()));
}
if (setQuotaOptions.LeaseIdOptional.HasValue())
if (setPropertiesOptions.XMsAccessTier.HasValue())
{
request.AddHeader(Details::HeaderLeaseId, setQuotaOptions.LeaseIdOptional.GetValue());
request.AddHeader(
Details::HeaderAccessTier, (setPropertiesOptions.XMsAccessTier.GetValue().Get()));
}
return SetQuotaParseResult(context, pipeline.Send(context, request));
if (setPropertiesOptions.LeaseIdOptional.HasValue())
{
request.AddHeader(
Details::HeaderLeaseId, setPropertiesOptions.LeaseIdOptional.GetValue());
}
return SetPropertiesParseResult(context, pipeline.Send(context, request));
}
struct SetMetadataOptions
@ -3232,6 +3301,23 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
result.LeaseStatus
= LeaseStatusType(response.GetHeaders().at(Details::HeaderLeaseStatus));
}
if (response.GetHeaders().find("x-ms-access-tier") != response.GetHeaders().end())
{
result.AccessTier = ShareAccessTier(response.GetHeaders().at("x-ms-access-tier"));
}
if (response.GetHeaders().find(Details::HeaderAccessTierChangeTime)
!= response.GetHeaders().end())
{
result.AccessTierChangeTime = Core::DateTime::Parse(
response.GetHeaders().at(Details::HeaderAccessTierChangeTime),
Core::DateTime::DateFormat::Rfc1123);
}
if (response.GetHeaders().find(Details::HeaderAccessTierTransitionState)
!= response.GetHeaders().end())
{
result.AccessTierTransitionState
= response.GetHeaders().at(Details::HeaderAccessTierTransitionState);
}
return Azure::Core::Response<ShareGetPropertiesResult>(
std::move(result), std::move(responsePtr));
}
@ -3502,7 +3588,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
return result;
}
static Azure::Core::Response<ShareSetQuotaResult> SetQuotaParseResult(
static Azure::Core::Response<ShareSetPropertiesResult> SetPropertiesParseResult(
Azure::Core::Context context,
std::unique_ptr<Azure::Core::Http::RawResponse> responsePtr)
{
@ -3510,13 +3596,13 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
if (response.GetStatusCode() == Azure::Core::Http::HttpStatusCode::Ok)
{
// Success
ShareSetQuotaResult result;
ShareSetPropertiesResult result;
result.ETag = Core::ETag(response.GetHeaders().at(Details::HeaderETag));
result.LastModified = Core::DateTime::Parse(
response.GetHeaders().at(Details::HeaderLastModified),
Core::DateTime::DateFormat::Rfc1123);
result.RequestId = response.GetHeaders().at(Details::HeaderRequestId);
return Azure::Core::Response<ShareSetQuotaResult>(
return Azure::Core::Response<ShareSetPropertiesResult>(
std::move(result), std::move(responsePtr));
}
else

View File

@ -126,6 +126,15 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
Azure::Core::Response<Models::CreateShareSnapshotResult> CreateSnapshot(
const CreateShareSnapshotOptions& options = CreateShareSnapshotOptions()) const;
/**
* @brief Sets the properties of the share.
* @param options Optional parameters to set the share properties.
* @return Azure::Core::Response<Models::SetSharePropertiesResult> containing the information
* including the version and modified time of a share.
*/
Azure::Core::Response<Models::SetSharePropertiesResult> SetProperties(
const SetSharePropertiesOptions& options = SetSharePropertiesOptions()) const;
/**
* @brief Gets the properties of the share.
* @param options Optional parameters to get the share properties.
@ -135,17 +144,6 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
Azure::Core::Response<Models::GetSharePropertiesResult> GetProperties(
const GetSharePropertiesOptions& options = GetSharePropertiesOptions()) const;
/**
* @brief Sets the quota of the share.
* @param quota Specifies the maximum size of the share, in gigabytes.
* @param options Optional parameters to set the share quota.
* @return Azure::Core::Response<Models::SetShareQuotaResult> containing the information
* including the version and modified time of a share.
*/
Azure::Core::Response<Models::SetShareQuotaResult> SetQuota(
int32_t quotaInGiB,
const SetShareQuotaOptions& options = SetShareQuotaOptions()) const;
/**
* @brief Sets the metadata to the share.
* @param metadata A name-value pair to associate with a file storage 'Share' object..

View File

@ -107,6 +107,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
*/
Storage::Metadata Metadata;
/**
* @brief Specifies the access tier of the share. This is only valid for standard file account
* and the value can only be one of `Hot`, `Cool` or `TransactionOptimized`
*/
Azure::Core::Nullable<Models::ShareAccessTier> AccessTier;
/**
* @brief Specifies the maximum size of the share, in gigabytes.
*/
@ -147,12 +153,23 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
Azure::Core::Context Context;
};
struct SetShareQuotaOptions
struct SetSharePropertiesOptions
{
/**
* @brief Context for cancelling long running operations.
*/
Azure::Core::Context Context;
/**
* @brief Specifies the access tier of the share. This is only valid for standard file account
* and the value can only be one of `Hot`, `Cool` or `TransactionOptimized`
*/
Azure::Core::Nullable<Models::ShareAccessTier> AccessTier;
/**
* @brief Specifies the maximum size of the share, in gigabytes.
*/
Azure::Core::Nullable<int64_t> ShareQuotaInGiB;
};
struct SetShareMetadataOptions

View File

@ -31,7 +31,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { names
};
using CreateShareSnapshotResult = Details::ShareCreateSnapshotResult;
using GetSharePropertiesResult = Details::ShareGetPropertiesResult;
using SetShareQuotaResult = Details::ShareSetQuotaResult;
using SetSharePropertiesResult = Details::ShareSetPropertiesResult;
using SetShareMetadataResult = Details::ShareSetMetadataResult;
using SetShareAccessPolicyResult = Details::ShareSetAccessPolicyResult;
using GetShareStatisticsResult = Details::ShareGetStatisticsResult;

View File

@ -115,6 +115,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
auto protocolLayerOptions = Details::ShareRestClient::Share::CreateOptions();
protocolLayerOptions.Metadata = options.Metadata;
protocolLayerOptions.ShareQuota = options.ShareQuotaInGiB;
protocolLayerOptions.XMsAccessTier = options.AccessTier;
auto result = Details::ShareRestClient::Share::Create(
m_shareUrl, *m_pipeline, options.Context, protocolLayerOptions);
Models::CreateShareResult ret;
@ -202,13 +203,13 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares {
m_shareUrl, *m_pipeline, options.Context, protocolLayerOptions);
}
Azure::Core::Response<Models::SetShareQuotaResult> ShareClient::SetQuota(
int32_t quotaInGiB,
const SetShareQuotaOptions& options) const
Azure::Core::Response<Models::SetSharePropertiesResult> ShareClient::SetProperties(
const SetSharePropertiesOptions& options) const
{
auto protocolLayerOptions = Details::ShareRestClient::Share::SetQuotaOptions();
protocolLayerOptions.ShareQuota = quotaInGiB;
return Details::ShareRestClient::Share::SetQuota(
auto protocolLayerOptions = Details::ShareRestClient::Share::SetPropertiesOptions();
protocolLayerOptions.ShareQuota = options.ShareQuotaInGiB;
protocolLayerOptions.XMsAccessTier = options.AccessTier;
return Details::ShareRestClient::Share::SetProperties(
m_shareUrl, *m_pipeline, options.Context, protocolLayerOptions);
}

View File

@ -5,6 +5,11 @@
#include "azure/storage/files/shares/protocol/share_rest_client.hpp"
namespace Azure { namespace Storage { namespace Files { namespace Shares { namespace Models {
const ShareAccessTier ShareAccessTier::TransactionOptimized("TransactionOptimized");
const ShareAccessTier ShareAccessTier::Hot("Hot");
const ShareAccessTier ShareAccessTier::Cool("Cool");
const ShareAccessTier ShareAccessTier::Premium("Premium");
const PermissionCopyModeType PermissionCopyModeType::Source("source");
const PermissionCopyModeType PermissionCopyModeType::Override("override");

View File

@ -145,7 +145,7 @@ namespace Azure { namespace Storage { namespace Test {
}
}
TEST_F(FileShareClientTest, ShareQuota)
TEST_F(FileShareClientTest, ShareProperties)
{
const int32_t quota32GB = 32;
const int32_t quota64GB = 64;
@ -153,16 +153,19 @@ namespace Azure { namespace Storage { namespace Test {
{
// Set quota /Get properties works
EXPECT_NO_THROW(m_shareClient->SetQuota(quota32GB));
Files::Shares::SetSharePropertiesOptions options;
options.ShareQuotaInGiB = quota32GB;
EXPECT_NO_THROW(m_shareClient->SetProperties(options));
auto result = m_shareClient->GetProperties();
EXPECT_EQ(quota32GB, result->Quota);
EXPECT_NO_THROW(m_shareClient->SetQuota(quota64GB));
options.ShareQuotaInGiB = quota64GB;
EXPECT_NO_THROW(m_shareClient->SetProperties(options));
result = m_shareClient->GetProperties();
EXPECT_EQ(quota64GB, result->Quota);
}
{
// Create file system with quota works
// Create share with quota works
auto client1 = Files::Shares::ShareClient::CreateFromConnectionString(
AdlsGen2ConnectionString(), LowercaseRandomString());
auto client2 = Files::Shares::ShareClient::CreateFromConnectionString(
@ -182,7 +185,9 @@ namespace Azure { namespace Storage { namespace Test {
{
// Limit/negative cases:
EXPECT_NO_THROW(m_shareClient->SetQuota(quota5120GB));
Files::Shares::SetSharePropertiesOptions options;
options.ShareQuotaInGiB = quota5120GB;
EXPECT_NO_THROW(m_shareClient->SetProperties(options));
auto result = m_shareClient->GetProperties()->Quota;
EXPECT_EQ(quota5120GB, result);
}
@ -361,4 +366,146 @@ namespace Azure { namespace Storage { namespace Test {
EXPECT_EQ(fileUrl, m_shareClient->GetUrl() + "/" + Storage::Details::UrlEncodePath(fileName));
}
}
TEST_F(FileShareClientTest, ShareTierRelated)
{
// Create/Get properties works
std::unordered_map<std::string, Files::Shares::ShareClient> shareClients;
std::string prefix = LowercaseRandomString(5);
Files::Shares::Models::GetSharePropertiesResult properties;
{
auto shareName = prefix + LowercaseRandomString(5);
auto shareClient = Files::Shares::ShareClient::CreateFromConnectionString(
StandardStorageConnectionString(), shareName);
auto options = Files::Shares::CreateShareOptions();
options.AccessTier = Files::Shares::Models::ShareAccessTier::TransactionOptimized;
EXPECT_NO_THROW(shareClient.Create(options));
EXPECT_NO_THROW(properties = *shareClient.GetProperties());
EXPECT_EQ(
Files::Shares::Models::ShareAccessTier::TransactionOptimized,
properties.AccessTier.GetValue());
EXPECT_FALSE(properties.AccessTierTransitionState.HasValue());
EXPECT_EQ(properties.LastModified, properties.AccessTierChangeTime.GetValue());
shareClients.emplace(std::move(shareName), std::move(shareClient));
}
{
auto shareName = prefix + LowercaseRandomString(5);
auto shareClient = Files::Shares::ShareClient::CreateFromConnectionString(
StandardStorageConnectionString(), shareName);
auto options = Files::Shares::CreateShareOptions();
options.AccessTier = Files::Shares::Models::ShareAccessTier::Hot;
EXPECT_NO_THROW(shareClient.Create(options));
EXPECT_NO_THROW(properties = *shareClient.GetProperties());
EXPECT_EQ(Files::Shares::Models::ShareAccessTier::Hot, properties.AccessTier.GetValue());
EXPECT_FALSE(properties.AccessTierTransitionState.HasValue());
EXPECT_EQ(properties.LastModified, properties.AccessTierChangeTime.GetValue());
shareClients.emplace(std::move(shareName), std::move(shareClient));
}
{
auto shareName = prefix + LowercaseRandomString(5);
auto shareClient = Files::Shares::ShareClient::CreateFromConnectionString(
StandardStorageConnectionString(), shareName);
auto options = Files::Shares::CreateShareOptions();
options.AccessTier = Files::Shares::Models::ShareAccessTier::Cool;
EXPECT_NO_THROW(shareClient.Create(options));
EXPECT_NO_THROW(properties = *shareClient.GetProperties());
EXPECT_EQ(Files::Shares::Models::ShareAccessTier::Cool, properties.AccessTier.GetValue());
EXPECT_FALSE(properties.AccessTierTransitionState.HasValue());
EXPECT_EQ(properties.LastModified, properties.AccessTierChangeTime.GetValue());
shareClients.emplace(std::move(shareName), std::move(shareClient));
}
// Set properties works
{
auto shareClient = Files::Shares::ShareClient::CreateFromConnectionString(
StandardStorageConnectionString(), LowercaseRandomString(10));
auto options = Files::Shares::CreateShareOptions();
options.AccessTier = Files::Shares::Models::ShareAccessTier::Cool;
EXPECT_NO_THROW(shareClient.Create(options));
EXPECT_EQ(
Files::Shares::Models::ShareAccessTier::Cool,
shareClient.GetProperties()->AccessTier.GetValue());
auto setPropertiesOptions = Files::Shares::SetSharePropertiesOptions();
setPropertiesOptions.AccessTier = Files::Shares::Models::ShareAccessTier::Hot;
EXPECT_NO_THROW(shareClient.SetProperties(setPropertiesOptions));
properties = *shareClient.GetProperties();
if (properties.AccessTierTransitionState.HasValue())
{
EXPECT_EQ(Files::Shares::Models::ShareAccessTier::Cool, properties.AccessTier.GetValue());
}
else
{
EXPECT_EQ(Files::Shares::Models::ShareAccessTier::Hot, properties.AccessTier.GetValue());
}
EXPECT_EQ(properties.LastModified, properties.AccessTierChangeTime.GetValue());
}
// List shares works.
Files::Shares::ListSharesSinglePageOptions listOptions;
listOptions.Prefix = prefix;
auto shareItems = Files::Shares::ShareServiceClient::CreateFromConnectionString(
StandardStorageConnectionString())
.ListSharesSinglePage(listOptions)
->Items;
EXPECT_EQ(3U, shareItems.size());
for (const auto& shareItem : shareItems)
{
EXPECT_TRUE(shareClients.find(shareItem.Name) != shareClients.end());
properties = *shareClients.at(shareItem.Name).GetProperties();
EXPECT_EQ(
true, shareItem.Properties.AccessTier.HasValue() && properties.AccessTier.HasValue());
EXPECT_EQ(shareItem.Properties.AccessTier.GetValue(), properties.AccessTier.GetValue());
EXPECT_EQ(
true,
shareItem.Properties.AccessTierChangeTime.HasValue()
&& properties.AccessTierChangeTime.HasValue());
EXPECT_EQ(
shareItem.Properties.AccessTierChangeTime.GetValue(),
properties.AccessTierChangeTime.GetValue());
EXPECT_EQ(
false,
shareItem.Properties.AccessTierTransitionState.HasValue()
|| properties.AccessTierTransitionState.HasValue());
}
}
TEST_F(FileShareClientTest, PremiumShare)
{
auto shareName = LowercaseRandomString(10);
auto shareClient = Files::Shares::ShareClient::CreateFromConnectionString(
PremiumFileConnectionString(), shareName);
EXPECT_NO_THROW(shareClient.Create());
Files::Shares::Models::GetSharePropertiesResult properties;
EXPECT_NO_THROW(properties = *shareClient.GetProperties());
EXPECT_EQ(Files::Shares::Models::ShareAccessTier::Premium, properties.AccessTier.GetValue());
EXPECT_FALSE(properties.AccessTierTransitionState.HasValue());
EXPECT_FALSE(properties.AccessTierChangeTime.HasValue());
Files::Shares::ListSharesSinglePageOptions listOptions;
listOptions.Prefix = shareName;
auto shareItems = Files::Shares::ShareServiceClient::CreateFromConnectionString(
PremiumFileConnectionString())
.ListSharesSinglePage(listOptions)
->Items;
EXPECT_EQ(1U, shareItems.size());
EXPECT_EQ(
Files::Shares::Models::ShareAccessTier::Premium,
shareItems[0].Properties.AccessTier.GetValue());
EXPECT_FALSE(shareItems[0].Properties.AccessTierTransitionState.HasValue());
EXPECT_FALSE(shareItems[0].Properties.AccessTierChangeTime.HasValue());
auto setPropertiesOptions = Files::Shares::SetSharePropertiesOptions();
setPropertiesOptions.AccessTier = Files::Shares::Models::ShareAccessTier::Hot;
EXPECT_THROW(shareClient.SetProperties(setPropertiesOptions), StorageException);
setPropertiesOptions.AccessTier = Files::Shares::Models::ShareAccessTier::Cool;
EXPECT_THROW(shareClient.SetProperties(setPropertiesOptions), StorageException);
setPropertiesOptions.AccessTier = Files::Shares::Models::ShareAccessTier::TransactionOptimized;
EXPECT_THROW(shareClient.SetProperties(setPropertiesOptions), StorageException);
setPropertiesOptions.AccessTier = Files::Shares::Models::ShareAccessTier::Premium;
EXPECT_NO_THROW(shareClient.SetProperties(setPropertiesOptions));
EXPECT_EQ(Files::Shares::Models::ShareAccessTier::Premium, properties.AccessTier.GetValue());
EXPECT_FALSE(properties.AccessTierTransitionState.HasValue());
EXPECT_FALSE(properties.AccessTierChangeTime.HasValue());
}
}}} // namespace Azure::Storage::Test

View File

@ -62,7 +62,8 @@
},
"authorizationApiVersion": "2018-01-01-preview",
"blobDataContributorRoleId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe')]",
"blobDataOwnerRoleId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/b7e6dc6d-f1e8-4753-8033-0f276bb0955b')]"
"blobDataOwnerRoleId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/b7e6dc6d-f1e8-4753-8033-0f276bb0955b')]",
"premiumFileAccountName": "[concat(parameters('baseName'), 'pfile')]"
},
"resources": [
{
@ -254,6 +255,40 @@
},
"accessTier": "Hot"
}
},
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "[variables('storageApiVersion')]",
"name": "[variables('premiumFileAccountName')]",
"location": "[variables('location')]",
"sku": {
"name": "Premium_LRS",
"tier": "Premium"
},
"kind": "FileStorage",
"properties": {
"networkAcls": {
"bypass": "AzureServices",
"virtualNetworkRules": [
],
"ipRules": [
],
"defaultAction": "Allow"
},
"supportsHttpsTrafficOnly": true,
"encryption": {
"services": {
"file": {
"enabled": true
},
"blob": {
"enabled": true
}
},
"keySource": "Microsoft.Storage"
},
"accessTier": "Hot"
}
}
],
"outputs": {
@ -281,6 +316,10 @@
"type": "string",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('dataLakeAccountName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('dataLakeAccountName')), variables('storageApiVersion')).keys[0].value, ';EndpointSuffix=', parameters('storageEndpointSuffix'))]"
},
"PREMIUM_FILE_CONNECTION_STRING": {
"type": "string",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('premiumFileAccountName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('premiumFileAccountName')), variables('storageApiVersion')).keys[0].value, ';EndpointSuffix=', parameters('storageEndpointSuffix'))]"
},
"AAD_TENANT_ID": {
"type": "string",
"value": "[parameters('tenantId')]"