From 88138fe6c4546874e93979f5bfa93295a4ad9aa7 Mon Sep 17 00:00:00 2001 From: Zhendong Chang Date: Fri, 9 Sep 2022 14:26:53 +0800 Subject: [PATCH 1/3] protocol layer for data lake STG82 --- .../storage/files/datalake/rest_client.hpp | 224 +++++- .../src/rest_client.cpp | 726 +++++++++++++++++- .../swagger/README.md | 28 +- 3 files changed, 961 insertions(+), 17 deletions(-) diff --git a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp index 9118b085cd..8b01692b30 100644 --- a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp +++ b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -26,7 +27,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { /** * The version used for the operations to Azure storage services. */ - constexpr static const char* ApiVersion = "2020-02-10"; + constexpr static const char* ApiVersion = "2021-06-08"; } // namespace _detail namespace Models { namespace _detail { @@ -92,6 +93,12 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { std::string Owner; std::string Group; std::string Permissions; + /** + * The name of the encryption scope under which the blob is encrypted. + */ + Nullable EncryptionScope; + std::string CreatedOn; + Nullable ExpiresOn; std::string ETag; }; namespace _detail { @@ -113,6 +120,127 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Nullable ContinuationToken; }; } // namespace _detail + struct BlobPrefix final + { + std::string Name; + }; + /** + * @brief Properties of a blob. + */ + struct BlobPropertiesInternal final + { + Nullable CreationTime; + DateTime LastModified; + ETag Etag; + /** + * Size in bytes. + */ + Nullable ContentLength; + Nullable ContentType; + Nullable ContentEncoding; + Nullable ContentLanguage; + Nullable> ContentMD5; + Nullable ContentDisposition; + Nullable CacheControl; + Nullable BlobSequenceNumber; + Nullable CopyId; + Nullable CopySource; + Nullable CopyProgress; + Nullable CopyCompletionTime; + Nullable CopyStatusDescription; + Nullable ServerEncrypted; + Nullable IncrementalCopy; + Nullable DestinationSnapshot; + Nullable DeletedTime; + Nullable RemainingRetentionDays; + Nullable AccessTierInferred; + Nullable CustomerProvidedKeySha256; + /** + * The name of the encryption scope under which the blob is encrypted. + */ + Nullable EncryptionScope; + Nullable AccessTierChangeTime; + Nullable TagCount; + Nullable ExpiresOn; + Nullable IsSealed; + Nullable LastAccessedOn; + Nullable DeleteTime; + }; + /** + * @brief An Azure Storage blob. + */ + struct BlobItemInternal final + { + std::string Name; + bool Deleted = bool(); + std::string Snapshot; + Nullable VersionId; + Nullable IsCurrentVersion; + /** + * Properties of a blob. + */ + BlobPropertiesInternal Properties; + Nullable DeletionId; + }; + struct BlobHierarchyListSegment final + { + /** + * Array of BlobPrefix. + */ + std::vector BlobPrefixes; + /** + * Array of BlobItemInternal. + */ + std::vector BlobItems; + }; + /** + * @brief Include this parameter to specify one or more datasets to include in the response. + */ + enum class ListBlobsIncludeFlags + { + None = 0, + Copy = 1, + Deleted = 2, + Metadata = 4, + Snapshots = 8, + Uncommittedblobs = 16, + Versions = 32, + Tags = 64, + }; + inline ListBlobsIncludeFlags operator|(ListBlobsIncludeFlags lhs, ListBlobsIncludeFlags rhs) + { + using type = std::underlying_type_t; + return static_cast(static_cast(lhs) | static_cast(rhs)); + } + inline ListBlobsIncludeFlags& operator|=(ListBlobsIncludeFlags& lhs, ListBlobsIncludeFlags rhs) + { + lhs = lhs | rhs; + return lhs; + } + inline ListBlobsIncludeFlags operator&(ListBlobsIncludeFlags lhs, ListBlobsIncludeFlags rhs) + { + using type = std::underlying_type_t; + return static_cast(static_cast(lhs) & static_cast(rhs)); + } + inline ListBlobsIncludeFlags& operator&=(ListBlobsIncludeFlags& lhs, ListBlobsIncludeFlags rhs) + { + lhs = lhs & rhs; + return lhs; + } + /** + * @brief An enumeration of blobs. + */ + struct ListBlobsHierarchySegmentResponse final + { + std::string ServiceEndpoint; + std::string ContainerName; + Nullable Prefix; + Nullable Marker; + Nullable MaxResults; + Nullable Delimiter; + BlobHierarchyListSegment Segment; + Nullable NextMarker; + }; /** * @brief Required only for Create File and Create Directory. The value must be "file" or * "directory". @@ -127,6 +255,24 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathResourceType Directory; AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathResourceType File; + private: + std::string m_value; + }; + /** + * @brief Required. Indicates mode of the expiry time. + */ + class PathExpiryOptions final { + public: + PathExpiryOptions() = default; + explicit PathExpiryOptions(std::string value) : m_value(std::move(value)) {} + bool operator==(const PathExpiryOptions& other) const { return m_value == other.m_value; } + bool operator!=(const PathExpiryOptions& other) const { return !(*this == other); } + const std::string& ToString() const { return m_value; } + AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathExpiryOptions NeverExpire; + AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathExpiryOptions RelativeToCreation; + AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathExpiryOptions RelativeToNow; + AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathExpiryOptions Absolute; + private: std::string m_value; }; @@ -152,6 +298,16 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { * The size of the resource in bytes. */ Nullable FileSize; + /** + * The value of this header is set to true if the contents of the request are successfully + * encrypted using the specified algorithm, and false otherwise. + */ + Nullable IsServerEncrypted; + /** + * The SHA-256 hash of the encryption key used to encrypt the blob. This header is only + * returned when the blob was encrypted with a customer-provided key. + */ + Nullable> EncryptionKeySha256; }; /** * @brief Response type for #Azure::Storage::Files::DataLake::PathClient::Delete. @@ -220,6 +376,19 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { */ Nullable ContinuationToken; }; + } // namespace _detail + /** + * @brief Response type for #Azure::Storage::Files::DataLake::PathClient::Undelete. + */ + struct UndeletePathResult final + { + /** + * The type of the resource. The value may be "file" or "directory". If not set, the value + * is "file". + */ + std::string ResourceType; + }; + namespace _detail { /** * @brief Response type for * #Azure::Storage::Files::DataLake::PathClient::GetAccessControlList. @@ -267,6 +436,16 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { * The size of the resource in bytes. */ int64_t FileSize = int64_t(); + /** + * The value of this header is set to true if the contents of the request are successfully + * encrypted using the specified algorithm, and false otherwise. + */ + Nullable IsServerEncrypted; + /** + * The SHA-256 hash of the encryption key used to encrypt the blob. This header is only + * returned when the blob was encrypted with a customer-provided key. + */ + Nullable> EncryptionKeySha256; }; /** * @brief Response type for #Azure::Storage::Files::DataLake::FileClient::Append. @@ -282,7 +461,12 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { * The value of this header is set to true if the contents of the request are successfully * encrypted using the specified algorithm, and false otherwise. */ - bool IsServerEncrypted = bool(); + Nullable IsServerEncrypted; + /** + * The SHA-256 hash of the encryption key used to encrypt the blob. This header is only + * returned when the blob was encrypted with a customer-provided key. + */ + Nullable> EncryptionKeySha256; }; } // namespace Models namespace _detail { @@ -303,6 +487,19 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { const Core::Url& url, const ListFileSystemPathsOptions& options, const Core::Context& context); + struct ListFileSystemBlobHierarchySegmentOptions final + { + Nullable Prefix; + Nullable Delimiter; + Nullable Marker; + Nullable MaxResults; + Nullable Include; + }; + static Response ListBlobHierarchySegment( + Core::Http::_internal::HttpPipeline& pipeline, + const Core::Url& url, + const ListFileSystemBlobHierarchySegmentOptions& options, + const Core::Context& context); }; class PathClient final { public: @@ -332,6 +529,15 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { ETag SourceIfNoneMatch; Nullable SourceIfModifiedSince; Nullable SourceIfUnmodifiedSince; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable Owner; + Nullable Group; + Nullable Acl; + Nullable ProposedLeaseId; + Nullable LeaseDuration; + Nullable ExpiryOptions; + Nullable ExpiresOn; }; static Response Create( Core::Http::_internal::HttpPipeline& pipeline, @@ -386,6 +592,15 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { const Core::Url& url, const SetPathAccessControlListRecursiveOptions& options, const Core::Context& context); + struct UndeletePathOptions final + { + Nullable UndeleteSource; + }; + static Response Undelete( + Core::Http::_internal::HttpPipeline& pipeline, + const Core::Url& url, + const UndeletePathOptions& options, + const Core::Context& context); struct GetPathAccessControlListOptions final { Nullable Upn; @@ -419,6 +634,8 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { ETag IfNoneMatch; Nullable IfModifiedSince; Nullable IfUnmodifiedSince; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; }; static Response Flush( Core::Http::_internal::HttpPipeline& pipeline, @@ -431,6 +648,9 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Nullable> TransactionalContentHash; Nullable> TransactionalContentCrc64; Nullable LeaseId; + Nullable EncryptionKey; + Nullable> EncryptionKeySha256; + Nullable Flush; }; static Response Append( Core::Http::_internal::HttpPipeline& pipeline, diff --git a/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp b/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp index a19745cfdc..627f901ba7 100644 --- a/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp @@ -8,6 +8,8 @@ #include #include +#include +#include #include #include @@ -21,9 +23,47 @@ #include #include #include +#include #include #include +namespace { +std::string ListBlobsIncludeFlagsToString( + const Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags& val) +{ + const Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags valueList[] = { + Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags::Copy, + Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags::Deleted, + Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags::Metadata, + Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags::Snapshots, + Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags::Uncommittedblobs, + Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags::Versions, + Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags::Tags, + }; + const char* stringList[] = { + "copy", + "deleted", + "metadata", + "snapshots", + "uncommittedblobs", + "versions", + "tags", + }; + std::string ret; + for (size_t i = 0; i < 7; ++i) + { + if ((val & valueList[i]) == valueList[i]) + { + if (!ret.empty()) + { + ret += ","; + } + ret += stringList[i]; + } + } + return ret; +} +} // namespace namespace Azure { namespace Storage { namespace Files { namespace DataLake { namespace Models { namespace _detail { @@ -40,6 +80,10 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { const PublicAccessType PublicAccessType::Path("blob"); const PathResourceType PathResourceType::Directory("directory"); const PathResourceType PathResourceType::File("file"); + const PathExpiryOptions PathExpiryOptions::NeverExpire("NeverExpire"); + const PathExpiryOptions PathExpiryOptions::RelativeToCreation("RelativeToCreation"); + const PathExpiryOptions PathExpiryOptions::RelativeToNow("RelativeToNow"); + const PathExpiryOptions PathExpiryOptions::Absolute("Absolute"); } // namespace Models namespace _detail { Response FileSystemClient::ListPaths( @@ -58,7 +102,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { request.GetUrl().AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); } - request.SetHeader("x-ms-version", "2020-02-10"); + request.SetHeader("x-ms-version", "2021-06-08"); if (options.ContinuationToken.HasValue() && !options.ContinuationToken.Value().empty()) { request.GetUrl().AppendQueryParameter( @@ -110,6 +154,15 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { vectorElement2.Owner = var0["owner"].get(); vectorElement2.Group = var0["group"].get(); vectorElement2.Permissions = var0["permissions"].get(); + if (var0.count("EncryptionScope") != 0) + { + vectorElement2.EncryptionScope = var0["EncryptionScope"].get(); + } + vectorElement2.CreatedOn = var0["creationTime"].get(); + if (var0.count("expiryTime") != 0) + { + vectorElement2.ExpiresOn = var0["expiryTime"].get(); + } if (var0.count("etag") != 0) { vectorElement2.ETag = var0["etag"].get(); @@ -123,6 +176,540 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { } return Response(std::move(response), std::move(pRawResponse)); } + Response FileSystemClient::ListBlobHierarchySegment( + Core::Http::_internal::HttpPipeline& pipeline, + const Core::Url& url, + const ListFileSystemBlobHierarchySegmentOptions& options, + const Core::Context& context) + { + auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter("restype", "container"); + request.GetUrl().AppendQueryParameter("comp", "list"); + if (options.Prefix.HasValue() && !options.Prefix.Value().empty()) + { + request.GetUrl().AppendQueryParameter( + "prefix", _internal::UrlEncodeQueryParameter(options.Prefix.Value())); + } + if (options.Delimiter.HasValue() && !options.Delimiter.Value().empty()) + { + request.GetUrl().AppendQueryParameter( + "delimiter", _internal::UrlEncodeQueryParameter(options.Delimiter.Value())); + } + if (options.Marker.HasValue() && !options.Marker.Value().empty()) + { + request.GetUrl().AppendQueryParameter( + "marker", _internal::UrlEncodeQueryParameter(options.Marker.Value())); + } + if (options.MaxResults.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "maxResults", std::to_string(options.MaxResults.Value())); + } + if (options.Include.HasValue() + && !ListBlobsIncludeFlagsToString(options.Include.Value()).empty()) + { + request.GetUrl().AppendQueryParameter( + "include", + _internal::UrlEncodeQueryParameter( + ListBlobsIncludeFlagsToString(options.Include.Value()))); + } + request.GetUrl().AppendQueryParameter("showonly", "deleted"); + request.SetHeader("x-ms-version", "2021-06-08"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) + { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::ListBlobsHierarchySegmentResponse response; + { + const auto& responseBody = pRawResponse->GetBody(); + _internal::XmlReader reader( + reinterpret_cast(responseBody.data()), responseBody.size()); + enum class XmlTagEnum + { + kUnknown, + kEnumerationResults, + kPrefix, + kMarker, + kMaxResults, + kDelimiter, + kSegment, + kBlobPrefixes, + kBlobPrefix, + kName, + kBlobItems, + kBlob, + kDeleted, + kSnapshot, + kVersionId, + kIsCurrentVersion, + kProperties, + kCreationTime, + kLastModified, + kEtag, + kContentLength, + kContentType, + kContentEncoding, + kContentLanguage, + kContentMD5, + kContentDisposition, + kCacheControl, + kXMsBlobSequenceNumber, + kCopyId, + kCopySource, + kCopyProgress, + kCopyCompletionTime, + kCopyStatusDescription, + kServerEncrypted, + kIncrementalCopy, + kDestinationSnapshot, + kDeletedTime, + kRemainingRetentionDays, + kAccessTierInferred, + kCustomerProvidedKeySha256, + kEncryptionScope, + kAccessTierChangeTime, + kTagCount, + kExpiryTime, + kSealed, + kLastAccessTime, + kDeleteTime, + kDeletionId, + kNextMarker, + }; + const std::unordered_map XmlTagEnumMap{ + {"EnumerationResults", XmlTagEnum::kEnumerationResults}, + {"Prefix", XmlTagEnum::kPrefix}, + {"Marker", XmlTagEnum::kMarker}, + {"MaxResults", XmlTagEnum::kMaxResults}, + {"Delimiter", XmlTagEnum::kDelimiter}, + {"Segment", XmlTagEnum::kSegment}, + {"BlobPrefixes", XmlTagEnum::kBlobPrefixes}, + {"BlobPrefix", XmlTagEnum::kBlobPrefix}, + {"Name", XmlTagEnum::kName}, + {"BlobItems", XmlTagEnum::kBlobItems}, + {"Blob", XmlTagEnum::kBlob}, + {"Deleted", XmlTagEnum::kDeleted}, + {"Snapshot", XmlTagEnum::kSnapshot}, + {"VersionId", XmlTagEnum::kVersionId}, + {"IsCurrentVersion", XmlTagEnum::kIsCurrentVersion}, + {"Properties", XmlTagEnum::kProperties}, + {"Creation-Time", XmlTagEnum::kCreationTime}, + {"Last-Modified", XmlTagEnum::kLastModified}, + {"Etag", XmlTagEnum::kEtag}, + {"Content-Length", XmlTagEnum::kContentLength}, + {"Content-Type", XmlTagEnum::kContentType}, + {"Content-Encoding", XmlTagEnum::kContentEncoding}, + {"Content-Language", XmlTagEnum::kContentLanguage}, + {"Content-MD5", XmlTagEnum::kContentMD5}, + {"Content-Disposition", XmlTagEnum::kContentDisposition}, + {"Cache-Control", XmlTagEnum::kCacheControl}, + {"x-ms-blob-sequence-number", XmlTagEnum::kXMsBlobSequenceNumber}, + {"CopyId", XmlTagEnum::kCopyId}, + {"CopySource", XmlTagEnum::kCopySource}, + {"CopyProgress", XmlTagEnum::kCopyProgress}, + {"CopyCompletionTime", XmlTagEnum::kCopyCompletionTime}, + {"CopyStatusDescription", XmlTagEnum::kCopyStatusDescription}, + {"ServerEncrypted", XmlTagEnum::kServerEncrypted}, + {"IncrementalCopy", XmlTagEnum::kIncrementalCopy}, + {"DestinationSnapshot", XmlTagEnum::kDestinationSnapshot}, + {"DeletedTime", XmlTagEnum::kDeletedTime}, + {"RemainingRetentionDays", XmlTagEnum::kRemainingRetentionDays}, + {"AccessTierInferred", XmlTagEnum::kAccessTierInferred}, + {"CustomerProvidedKeySha256", XmlTagEnum::kCustomerProvidedKeySha256}, + {"EncryptionScope", XmlTagEnum::kEncryptionScope}, + {"AccessTierChangeTime", XmlTagEnum::kAccessTierChangeTime}, + {"TagCount", XmlTagEnum::kTagCount}, + {"Expiry-Time", XmlTagEnum::kExpiryTime}, + {"Sealed", XmlTagEnum::kSealed}, + {"LastAccessTime", XmlTagEnum::kLastAccessTime}, + {"DeleteTime", XmlTagEnum::kDeleteTime}, + {"DeletionId", XmlTagEnum::kDeletionId}, + {"NextMarker", XmlTagEnum::kNextMarker}, + }; + std::vector xmlPath; + Models::BlobPrefix vectorElement1; + Models::BlobItemInternal vectorElement2; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + auto ite = XmlTagEnumMap.find(node.Name); + xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown : ite->second); + } + else if (node.Type == _internal::XmlNodeType::Text) + { + if (xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kPrefix) + { + response.Prefix = node.Value; + } + else if ( + xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kMarker) + { + response.Marker = node.Value; + } + else if ( + xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kMaxResults) + { + response.MaxResults = std::stoi(node.Value); + } + else if ( + xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kDelimiter) + { + response.Delimiter = node.Value; + } + else if ( + xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobPrefixes + && xmlPath[3] == XmlTagEnum::kBlobPrefix && xmlPath[4] == XmlTagEnum::kName) + { + vectorElement1.Name = node.Value; + } + else if ( + xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kName) + { + vectorElement2.Name = node.Value; + } + else if ( + xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kDeleted) + { + vectorElement2.Deleted = node.Value == std::string("true"); + } + else if ( + xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kSnapshot) + { + vectorElement2.Snapshot = node.Value; + } + else if ( + xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kVersionId) + { + vectorElement2.VersionId = node.Value; + } + else if ( + xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kIsCurrentVersion) + { + vectorElement2.IsCurrentVersion = node.Value == std::string("true"); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kCreationTime) + { + vectorElement2.Properties.CreationTime + = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kLastModified) + { + vectorElement2.Properties.LastModified + = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kEtag) + { + vectorElement2.Properties.Etag = ETag(node.Value); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kContentLength) + { + vectorElement2.Properties.ContentLength = std::stoll(node.Value); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kContentType) + { + vectorElement2.Properties.ContentType = node.Value; + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kContentEncoding) + { + vectorElement2.Properties.ContentEncoding = node.Value; + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kContentLanguage) + { + vectorElement2.Properties.ContentLanguage = node.Value; + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kContentMD5) + { + vectorElement2.Properties.ContentMD5 = Core::Convert::Base64Decode(node.Value); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kContentDisposition) + { + vectorElement2.Properties.ContentDisposition = node.Value; + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kCacheControl) + { + vectorElement2.Properties.CacheControl = node.Value; + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kXMsBlobSequenceNumber) + { + vectorElement2.Properties.BlobSequenceNumber = std::stoll(node.Value); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kCopyId) + { + vectorElement2.Properties.CopyId = node.Value; + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kCopySource) + { + vectorElement2.Properties.CopySource = node.Value; + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kCopyProgress) + { + vectorElement2.Properties.CopyProgress = node.Value; + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kCopyCompletionTime) + { + vectorElement2.Properties.CopyCompletionTime + = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kCopyStatusDescription) + { + vectorElement2.Properties.CopyStatusDescription = node.Value; + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kServerEncrypted) + { + vectorElement2.Properties.ServerEncrypted = node.Value == std::string("true"); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kIncrementalCopy) + { + vectorElement2.Properties.IncrementalCopy = node.Value == std::string("true"); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kDestinationSnapshot) + { + vectorElement2.Properties.DestinationSnapshot = node.Value; + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kDeletedTime) + { + vectorElement2.Properties.DeletedTime + = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kRemainingRetentionDays) + { + vectorElement2.Properties.RemainingRetentionDays = std::stoi(node.Value); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kAccessTierInferred) + { + vectorElement2.Properties.AccessTierInferred = node.Value == std::string("true"); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kCustomerProvidedKeySha256) + { + vectorElement2.Properties.CustomerProvidedKeySha256 = node.Value; + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kEncryptionScope) + { + vectorElement2.Properties.EncryptionScope = node.Value; + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kAccessTierChangeTime) + { + vectorElement2.Properties.AccessTierChangeTime + = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kTagCount) + { + vectorElement2.Properties.TagCount = std::stoi(node.Value); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kExpiryTime) + { + vectorElement2.Properties.ExpiresOn + = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kSealed) + { + vectorElement2.Properties.IsSealed = node.Value == std::string("true"); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kLastAccessTime) + { + vectorElement2.Properties.LastAccessedOn + = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + else if ( + xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties + && xmlPath[5] == XmlTagEnum::kDeleteTime) + { + vectorElement2.Properties.DeleteTime + = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + else if ( + xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kDeletionId) + { + vectorElement2.DeletionId = node.Value; + } + else if ( + xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kNextMarker) + { + response.NextMarker = node.Value; + } + } + else if (node.Type == _internal::XmlNodeType::Attribute) + { + if (xmlPath.size() == 1 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && node.Name == "ServiceEndpoint") + { + response.ServiceEndpoint = node.Value; + } + else if ( + xmlPath.size() == 1 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && node.Name == "ContainerName") + { + response.ContainerName = node.Value; + } + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobPrefixes + && xmlPath[3] == XmlTagEnum::kBlobPrefix) + { + response.Segment.BlobPrefixes.push_back(std::move(vectorElement1)); + vectorElement1 = Models::BlobPrefix(); + } + else if ( + xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems + && xmlPath[3] == XmlTagEnum::kBlob) + { + response.Segment.BlobItems.push_back(std::move(vectorElement2)); + vectorElement2 = Models::BlobItemInternal(); + } + xmlPath.pop_back(); + } + } + } + return Response( + std::move(response), std::move(pRawResponse)); + } Response PathClient::Create( Core::Http::_internal::HttpPipeline& pipeline, const Core::Url& url, @@ -138,7 +725,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { request.GetUrl().AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); } - request.SetHeader("x-ms-version", "2020-02-10"); + request.SetHeader("x-ms-version", "2021-06-08"); if (options.Resource.HasValue() && !options.Resource.Value().ToString().empty()) { request.GetUrl().AppendQueryParameter( @@ -238,6 +825,46 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { "x-ms-source-if-unmodified-since", options.SourceIfUnmodifiedSince.Value().ToString(Azure::DateTime::DateFormat::Rfc1123)); } + if (options.EncryptionKey.HasValue() && !options.EncryptionKey.Value().empty()) + { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() + && !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()).empty()) + { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + request.SetHeader("x-ms-encryption-algorithm", "AES256"); + if (options.Owner.HasValue() && !options.Owner.Value().empty()) + { + request.SetHeader("x-ms-owner", options.Owner.Value()); + } + if (options.Group.HasValue() && !options.Group.Value().empty()) + { + request.SetHeader("x-ms-group", options.Group.Value()); + } + if (options.Acl.HasValue() && !options.Acl.Value().empty()) + { + request.SetHeader("x-ms-acl", options.Acl.Value()); + } + if (options.ProposedLeaseId.HasValue() && !options.ProposedLeaseId.Value().empty()) + { + request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId.Value()); + } + if (options.LeaseDuration.HasValue()) + { + request.SetHeader("x-ms-lease-duration", std::to_string(options.LeaseDuration.Value())); + } + if (options.ExpiryOptions.HasValue() && !options.ExpiryOptions.Value().ToString().empty()) + { + request.SetHeader("x-ms-expiry-option", options.ExpiryOptions.Value().ToString()); + } + if (options.ExpiresOn.HasValue() && !options.ExpiresOn.Value().empty()) + { + request.SetHeader("x-ms-expiry-time", options.ExpiresOn.Value()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Created) @@ -252,6 +879,16 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { response.FileSize = std::stoll(pRawResponse->GetHeaders().at("Content-Length")); } + if (pRawResponse->GetHeaders().count("x-ms-request-server-encrypted") != 0) + { + response.IsServerEncrypted + = pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == std::string("true"); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) + { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } return Response(std::move(response), std::move(pRawResponse)); } Response PathClient::Delete( @@ -269,7 +906,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { request.GetUrl().AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); } - request.SetHeader("x-ms-version", "2020-02-10"); + request.SetHeader("x-ms-version", "2021-06-08"); if (options.Recursive.HasValue()) { request.GetUrl().AppendQueryParameter( @@ -361,7 +998,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { "If-Unmodified-Since", options.IfUnmodifiedSince.Value().ToString(Azure::DateTime::DateFormat::Rfc1123)); } - request.SetHeader("x-ms-version", "2020-02-10"); + request.SetHeader("x-ms-version", "2021-06-08"); auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -408,7 +1045,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { request.SetHeader("x-ms-acl", options.Acl.Value()); } - request.SetHeader("x-ms-version", "2020-02-10"); + request.SetHeader("x-ms-version", "2021-06-08"); auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -449,6 +1086,29 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { return Response( std::move(response), std::move(pRawResponse)); } + Response PathClient::Undelete( + Core::Http::_internal::HttpPipeline& pipeline, + const Core::Url& url, + const UndeletePathOptions& options, + const Core::Context& context) + { + auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); + request.GetUrl().AppendQueryParameter("comp", "undelete"); + if (options.UndeleteSource.HasValue() && !options.UndeleteSource.Value().empty()) + { + request.SetHeader("x-ms-undelete-source", options.UndeleteSource.Value()); + } + request.SetHeader("x-ms-version", "2021-06-08"); + auto pRawResponse = pipeline.Send(request, context); + auto httpStatusCode = pRawResponse->GetStatusCode(); + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) + { + throw StorageException::CreateFromResponse(std::move(pRawResponse)); + } + Models::UndeletePathResult response; + response.ResourceType = pRawResponse->GetHeaders().at("x-ms-resource-type"); + return Response(std::move(response), std::move(pRawResponse)); + } Response PathClient::GetAccessControlList( Core::Http::_internal::HttpPipeline& pipeline, const Core::Url& url, @@ -485,7 +1145,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { "If-Unmodified-Since", options.IfUnmodifiedSince.Value().ToString(Azure::DateTime::DateFormat::Rfc1123)); } - request.SetHeader("x-ms-version", "2020-02-10"); + request.SetHeader("x-ms-version", "2021-06-08"); auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -572,7 +1232,19 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { "If-Unmodified-Since", options.IfUnmodifiedSince.Value().ToString(Azure::DateTime::DateFormat::Rfc1123)); } - request.SetHeader("x-ms-version", "2020-02-10"); + request.SetHeader("x-ms-version", "2021-06-08"); + if (options.EncryptionKey.HasValue() && !options.EncryptionKey.Value().empty()) + { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() + && !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()).empty()) + { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + request.SetHeader("x-ms-encryption-algorithm", "AES256"); auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -584,6 +1256,16 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { response.LastModified = DateTime::Parse( pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123); response.FileSize = std::stoll(pRawResponse->GetHeaders().at("Content-Length")); + if (pRawResponse->GetHeaders().count("x-ms-request-server-encrypted") != 0) + { + response.IsServerEncrypted + = pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == std::string("true"); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) + { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } return Response(std::move(response), std::move(pRawResponse)); } Response FileClient::Append( @@ -617,7 +1299,23 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); } - request.SetHeader("x-ms-version", "2020-02-10"); + request.SetHeader("x-ms-version", "2021-06-08"); + if (options.EncryptionKey.HasValue() && !options.EncryptionKey.Value().empty()) + { + request.SetHeader("x-ms-encryption-key", options.EncryptionKey.Value()); + } + if (options.EncryptionKeySha256.HasValue() + && !Core::Convert::Base64Encode(options.EncryptionKeySha256.Value()).empty()) + { + request.SetHeader( + "x-ms-encryption-key-sha256", + Core::Convert::Base64Encode(options.EncryptionKeySha256.Value())); + } + request.SetHeader("x-ms-encryption-algorithm", "AES256"); + if (options.Flush.HasValue()) + { + request.GetUrl().AppendQueryParameter("flush", options.Flush.Value() ? "true" : "false"); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Accepted) @@ -639,8 +1337,16 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { = Core::Convert::Base64Decode(pRawResponse->GetHeaders().at("x-ms-content-crc64")); response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Crc64; } - response.IsServerEncrypted - = pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == std::string("true"); + if (pRawResponse->GetHeaders().count("x-ms-request-server-encrypted") != 0) + { + response.IsServerEncrypted + = pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == std::string("true"); + } + if (pRawResponse->GetHeaders().count("x-ms-encryption-key-sha256") != 0) + { + response.EncryptionKeySha256 = Core::Convert::Base64Decode( + pRawResponse->GetHeaders().at("x-ms-encryption-key-sha256")); + } return Response(std::move(response), std::move(pRawResponse)); } } // namespace _detail diff --git a/sdk/storage/azure-storage-files-datalake/swagger/README.md b/sdk/storage/azure-storage-files-datalake/swagger/README.md index 0e9b87c617..8bc9e92e05 100644 --- a/sdk/storage/azure-storage-files-datalake/swagger/README.md +++ b/sdk/storage/azure-storage-files-datalake/swagger/README.md @@ -9,7 +9,7 @@ package-name: azure-storage-files-datalake namespace: Azure::Storage::Files::DataLake output-folder: generated clear-output-folder: true -input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/storage-main/specification/storage/data-plane/Microsoft.StorageDataLake/stable/2020-06-12/DataLakeStorage.json +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/storage/data-plane/Azure.Storage.Files.DataLake/preview/2021-06-08/DataLakeStorage.json ``` ## ModelFour Options @@ -66,12 +66,10 @@ directive: delete $["/{filesystem}"].patch; delete $["/{filesystem}"].head; delete $["/{filesystem}"].delete; - delete $["/{filesystem}?restype=container&comp=list&hierarchy"]; delete $["/{filesystem}/{path}"].post; delete $["/{filesystem}/{path}"].get; delete $["/{filesystem}/{path}"].patch; delete $["/{filesystem}/{path}?comp=expiry"]; - delete $["/{filesystem}/{path}?comp=undelete"]; ``` ### API Version @@ -89,13 +87,13 @@ directive: "name": "ApiVersion", "modelAsString": false }, - "enum": ["2020-02-10"], + "enum": ["2021-06-08"], "description": "The version used for the operations to Azure storage services." }; - from: swagger-document where: $.parameters transform: > - $.ApiVersionParameter.enum[0] = "2020-02-10"; + $.ApiVersionParameter.enum[0] = "2021-06-08"; ``` ### Rename Operations @@ -122,10 +120,20 @@ directive: ```yaml directive: + - from: swagger-document + where: $["x-ms-paths"].*.*.responses.*.headers + transform: > + for (const h in $) { + if (h === "x-ms-encryption-key-sha256") { + $[h]["format"] = "byte"; + } + } - from: swagger-document where: $.parameters transform: > $.Continuation["x-ms-client-name"] = "ContinuationToken"; + $.ListBlobsInclude.items["x-ms-enum"]["name"] = "ListBlobsIncludeFlags"; + $.EncryptionKeySha256["format"] = "byte"; - from: swagger-document where: $.definitions transform: > @@ -175,6 +183,10 @@ directive: $.Path.properties["lastModified"]["format"] = "date-time-rfc1123"; $.Path.properties["contentLength"]["x-ms-client-name"] = "FileSize"; $.Path.properties["isDirectory"]["x-ms-client-default"] = false; + $.Path.properties["EncryptionScope"]["x-nullable"] = true; + $.Path.properties["creationTime"]["x-ms-client-name"] = "CreatedOn"; + $.Path.properties["expiryTime"]["x-ms-client-name"] = "ExpiresOn"; + $.Path.properties["expiryTime"]["x-nullable"] = true; $.Path.properties["etag"] = {"type": "string", "x-ms-format": "string", "x-ms-client-default": "", "x-ms-client-name": "ETag"}; delete $.Path.properties["eTag"]; $.PathList["x-namespace"] = "_detail"; @@ -197,6 +209,8 @@ directive: transform: > $["201"].headers["Content-Length"]["x-ms-client-name"] = "FileSize"; $["201"].headers["Content-Length"]["x-nullable"] = true; + $["201"].headers["x-ms-request-server-encrypted"]["x-nullable"] = true; + $["201"].headers["x-ms-encryption-key-sha256"]["x-nullable"] = true; delete $["201"].headers["x-ms-continuation"]; $["201"].schema = { "type": "object", @@ -349,6 +363,8 @@ directive: $["Content-MD5"]["x-nullable"] = true; $["x-ms-content-crc64"]["x-ms-client-name"] = "TransactionalContentHash"; $["x-ms-content-crc64"]["x-nullable"] = true; + $["x-ms-request-server-encrypted"]["x-nullable"] = true; + $["x-ms-encryption-key-sha256"]["x-nullable"] = true; delete $["ETag"]; ``` @@ -360,4 +376,6 @@ directive: where: $["x-ms-paths"]["/{filesystem}/{path}?action=flush"].patch.responses["200"].headers transform: > $["Content-Length"]["x-ms-client-name"] = "FileSize"; + $["x-ms-request-server-encrypted"]["x-nullable"] = true; + $["x-ms-encryption-key-sha256"]["x-nullable"] = true; ``` \ No newline at end of file From 0fd902b58a1a10087e0e54b3424c2c7886d78915 Mon Sep 17 00:00:00 2001 From: Zhendong Chang Date: Tue, 13 Sep 2022 16:29:20 +0800 Subject: [PATCH 2/3] fix conversation --- .../storage/files/datalake/rest_client.hpp | 162 +---- .../src/rest_client.cpp | 593 +----------------- .../swagger/README.md | 48 +- 3 files changed, 52 insertions(+), 751 deletions(-) diff --git a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp index 8b01692b30..f64978c407 100644 --- a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp +++ b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp @@ -8,7 +8,6 @@ #include #include -#include #include #include @@ -97,8 +96,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { * The name of the encryption scope under which the blob is encrypted. */ Nullable EncryptionScope; - std::string CreatedOn; - Nullable ExpiresOn; std::string ETag; }; namespace _detail { @@ -120,130 +117,9 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Nullable ContinuationToken; }; } // namespace _detail - struct BlobPrefix final - { - std::string Name; - }; - /** - * @brief Properties of a blob. - */ - struct BlobPropertiesInternal final - { - Nullable CreationTime; - DateTime LastModified; - ETag Etag; - /** - * Size in bytes. - */ - Nullable ContentLength; - Nullable ContentType; - Nullable ContentEncoding; - Nullable ContentLanguage; - Nullable> ContentMD5; - Nullable ContentDisposition; - Nullable CacheControl; - Nullable BlobSequenceNumber; - Nullable CopyId; - Nullable CopySource; - Nullable CopyProgress; - Nullable CopyCompletionTime; - Nullable CopyStatusDescription; - Nullable ServerEncrypted; - Nullable IncrementalCopy; - Nullable DestinationSnapshot; - Nullable DeletedTime; - Nullable RemainingRetentionDays; - Nullable AccessTierInferred; - Nullable CustomerProvidedKeySha256; - /** - * The name of the encryption scope under which the blob is encrypted. - */ - Nullable EncryptionScope; - Nullable AccessTierChangeTime; - Nullable TagCount; - Nullable ExpiresOn; - Nullable IsSealed; - Nullable LastAccessedOn; - Nullable DeleteTime; - }; - /** - * @brief An Azure Storage blob. - */ - struct BlobItemInternal final - { - std::string Name; - bool Deleted = bool(); - std::string Snapshot; - Nullable VersionId; - Nullable IsCurrentVersion; - /** - * Properties of a blob. - */ - BlobPropertiesInternal Properties; - Nullable DeletionId; - }; - struct BlobHierarchyListSegment final - { - /** - * Array of BlobPrefix. - */ - std::vector BlobPrefixes; - /** - * Array of BlobItemInternal. - */ - std::vector BlobItems; - }; /** - * @brief Include this parameter to specify one or more datasets to include in the response. - */ - enum class ListBlobsIncludeFlags - { - None = 0, - Copy = 1, - Deleted = 2, - Metadata = 4, - Snapshots = 8, - Uncommittedblobs = 16, - Versions = 32, - Tags = 64, - }; - inline ListBlobsIncludeFlags operator|(ListBlobsIncludeFlags lhs, ListBlobsIncludeFlags rhs) - { - using type = std::underlying_type_t; - return static_cast(static_cast(lhs) | static_cast(rhs)); - } - inline ListBlobsIncludeFlags& operator|=(ListBlobsIncludeFlags& lhs, ListBlobsIncludeFlags rhs) - { - lhs = lhs | rhs; - return lhs; - } - inline ListBlobsIncludeFlags operator&(ListBlobsIncludeFlags lhs, ListBlobsIncludeFlags rhs) - { - using type = std::underlying_type_t; - return static_cast(static_cast(lhs) & static_cast(rhs)); - } - inline ListBlobsIncludeFlags& operator&=(ListBlobsIncludeFlags& lhs, ListBlobsIncludeFlags rhs) - { - lhs = lhs & rhs; - return lhs; - } - /** - * @brief An enumeration of blobs. - */ - struct ListBlobsHierarchySegmentResponse final - { - std::string ServiceEndpoint; - std::string ContainerName; - Nullable Prefix; - Nullable Marker; - Nullable MaxResults; - Nullable Delimiter; - BlobHierarchyListSegment Segment; - Nullable NextMarker; - }; - /** - * @brief Required only for Create File and Create Directory. The value must be "file" or - * "directory". + * @brief The type of the resource. The value may be "file" or "directory". If not set, the + * value is "file". */ class PathResourceType final { public: @@ -255,24 +131,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathResourceType Directory; AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathResourceType File; - private: - std::string m_value; - }; - /** - * @brief Required. Indicates mode of the expiry time. - */ - class PathExpiryOptions final { - public: - PathExpiryOptions() = default; - explicit PathExpiryOptions(std::string value) : m_value(std::move(value)) {} - bool operator==(const PathExpiryOptions& other) const { return m_value == other.m_value; } - bool operator!=(const PathExpiryOptions& other) const { return !(*this == other); } - const std::string& ToString() const { return m_value; } - AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathExpiryOptions NeverExpire; - AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathExpiryOptions RelativeToCreation; - AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathExpiryOptions RelativeToNow; - AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathExpiryOptions Absolute; - private: std::string m_value; }; @@ -386,7 +244,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { * The type of the resource. The value may be "file" or "directory". If not set, the value * is "file". */ - std::string ResourceType; + Nullable ResourceType; }; namespace _detail { /** @@ -487,19 +345,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { const Core::Url& url, const ListFileSystemPathsOptions& options, const Core::Context& context); - struct ListFileSystemBlobHierarchySegmentOptions final - { - Nullable Prefix; - Nullable Delimiter; - Nullable Marker; - Nullable MaxResults; - Nullable Include; - }; - static Response ListBlobHierarchySegment( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const ListFileSystemBlobHierarchySegmentOptions& options, - const Core::Context& context); }; class PathClient final { public: @@ -536,7 +381,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Nullable Acl; Nullable ProposedLeaseId; Nullable LeaseDuration; - Nullable ExpiryOptions; Nullable ExpiresOn; }; static Response Create( diff --git a/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp b/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp index 627f901ba7..94fef688cf 100644 --- a/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp @@ -8,8 +8,6 @@ #include #include -#include -#include #include #include @@ -23,47 +21,9 @@ #include #include #include -#include #include #include -namespace { -std::string ListBlobsIncludeFlagsToString( - const Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags& val) -{ - const Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags valueList[] = { - Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags::Copy, - Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags::Deleted, - Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags::Metadata, - Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags::Snapshots, - Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags::Uncommittedblobs, - Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags::Versions, - Azure::Storage::Files::DataLake::Models::ListBlobsIncludeFlags::Tags, - }; - const char* stringList[] = { - "copy", - "deleted", - "metadata", - "snapshots", - "uncommittedblobs", - "versions", - "tags", - }; - std::string ret; - for (size_t i = 0; i < 7; ++i) - { - if ((val & valueList[i]) == valueList[i]) - { - if (!ret.empty()) - { - ret += ","; - } - ret += stringList[i]; - } - } - return ret; -} -} // namespace namespace Azure { namespace Storage { namespace Files { namespace DataLake { namespace Models { namespace _detail { @@ -80,10 +40,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { const PublicAccessType PublicAccessType::Path("blob"); const PathResourceType PathResourceType::Directory("directory"); const PathResourceType PathResourceType::File("file"); - const PathExpiryOptions PathExpiryOptions::NeverExpire("NeverExpire"); - const PathExpiryOptions PathExpiryOptions::RelativeToCreation("RelativeToCreation"); - const PathExpiryOptions PathExpiryOptions::RelativeToNow("RelativeToNow"); - const PathExpiryOptions PathExpiryOptions::Absolute("Absolute"); } // namespace Models namespace _detail { Response FileSystemClient::ListPaths( @@ -158,11 +114,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { vectorElement2.EncryptionScope = var0["EncryptionScope"].get(); } - vectorElement2.CreatedOn = var0["creationTime"].get(); - if (var0.count("expiryTime") != 0) - { - vectorElement2.ExpiresOn = var0["expiryTime"].get(); - } if (var0.count("etag") != 0) { vectorElement2.ETag = var0["etag"].get(); @@ -176,540 +127,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { } return Response(std::move(response), std::move(pRawResponse)); } - Response FileSystemClient::ListBlobHierarchySegment( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const ListFileSystemBlobHierarchySegmentOptions& options, - const Core::Context& context) - { - auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter("restype", "container"); - request.GetUrl().AppendQueryParameter("comp", "list"); - if (options.Prefix.HasValue() && !options.Prefix.Value().empty()) - { - request.GetUrl().AppendQueryParameter( - "prefix", _internal::UrlEncodeQueryParameter(options.Prefix.Value())); - } - if (options.Delimiter.HasValue() && !options.Delimiter.Value().empty()) - { - request.GetUrl().AppendQueryParameter( - "delimiter", _internal::UrlEncodeQueryParameter(options.Delimiter.Value())); - } - if (options.Marker.HasValue() && !options.Marker.Value().empty()) - { - request.GetUrl().AppendQueryParameter( - "marker", _internal::UrlEncodeQueryParameter(options.Marker.Value())); - } - if (options.MaxResults.HasValue()) - { - request.GetUrl().AppendQueryParameter( - "maxResults", std::to_string(options.MaxResults.Value())); - } - if (options.Include.HasValue() - && !ListBlobsIncludeFlagsToString(options.Include.Value()).empty()) - { - request.GetUrl().AppendQueryParameter( - "include", - _internal::UrlEncodeQueryParameter( - ListBlobsIncludeFlagsToString(options.Include.Value()))); - } - request.GetUrl().AppendQueryParameter("showonly", "deleted"); - request.SetHeader("x-ms-version", "2021-06-08"); - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::Ok) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::ListBlobsHierarchySegmentResponse response; - { - const auto& responseBody = pRawResponse->GetBody(); - _internal::XmlReader reader( - reinterpret_cast(responseBody.data()), responseBody.size()); - enum class XmlTagEnum - { - kUnknown, - kEnumerationResults, - kPrefix, - kMarker, - kMaxResults, - kDelimiter, - kSegment, - kBlobPrefixes, - kBlobPrefix, - kName, - kBlobItems, - kBlob, - kDeleted, - kSnapshot, - kVersionId, - kIsCurrentVersion, - kProperties, - kCreationTime, - kLastModified, - kEtag, - kContentLength, - kContentType, - kContentEncoding, - kContentLanguage, - kContentMD5, - kContentDisposition, - kCacheControl, - kXMsBlobSequenceNumber, - kCopyId, - kCopySource, - kCopyProgress, - kCopyCompletionTime, - kCopyStatusDescription, - kServerEncrypted, - kIncrementalCopy, - kDestinationSnapshot, - kDeletedTime, - kRemainingRetentionDays, - kAccessTierInferred, - kCustomerProvidedKeySha256, - kEncryptionScope, - kAccessTierChangeTime, - kTagCount, - kExpiryTime, - kSealed, - kLastAccessTime, - kDeleteTime, - kDeletionId, - kNextMarker, - }; - const std::unordered_map XmlTagEnumMap{ - {"EnumerationResults", XmlTagEnum::kEnumerationResults}, - {"Prefix", XmlTagEnum::kPrefix}, - {"Marker", XmlTagEnum::kMarker}, - {"MaxResults", XmlTagEnum::kMaxResults}, - {"Delimiter", XmlTagEnum::kDelimiter}, - {"Segment", XmlTagEnum::kSegment}, - {"BlobPrefixes", XmlTagEnum::kBlobPrefixes}, - {"BlobPrefix", XmlTagEnum::kBlobPrefix}, - {"Name", XmlTagEnum::kName}, - {"BlobItems", XmlTagEnum::kBlobItems}, - {"Blob", XmlTagEnum::kBlob}, - {"Deleted", XmlTagEnum::kDeleted}, - {"Snapshot", XmlTagEnum::kSnapshot}, - {"VersionId", XmlTagEnum::kVersionId}, - {"IsCurrentVersion", XmlTagEnum::kIsCurrentVersion}, - {"Properties", XmlTagEnum::kProperties}, - {"Creation-Time", XmlTagEnum::kCreationTime}, - {"Last-Modified", XmlTagEnum::kLastModified}, - {"Etag", XmlTagEnum::kEtag}, - {"Content-Length", XmlTagEnum::kContentLength}, - {"Content-Type", XmlTagEnum::kContentType}, - {"Content-Encoding", XmlTagEnum::kContentEncoding}, - {"Content-Language", XmlTagEnum::kContentLanguage}, - {"Content-MD5", XmlTagEnum::kContentMD5}, - {"Content-Disposition", XmlTagEnum::kContentDisposition}, - {"Cache-Control", XmlTagEnum::kCacheControl}, - {"x-ms-blob-sequence-number", XmlTagEnum::kXMsBlobSequenceNumber}, - {"CopyId", XmlTagEnum::kCopyId}, - {"CopySource", XmlTagEnum::kCopySource}, - {"CopyProgress", XmlTagEnum::kCopyProgress}, - {"CopyCompletionTime", XmlTagEnum::kCopyCompletionTime}, - {"CopyStatusDescription", XmlTagEnum::kCopyStatusDescription}, - {"ServerEncrypted", XmlTagEnum::kServerEncrypted}, - {"IncrementalCopy", XmlTagEnum::kIncrementalCopy}, - {"DestinationSnapshot", XmlTagEnum::kDestinationSnapshot}, - {"DeletedTime", XmlTagEnum::kDeletedTime}, - {"RemainingRetentionDays", XmlTagEnum::kRemainingRetentionDays}, - {"AccessTierInferred", XmlTagEnum::kAccessTierInferred}, - {"CustomerProvidedKeySha256", XmlTagEnum::kCustomerProvidedKeySha256}, - {"EncryptionScope", XmlTagEnum::kEncryptionScope}, - {"AccessTierChangeTime", XmlTagEnum::kAccessTierChangeTime}, - {"TagCount", XmlTagEnum::kTagCount}, - {"Expiry-Time", XmlTagEnum::kExpiryTime}, - {"Sealed", XmlTagEnum::kSealed}, - {"LastAccessTime", XmlTagEnum::kLastAccessTime}, - {"DeleteTime", XmlTagEnum::kDeleteTime}, - {"DeletionId", XmlTagEnum::kDeletionId}, - {"NextMarker", XmlTagEnum::kNextMarker}, - }; - std::vector xmlPath; - Models::BlobPrefix vectorElement1; - Models::BlobItemInternal vectorElement2; - while (true) - { - auto node = reader.Read(); - if (node.Type == _internal::XmlNodeType::End) - { - break; - } - else if (node.Type == _internal::XmlNodeType::StartTag) - { - auto ite = XmlTagEnumMap.find(node.Name); - xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown : ite->second); - } - else if (node.Type == _internal::XmlNodeType::Text) - { - if (xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kPrefix) - { - response.Prefix = node.Value; - } - else if ( - xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kMarker) - { - response.Marker = node.Value; - } - else if ( - xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kMaxResults) - { - response.MaxResults = std::stoi(node.Value); - } - else if ( - xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kDelimiter) - { - response.Delimiter = node.Value; - } - else if ( - xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobPrefixes - && xmlPath[3] == XmlTagEnum::kBlobPrefix && xmlPath[4] == XmlTagEnum::kName) - { - vectorElement1.Name = node.Value; - } - else if ( - xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kName) - { - vectorElement2.Name = node.Value; - } - else if ( - xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kDeleted) - { - vectorElement2.Deleted = node.Value == std::string("true"); - } - else if ( - xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kSnapshot) - { - vectorElement2.Snapshot = node.Value; - } - else if ( - xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kVersionId) - { - vectorElement2.VersionId = node.Value; - } - else if ( - xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kIsCurrentVersion) - { - vectorElement2.IsCurrentVersion = node.Value == std::string("true"); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kCreationTime) - { - vectorElement2.Properties.CreationTime - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kLastModified) - { - vectorElement2.Properties.LastModified - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kEtag) - { - vectorElement2.Properties.Etag = ETag(node.Value); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kContentLength) - { - vectorElement2.Properties.ContentLength = std::stoll(node.Value); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kContentType) - { - vectorElement2.Properties.ContentType = node.Value; - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kContentEncoding) - { - vectorElement2.Properties.ContentEncoding = node.Value; - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kContentLanguage) - { - vectorElement2.Properties.ContentLanguage = node.Value; - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kContentMD5) - { - vectorElement2.Properties.ContentMD5 = Core::Convert::Base64Decode(node.Value); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kContentDisposition) - { - vectorElement2.Properties.ContentDisposition = node.Value; - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kCacheControl) - { - vectorElement2.Properties.CacheControl = node.Value; - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kXMsBlobSequenceNumber) - { - vectorElement2.Properties.BlobSequenceNumber = std::stoll(node.Value); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kCopyId) - { - vectorElement2.Properties.CopyId = node.Value; - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kCopySource) - { - vectorElement2.Properties.CopySource = node.Value; - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kCopyProgress) - { - vectorElement2.Properties.CopyProgress = node.Value; - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kCopyCompletionTime) - { - vectorElement2.Properties.CopyCompletionTime - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kCopyStatusDescription) - { - vectorElement2.Properties.CopyStatusDescription = node.Value; - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kServerEncrypted) - { - vectorElement2.Properties.ServerEncrypted = node.Value == std::string("true"); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kIncrementalCopy) - { - vectorElement2.Properties.IncrementalCopy = node.Value == std::string("true"); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kDestinationSnapshot) - { - vectorElement2.Properties.DestinationSnapshot = node.Value; - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kDeletedTime) - { - vectorElement2.Properties.DeletedTime - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kRemainingRetentionDays) - { - vectorElement2.Properties.RemainingRetentionDays = std::stoi(node.Value); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kAccessTierInferred) - { - vectorElement2.Properties.AccessTierInferred = node.Value == std::string("true"); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kCustomerProvidedKeySha256) - { - vectorElement2.Properties.CustomerProvidedKeySha256 = node.Value; - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kEncryptionScope) - { - vectorElement2.Properties.EncryptionScope = node.Value; - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kAccessTierChangeTime) - { - vectorElement2.Properties.AccessTierChangeTime - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kTagCount) - { - vectorElement2.Properties.TagCount = std::stoi(node.Value); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kExpiryTime) - { - vectorElement2.Properties.ExpiresOn - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kSealed) - { - vectorElement2.Properties.IsSealed = node.Value == std::string("true"); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kLastAccessTime) - { - vectorElement2.Properties.LastAccessedOn - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - else if ( - xmlPath.size() == 6 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kProperties - && xmlPath[5] == XmlTagEnum::kDeleteTime) - { - vectorElement2.Properties.DeleteTime - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - else if ( - xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob && xmlPath[4] == XmlTagEnum::kDeletionId) - { - vectorElement2.DeletionId = node.Value; - } - else if ( - xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kNextMarker) - { - response.NextMarker = node.Value; - } - } - else if (node.Type == _internal::XmlNodeType::Attribute) - { - if (xmlPath.size() == 1 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && node.Name == "ServiceEndpoint") - { - response.ServiceEndpoint = node.Value; - } - else if ( - xmlPath.size() == 1 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && node.Name == "ContainerName") - { - response.ContainerName = node.Value; - } - } - else if (node.Type == _internal::XmlNodeType::EndTag) - { - if (xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobPrefixes - && xmlPath[3] == XmlTagEnum::kBlobPrefix) - { - response.Segment.BlobPrefixes.push_back(std::move(vectorElement1)); - vectorElement1 = Models::BlobPrefix(); - } - else if ( - xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kSegment && xmlPath[2] == XmlTagEnum::kBlobItems - && xmlPath[3] == XmlTagEnum::kBlob) - { - response.Segment.BlobItems.push_back(std::move(vectorElement2)); - vectorElement2 = Models::BlobItemInternal(); - } - xmlPath.pop_back(); - } - } - } - return Response( - std::move(response), std::move(pRawResponse)); - } Response PathClient::Create( Core::Http::_internal::HttpPipeline& pipeline, const Core::Url& url, @@ -857,10 +274,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { request.SetHeader("x-ms-lease-duration", std::to_string(options.LeaseDuration.Value())); } - if (options.ExpiryOptions.HasValue() && !options.ExpiryOptions.Value().ToString().empty()) - { - request.SetHeader("x-ms-expiry-option", options.ExpiryOptions.Value().ToString()); - } if (options.ExpiresOn.HasValue() && !options.ExpiresOn.Value().empty()) { request.SetHeader("x-ms-expiry-time", options.ExpiresOn.Value()); @@ -1106,7 +519,11 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { throw StorageException::CreateFromResponse(std::move(pRawResponse)); } Models::UndeletePathResult response; - response.ResourceType = pRawResponse->GetHeaders().at("x-ms-resource-type"); + if (pRawResponse->GetHeaders().count("x-ms-resource-type") != 0) + { + response.ResourceType + = Models::PathResourceType(pRawResponse->GetHeaders().at("x-ms-resource-type")); + } return Response(std::move(response), std::move(pRawResponse)); } Response PathClient::GetAccessControlList( diff --git a/sdk/storage/azure-storage-files-datalake/swagger/README.md b/sdk/storage/azure-storage-files-datalake/swagger/README.md index 8bc9e92e05..d7a1f3babe 100644 --- a/sdk/storage/azure-storage-files-datalake/swagger/README.md +++ b/sdk/storage/azure-storage-files-datalake/swagger/README.md @@ -70,6 +70,7 @@ directive: delete $["/{filesystem}/{path}"].get; delete $["/{filesystem}/{path}"].patch; delete $["/{filesystem}/{path}?comp=expiry"]; + delete $["/{filesystem}?restype=container&comp=list&hierarchy"]; ``` ### API Version @@ -132,7 +133,6 @@ directive: where: $.parameters transform: > $.Continuation["x-ms-client-name"] = "ContinuationToken"; - $.ListBlobsInclude.items["x-ms-enum"]["name"] = "ListBlobsIncludeFlags"; $.EncryptionKeySha256["format"] = "byte"; - from: swagger-document where: $.definitions @@ -184,9 +184,8 @@ directive: $.Path.properties["contentLength"]["x-ms-client-name"] = "FileSize"; $.Path.properties["isDirectory"]["x-ms-client-default"] = false; $.Path.properties["EncryptionScope"]["x-nullable"] = true; - $.Path.properties["creationTime"]["x-ms-client-name"] = "CreatedOn"; - $.Path.properties["expiryTime"]["x-ms-client-name"] = "ExpiresOn"; - $.Path.properties["expiryTime"]["x-nullable"] = true; + delete $.Path.properties["creationTime"]; + delete $.Path.properties["expiryTime"]; $.Path.properties["etag"] = {"type": "string", "x-ms-format": "string", "x-ms-client-default": "", "x-ms-client-name": "ETag"}; delete $.Path.properties["eTag"]; $.PathList["x-namespace"] = "_detail"; @@ -200,10 +199,24 @@ directive: delete $["Last-Modified"]; ``` +### ListBlobsByHierarchy + +```yaml +directive: + - from: swagger-document + where: $.parameters + transform: > + $.ListBlobsInclude.items["x-ms-enum"]["name"] = "ListBlobsIncludeFlags"; +``` + ### CreatePath ```yaml directive: + - from: swagger-document + where: $["x-ms-paths"]["/{filesystem}/{path}"].put.parameters + transform: > + $ = $.filter(p => !(p["$ref"] && (p["$ref"].endsWith("#/parameters/PathExpiryOptionsOptional")))); - from: swagger-document where: $["x-ms-paths"]["/{filesystem}/{path}"].put.responses transform: > @@ -222,6 +235,18 @@ directive: }; ``` + +### SetExpiry + +```yaml +directive: + - from: swagger-document + where: $.parameters + transform: > + delete $["PathExpiryOptions"]; + delete $["PathExpiryOptionsOptional"]; +``` + ### DeletePath ```yaml @@ -267,6 +292,21 @@ directive: } ``` +### UndeletePath + +```yaml +directive: + - from: swagger-document + where: $["x-ms-paths"]["/{filesystem}/{path}?comp=undelete"].put.responses + transform: > + $["200"].headers["x-ms-resource-type"]["enum"] = ["directory", "file"]; + $["200"].headers["x-ms-resource-type"]["x-ms-enum"] = { + "name": "PathResourceType", + "modelAsString": false + }; + $["200"].headers["x-ms-resource-type"]["x-nullable"] = true; +``` + ### GetPathAccessControlList ```yaml From 96062ab91b0ec30633ece19a0454caca673c5fa3 Mon Sep 17 00:00:00 2001 From: Zhendong Chang Date: Wed, 14 Sep 2022 10:16:34 +0800 Subject: [PATCH 3/3] fix conversation --- .../storage/files/datalake/rest_client.hpp | 26 ++++---- .../src/rest_client.cpp | 10 +-- .../swagger/README.md | 62 ++++++++++++++----- 3 files changed, 64 insertions(+), 34 deletions(-) diff --git a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp index f64978c407..0a58b8e565 100644 --- a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp +++ b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp @@ -118,8 +118,8 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { }; } // namespace _detail /** - * @brief The type of the resource. The value may be "file" or "directory". If not set, the - * value is "file". + * @brief Required only for Create File and Create Directory. The value must be "file" or + * "directory". */ class PathResourceType final { public: @@ -234,19 +234,17 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { */ Nullable ContinuationToken; }; - } // namespace _detail - /** - * @brief Response type for #Azure::Storage::Files::DataLake::PathClient::Undelete. - */ - struct UndeletePathResult final - { /** - * The type of the resource. The value may be "file" or "directory". If not set, the value - * is "file". + * @brief Response type for #Azure::Storage::Files::DataLake::PathClient::Undelete. */ - Nullable ResourceType; - }; - namespace _detail { + struct UndeletePathResult final + { + /** + * The type of the resource. The value may be "file" or "directory". If not set, the value + * is "file". + */ + Nullable ResourceType; + }; /** * @brief Response type for * #Azure::Storage::Files::DataLake::PathClient::GetAccessControlList. @@ -440,7 +438,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { Nullable UndeleteSource; }; - static Response Undelete( + static Response Undelete( Core::Http::_internal::HttpPipeline& pipeline, const Core::Url& url, const UndeletePathOptions& options, diff --git a/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp b/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp index 94fef688cf..2d519a9487 100644 --- a/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp @@ -499,7 +499,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { return Response( std::move(response), std::move(pRawResponse)); } - Response PathClient::Undelete( + Response PathClient::Undelete( Core::Http::_internal::HttpPipeline& pipeline, const Core::Url& url, const UndeletePathOptions& options, @@ -518,13 +518,13 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { { throw StorageException::CreateFromResponse(std::move(pRawResponse)); } - Models::UndeletePathResult response; + Models::_detail::UndeletePathResult response; if (pRawResponse->GetHeaders().count("x-ms-resource-type") != 0) { - response.ResourceType - = Models::PathResourceType(pRawResponse->GetHeaders().at("x-ms-resource-type")); + response.ResourceType = pRawResponse->GetHeaders().at("x-ms-resource-type"); } - return Response(std::move(response), std::move(pRawResponse)); + return Response( + std::move(response), std::move(pRawResponse)); } Response PathClient::GetAccessControlList( Core::Http::_internal::HttpPipeline& pipeline, diff --git a/sdk/storage/azure-storage-files-datalake/swagger/README.md b/sdk/storage/azure-storage-files-datalake/swagger/README.md index d7a1f3babe..5344d267a8 100644 --- a/sdk/storage/azure-storage-files-datalake/swagger/README.md +++ b/sdk/storage/azure-storage-files-datalake/swagger/README.md @@ -117,6 +117,53 @@ directive: } ``` +### Return Type namespace + +```yaml +directive: + - from: swagger-document + where: $ + transform: > + const operations = [ + "Path_Undelete", + ]; + for (const url in $["x-ms-paths"]) { + for (const verb in $["x-ms-paths"][url]) { + if (!operations.includes($["x-ms-paths"][url][verb].operationId)) continue; + const operation = $["x-ms-paths"][url][verb]; + + const status_codes = Object.keys(operation.responses).filter(s => s !== "default"); + status_codes.forEach((status_code, i) => { + if (!operation.responses[status_code].schema) { + const operationId = operation.operationId; + const clientName = operationId.substr(0, operationId.indexOf("_")); + const operationName = operationId.substr(operationId.indexOf("_") + 1); + let operationWords = operationName.split(/(?=[A-Z])/); + operationWords.splice(1, 0, clientName); + const defaultReturnTypeName = operationWords.join("") + "Result"; + operation.responses[status_code].schema = { + "type": "object", + "x-ms-sealed": false, + "x-ms-client-name": defaultReturnTypeName, + "x-namespace": "_detail", + "properties": { + "__placeHolder": {"type": "integer"} + } + }; + } else if (operation.responses[status_code].schema["$ref"]) { + let obj = $; + for (const p of operation.responses[status_code].schema["$ref"].split("/").slice(1)) { + obj = obj[p]; + } + obj["x-namespace"] = "_detail"; + } else { + operation.responses[status_code].schema["x-namespace"] = "_detail"; + } + }); + } + } +``` + ### Global Changes for Definitions, Types etc. ```yaml @@ -199,16 +246,6 @@ directive: delete $["Last-Modified"]; ``` -### ListBlobsByHierarchy - -```yaml -directive: - - from: swagger-document - where: $.parameters - transform: > - $.ListBlobsInclude.items["x-ms-enum"]["name"] = "ListBlobsIncludeFlags"; -``` - ### CreatePath ```yaml @@ -299,11 +336,6 @@ directive: - from: swagger-document where: $["x-ms-paths"]["/{filesystem}/{path}?comp=undelete"].put.responses transform: > - $["200"].headers["x-ms-resource-type"]["enum"] = ["directory", "file"]; - $["200"].headers["x-ms-resource-type"]["x-ms-enum"] = { - "name": "PathResourceType", - "modelAsString": false - }; $["200"].headers["x-ms-resource-type"]["x-nullable"] = true; ```