diff --git a/sdk/storage/assets.json b/sdk/storage/assets.json index 2dbc595590..820a15d34e 100644 --- a/sdk/storage/assets.json +++ b/sdk/storage/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "cpp", "TagPrefix": "cpp/storage", - "Tag": "cpp/storage_0b9df101f1" + "Tag": "cpp/storage_a6149e4c39" } diff --git a/sdk/storage/azure-storage-common/CMakeLists.txt b/sdk/storage/azure-storage-common/CMakeLists.txt index d2e3d724e6..15fca9e297 100644 --- a/sdk/storage/azure-storage-common/CMakeLists.txt +++ b/sdk/storage/azure-storage-common/CMakeLists.txt @@ -57,6 +57,7 @@ set( inc/azure/storage/common/internal/storage_data_locality_policy.hpp inc/azure/storage/common/internal/storage_per_retry_policy.hpp inc/azure/storage/common/internal/storage_pipeline.hpp + inc/azure/storage/common/internal/storage_protocol.hpp inc/azure/storage/common/internal/storage_retry_policy.hpp inc/azure/storage/common/internal/storage_service_version_policy.hpp inc/azure/storage/common/internal/storage_switch_to_secondary_policy.hpp diff --git a/sdk/storage/azure-storage-common/inc/azure/storage/common/internal/storage_protocol.hpp b/sdk/storage/azure-storage-common/inc/azure/storage/common/internal/storage_protocol.hpp new file mode 100644 index 0000000000..d82114aa84 --- /dev/null +++ b/sdk/storage/azure-storage-common/inc/azure/storage/common/internal/storage_protocol.hpp @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#pragma once + +#include +#include + +#include + +namespace Azure { namespace Storage { namespace _internal { + + template + auto InvokeStorageProtocol(Operation&& operation) + -> decltype(std::forward(operation)()) + { + try + { + return std::forward(operation)(); + } + catch (StorageException const&) + { + throw; + } + catch (Core::RequestFailedException& error) + { + if (!error.RawResponse) + { + throw; + } + throw StorageException::CreateFromResponse(std::move(error.RawResponse)); + } + } + +}}} // namespace Azure::Storage::_internal diff --git a/sdk/storage/azure-storage-queues/CMakeLists.txt b/sdk/storage/azure-storage-queues/CMakeLists.txt index 7f018f19dc..69b1ee1565 100644 --- a/sdk/storage/azure-storage-queues/CMakeLists.txt +++ b/sdk/storage/azure-storage-queues/CMakeLists.txt @@ -48,19 +48,23 @@ set( inc/azure/storage/queues/queue_responses.hpp inc/azure/storage/queues/queue_sas_builder.hpp inc/azure/storage/queues/queue_service_client.hpp - inc/azure/storage/queues/rest_client.hpp inc/azure/storage/queues/rtti.hpp ) set( AZURE_STORAGE_QUEUES_SOURCE src/private/package_version.hpp + src/private/queue_model_conversions.hpp + src/generated/queues_client.hpp + src/generated/queues_client_options.hpp + src/generated/queues_models.hpp + src/generated/queues_client.cpp + src/generated/queues.cpp src/queue_client.cpp src/queue_options.cpp src/queue_responses.cpp src/queue_sas_builder.cpp src/queue_service_client.cpp - src/rest_client.cpp ) add_library(azure-storage-queues ${AZURE_STORAGE_QUEUES_HEADER} ${AZURE_STORAGE_QUEUES_SOURCE}) diff --git a/sdk/storage/azure-storage-queues/cspell.json b/sdk/storage/azure-storage-queues/cspell.json new file mode 100644 index 0000000000..bf89651b12 --- /dev/null +++ b/sdk/storage/azure-storage-queues/cspell.json @@ -0,0 +1,12 @@ +{ + "version": "0.2", + "language": "en", + "languageId": "cpp", + "dictionaries": [ + "powershell", + "cpp" + ], + "words": [ + "numofmessages" + ] +} diff --git a/sdk/storage/azure-storage-queues/inc/azure/storage/queues.hpp b/sdk/storage/azure-storage-queues/inc/azure/storage/queues.hpp index a88551d86f..5771be1fdf 100644 --- a/sdk/storage/azure-storage-queues/inc/azure/storage/queues.hpp +++ b/sdk/storage/azure-storage-queues/inc/azure/storage/queues.hpp @@ -14,7 +14,6 @@ #include "azure/storage/queues/queue_responses.hpp" #include "azure/storage/queues/queue_sas_builder.hpp" #include "azure/storage/queues/queue_service_client.hpp" -#include "azure/storage/queues/rest_client.hpp" #include "azure/storage/queues/rtti.hpp" #include diff --git a/sdk/storage/azure-storage-queues/inc/azure/storage/queues/queue_client.hpp b/sdk/storage/azure-storage-queues/inc/azure/storage/queues/queue_client.hpp index 64d173a5ac..35a9ef888b 100644 --- a/sdk/storage/azure-storage-queues/inc/azure/storage/queues/queue_client.hpp +++ b/sdk/storage/azure-storage-queues/inc/azure/storage/queues/queue_client.hpp @@ -11,7 +11,11 @@ #include "azure/storage/queues/queue_options.hpp" #include "azure/storage/queues/queue_responses.hpp" +#include #include +#include +#include +#include #include #include diff --git a/sdk/storage/azure-storage-queues/inc/azure/storage/queues/queue_options.hpp b/sdk/storage/azure-storage-queues/inc/azure/storage/queues/queue_options.hpp index 3a10cf22fc..dbdd1f6c73 100644 --- a/sdk/storage/azure-storage-queues/inc/azure/storage/queues/queue_options.hpp +++ b/sdk/storage/azure-storage-queues/inc/azure/storage/queues/queue_options.hpp @@ -8,17 +8,85 @@ #pragma once -#include "azure/storage/queues/rest_client.hpp" +#include "azure/storage/queues/dll_import_export.hpp" +#include #include #include #include #include +#include #include +#include +#include namespace Azure { namespace Storage { namespace Queues { + namespace Models { + /** + * @brief Include this parameter to specify that the queues' metadata be returned as part of the + * response body. + */ + enum class ListQueuesIncludeFlags + { + None = 0, + Metadata = 1, + }; + /** + * @brief Combines the flags from both operands. + * @param lhs The left operand. + * @param rhs The right operand. + * @return The combined flags. + */ + inline ListQueuesIncludeFlags operator|(ListQueuesIncludeFlags lhs, ListQueuesIncludeFlags rhs) + { + using type = std::underlying_type_t; + return static_cast(static_cast(lhs) | static_cast(rhs)); + } + /** + * @brief Adds the right operand's flags to the left operand. + * @param lhs The flags to update. + * @param rhs The flags to add. + * @return A reference to the updated left operand. + */ + inline ListQueuesIncludeFlags& operator|=( + ListQueuesIncludeFlags& lhs, + ListQueuesIncludeFlags rhs) + { + lhs = lhs | rhs; + return lhs; + } + /** + * @brief Selects the flags present in both operands. + * @param lhs The left operand. + * @param rhs The right operand. + * @return The flags present in both operands. + */ + inline ListQueuesIncludeFlags operator&(ListQueuesIncludeFlags lhs, ListQueuesIncludeFlags rhs) + { + using type = std::underlying_type_t; + return static_cast(static_cast(lhs) & static_cast(rhs)); + } + /** + * @brief Retains only the right operand's flags in the left operand. + * @param lhs The flags to update. + * @param rhs The flags to retain. + * @return A reference to the updated left operand. + */ + inline ListQueuesIncludeFlags& operator&=( + ListQueuesIncludeFlags& lhs, + ListQueuesIncludeFlags rhs) + { + lhs = lhs & rhs; + return lhs; + } + } // namespace Models + + namespace _detail { + constexpr static const char* ApiVersion = "2026-04-06"; + } // namespace _detail + /** * @brief Audiences available for queue service * @@ -145,37 +213,6 @@ namespace Azure { namespace Storage { namespace Queues { Azure::Nullable Audience; }; - /** - * Optional parameters for #Azure::Storage::Queues::QueueServiceClient::ListQueues. - */ - struct ListQueuesOptions final - { - /** - * @brief Specifies a string that filters the results to return only queues whose name begins - * with the specified prefix. - */ - Azure::Nullable Prefix; - - /** - * @brief A string value that identifies the portion of the list of queues to be returned with - * the next listing operation. The operation returns a non-empty continuation token if the - * listing operation did not return all queues remaining to be listed with the current segment. - * The ContinuationToken value can be used as the value for the ContinuationToken parameter in a - * subsequent call to request the next segment of list items. - */ - Azure::Nullable ContinuationToken; - - /** - * @brief Specifies the maximum number of queues to return. - */ - Azure::Nullable PageSizeHint; - - /** - * @brief Specifies that the queue's metadata be returned. - */ - Models::ListQueuesIncludeFlags Include = Models::ListQueuesIncludeFlags::None; - }; - /** * Optional parameters for #Azure::Storage::Queues::QueueServiceClient::SetProperties. */ @@ -215,6 +252,37 @@ namespace Azure { namespace Storage { namespace Queues { Nullable DelegatedUserTid; }; + /** + * Optional parameters for #Azure::Storage::Queues::QueueServiceClient::ListQueues. + */ + struct ListQueuesOptions final + { + /** + * @brief Specifies a string that filters the results to return only queues whose name begins + * with the specified prefix. + */ + Azure::Nullable Prefix; + + /** + * @brief A string value that identifies the portion of the list of queues to be returned with + * the next listing operation. The operation returns a non-empty continuation token if the + * listing operation did not return all queues remaining to be listed with the current segment. + * The ContinuationToken value can be used as the value for the ContinuationToken parameter in a + * subsequent call to request the next segment of list items. + */ + Azure::Nullable ContinuationToken; + + /** + * @brief Specifies the maximum number of queues to return. + */ + Azure::Nullable PageSizeHint; + + /** + * @brief Specifies that the queue's metadata be returned. + */ + Models::ListQueuesIncludeFlags Include = Models::ListQueuesIncludeFlags::None; + }; + /** * Optional parameters for #Azure::Storage::Queues::QueueClient::Create. */ diff --git a/sdk/storage/azure-storage-queues/inc/azure/storage/queues/queue_responses.hpp b/sdk/storage/azure-storage-queues/inc/azure/storage/queues/queue_responses.hpp index 31cb3f260b..0a925ff409 100644 --- a/sdk/storage/azure-storage-queues/inc/azure/storage/queues/queue_responses.hpp +++ b/sdk/storage/azure-storage-queues/inc/azure/storage/queues/queue_responses.hpp @@ -2,25 +2,451 @@ // Licensed under the MIT License. /** * @file - * @brief Defines Queue operation responses. - * + * @brief Defines Queue service models and operation results. */ #pragma once #include "azure/storage/queues/queue_options.hpp" -#include "azure/storage/queues/rest_client.hpp" +#include +#include +#include +#include #include +#include +#include #include #include +#include +#include namespace Azure { namespace Storage { namespace Queues { - - class QueueServiceClient; - namespace Models { + /** + * @brief The retention policy. + */ + struct RetentionPolicy final + { + /** + * Indicates whether a retention policy is enabled for the storage service. + */ + bool IsEnabled = false; + /** + * Indicates the number of days that metrics or logging or soft-deleted data should be + * retained. All data older than this value will be deleted. + */ + Nullable Days; + }; + /** + * @brief Azure Analytics Logging settings. + */ + struct AnalyticsLogging final + { + /** + * The version of Storage Analytics to configure. + */ + std::string Version; + /** + * Indicates whether all delete requests should be logged. + */ + bool Delete = false; + /** + * Indicates whether all read requests should be logged. + */ + bool Read = false; + /** + * Indicates whether all write requests should be logged. + */ + bool Write = false; + /** + * The retention policy. + */ + Models::RetentionPolicy RetentionPolicy; + }; + /** + * @brief A summary of request statistics grouped by API in hour or minute aggregates for + * queues. + */ + struct Metrics final + { + /** + * The version of Storage Analytics to configure. + */ + std::string Version; + /** + * Indicates whether metrics are enabled for the Queue service. + */ + bool IsEnabled = false; + /** + * Indicates whether metrics should generate summary statistics for called API operations. + */ + Nullable IncludeApis; + /** + * The retention policy. + */ + Models::RetentionPolicy RetentionPolicy; + }; + /** + * @brief CORS is an HTTP feature that enables a web application running under one domain to + * access resources in another domain. Web browsers implement a security restriction known as + * same-origin policy that prevents a web page from calling APIs in a different domain; CORS + * provides a secure way to allow one domain (the origin domain) to call APIs in another domain. + */ + struct CorsRule final + { + /** + * The origin domains that are permitted to make a request against the storage service via + * CORS. The origin domain is the domain from which the request originates. Note that the + * origin must be an exact case-sensitive match with the origin that the user age sends to the + * service. You can also use the wildcard character '*' to allow all origin domains to make + * requests via CORS. + */ + std::string AllowedOrigins; + /** + * The methods (HTTP request verbs) that the origin domain may use for a CORS request. (comma + * separated). + */ + std::string AllowedMethods; + /** + * The request headers that the origin domain may specify on the CORS request. + */ + std::string AllowedHeaders; + /** + * The response headers that may be sent in the response to the CORS request and exposed by + * the browser to the request issuer. + */ + std::string ExposedHeaders; + /** + * The maximum amount time that a browser should cache the preflight OPTIONS request. + */ + std::int32_t MaxAgeInSeconds = std::int32_t(); + }; + /** + * @brief Response type for #Azure::Storage::Queues::QueueServiceClient::SetProperties. + */ + struct SetServicePropertiesResult final + { + }; + /** + * @brief Storage Service Properties. + */ + struct QueueServiceProperties final + { + /** + * Azure Analytics Logging settings. + */ + AnalyticsLogging Logging; + /** + * A summary of request statistics grouped by API in hourly aggregates for queues. + */ + Metrics HourMetrics; + /** + * A summary of request statistics grouped by API in minute aggregates for queues. + */ + Metrics MinuteMetrics; + /** + * The set of CORS rules. + */ + std::vector Cors; + }; + /** + * @brief The status of the secondary location. + */ + class GeoReplicationStatus final + : public Core::_internal::ExtendableEnumeration { + public: + /** Constructs a new GeoReplicationStatus instance */ + GeoReplicationStatus() = default; + /** Constructs a new GeoReplicationStatus from a string. */ + explicit GeoReplicationStatus(std::string value) : ExtendableEnumeration(std::move(value)) {} + + /** Constant value of type GeoReplicationStatus: Live */ + AZ_STORAGE_QUEUES_DLLEXPORT const static GeoReplicationStatus Live; + /** Constant value of type GeoReplicationStatus: Bootstrap */ + AZ_STORAGE_QUEUES_DLLEXPORT const static GeoReplicationStatus Bootstrap; + /** Constant value of type GeoReplicationStatus: Unavailable */ + AZ_STORAGE_QUEUES_DLLEXPORT const static GeoReplicationStatus Unavailable; + }; + /** + * @brief Geo-Replication information for the Secondary Storage Service. + */ + struct GeoReplication final + { + /** + * The status of the secondary location. + */ + GeoReplicationStatus Status; + /** + * A GMT date/time value, to the second. All primary writes preceding this value are + * guaranteed to be available for read operations at the secondary. Primary writes after this + * point in time may or may not be available for reads. + */ + Nullable LastSyncedOn; + }; + /** + * @brief Stats for the storage service. + */ + struct ServiceStatistics final + { + /** + * Geo-Replication information for the Secondary Storage Service. + */ + Models::GeoReplication GeoReplication; + }; + /** + * @brief A user delegation key. + */ + struct UserDelegationKey final + { + /** + * The Azure Active Directory object ID in GUID format. + */ + std::string SignedObjectId; + /** + * The Azure Active Directory tenant ID in GUID format. + */ + std::string SignedTenantId; + /** + * The date-time the key is active. + */ + DateTime SignedStartsOn; + /** + * The date-time the key expires. + */ + DateTime SignedExpiresOn; + /** + * Abbreviation of the Azure Storage service that accepts the key. + */ + std::string SignedService; + /** + * The service version that created the key. + */ + std::string SignedVersion; + /** + * The delegated user tenant id in Azure AD. Return if DelegatedUserTid is specified. + */ + Nullable SignedDelegatedUserTid; + /** + * The key as a base64 string. + */ + std::string Value; + }; + /** + * @brief An Azure Storage Queue. + */ + struct QueueItem final + { + /** + * The name of the Queue. + */ + std::string Name; + /** + * A set of name-value pairs associated with this queue. + */ + Core::CaseInsensitiveMap Metadata; + }; + /** + * @brief Response type for #Azure::Storage::Queues::QueueClient::Create. + */ + struct CreateQueueResult final + { + /** + * Indicates if the queue was successfully created by this operation. + */ + bool Created = false; + }; + /** + * @brief Response type for #Azure::Storage::Queues::QueueClient::Delete. + */ + struct DeleteQueueResult final + { + /** + * Indicates if the queue was successfully deleted by this operation. + */ + bool Deleted = true; + }; + /** + * @brief Response type for #Azure::Storage::Queues::QueueClient::SetMetadata. + */ + struct SetQueueMetadataResult final + { + }; + /** + * @brief Signed identifier. + */ + struct SignedIdentifier final + { + /** + * A unique id. + */ + std::string Id; + /** + * The date-time the policy is active. + */ + Nullable StartsOn; + /** + * The date-time the policy expires. + */ + Nullable ExpiresOn; + /** + * The permissions for the acl policy. + */ + std::string Permissions; + }; + /** + * @brief Response type for #Azure::Storage::Queues::QueueClient::GetAccessPolicy. + */ + struct QueueAccessPolicy final + { + /** + * A collection of signed identifiers. + */ + std::vector SignedIdentifiers; + }; + /** + * @brief Response type for #Azure::Storage::Queues::QueueClient::SetAccessPolicy. + */ + struct SetQueueAccessPolicyResult final + { + }; + /** + * @brief The object returned in the QueueMessageList array when calling Get Messages on a + * Queue. + */ + struct QueueMessage final + { + /** + * The Id of the Message. + */ + std::string MessageId; + /** + * The time the Message was inserted into the Queue. + */ + DateTime InsertedOn; + /** + * The time that the Message will expire and be automatically deleted. + */ + DateTime ExpiresOn; + /** + * This value is required to delete the Message. If deletion fails using this popreceipt then + * the message has been dequeued by another client. + */ + std::string PopReceipt; + /** + * The time that the message will again become visible in the Queue. + */ + DateTime NextVisibleOn; + /** + * The number of times the message has been dequeued. + */ + std::int64_t DequeueCount = std::int64_t(); + /** + * The content of the Message. + */ + std::string MessageText; + }; + /** + * @brief Response type for #Azure::Storage::Queues::QueueClient::ReceiveMessages. + */ + struct ReceivedMessages final + { + /** + * The object returned when calling Get Messages on a Queue. + */ + std::vector Messages; + }; + /** + * @brief Response type for #Azure::Storage::Queues::QueueClient::ClearMessages. + */ + struct ClearMessagesResult final + { + }; + /** + * @brief The object returned in the QueueMessageList array when calling Put Message on a Queue. + */ + struct EnqueueMessageResult final + { + /** + * The Id of the Message. + */ + std::string MessageId; + /** + * The time the Message was inserted into the Queue. + */ + DateTime InsertedOn; + /** + * The time that the Message will expire and be automatically deleted. + */ + DateTime ExpiresOn; + /** + * This value is required to delete the Message. If deletion fails using this popreceipt then + * the message has been dequeued by another client. + */ + std::string PopReceipt; + /** + * The time that the message will again become visible in the Queue. + */ + DateTime NextVisibleOn; + }; + /** + * @brief The object returned in the QueueMessageList array when calling Peek Messages on a + * Queue. + */ + struct PeekedQueueMessage final + { + /** + * The Id of the Message. + */ + std::string MessageId; + /** + * The time the Message was inserted into the Queue. + */ + DateTime InsertedOn; + /** + * The time that the Message will expire and be automatically deleted. + */ + DateTime ExpiresOn; + /** + * The number of times the message has been dequeued. + */ + std::int64_t DequeueCount = std::int64_t(); + /** + * The content of the Message. + */ + std::string MessageText; + }; + /** + * @brief Response type for #Azure::Storage::Queues::QueueClient::PeekMessages. + */ + struct PeekedMessages final + { + /** + * The object returned when calling Peek Messages on a Queue. + */ + std::vector Messages; + }; + /** + * @brief Response type for #Azure::Storage::Queues::QueueClient::DeleteMessage. + */ + struct DeleteMessageResult final + { + }; + /** + * @brief Response type for #Azure::Storage::Queues::QueueClient::UpdateMessage. + */ + struct UpdateMessageResult final + { + /** + * The pop receipt of the queue message. + */ + std::string PopReceipt; + /** + * A UTC date/time value that represents when the message will be visible on the queue. + */ + DateTime NextVisibleOn; + }; /** * @brief Response type for #Azure::Storage::Queues::QueueClient::GetProperties. */ @@ -46,6 +472,8 @@ namespace Azure { namespace Storage { namespace Queues { }; } // namespace Models + class QueueServiceClient; + /** * @brief Response type for #Azure::Storage::Queues::QueueServiceClient::ListQueues. */ diff --git a/sdk/storage/azure-storage-queues/inc/azure/storage/queues/rest_client.hpp b/sdk/storage/azure-storage-queues/inc/azure/storage/queues/rest_client.hpp deleted file mode 100644 index 8f4fd815d5..0000000000 --- a/sdk/storage/azure-storage-queues/inc/azure/storage/queues/rest_client.hpp +++ /dev/null @@ -1,727 +0,0 @@ - -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -// -// Code generated by Microsoft (R) AutoRest C++ Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace Azure { namespace Storage { namespace Queues { - namespace _detail { - /** - * The version used for the operations to Azure storage services. - */ - constexpr static const char* ApiVersion = "2026-04-06"; - } // namespace _detail - namespace Models { - /** - * @brief The retention policy. - */ - struct RetentionPolicy final - { - /** - * Indicates whether a retention policy is enabled for the storage service. - */ - bool IsEnabled = bool(); - /** - * Indicates the number of days that metrics or logging or soft-deleted data should be - * retained. All data older than this value will be deleted. - */ - Nullable Days; - }; - /** - * @brief Azure Analytics Logging settings. - */ - struct AnalyticsLogging final - { - /** - * The version of Storage Analytics to configure. - */ - std::string Version; - /** - * Indicates whether all delete requests should be logged. - */ - bool Delete = bool(); - /** - * Indicates whether all read requests should be logged. - */ - bool Read = bool(); - /** - * Indicates whether all write requests should be logged. - */ - bool Write = bool(); - /** - * The retention policy. - */ - Models::RetentionPolicy RetentionPolicy; - }; - /** - * @brief A summary of request statistics grouped by API in hour or minute aggregates for - * queues. - */ - struct Metrics final - { - /** - * The version of Storage Analytics to configure. - */ - std::string Version; - /** - * Indicates whether metrics are enabled for the Queue service. - */ - bool IsEnabled = bool(); - /** - * Indicates whether metrics should generate summary statistics for called API operations. - */ - Nullable IncludeApis; - /** - * The retention policy. - */ - Models::RetentionPolicy RetentionPolicy; - }; - /** - * @brief CORS is an HTTP feature that enables a web application running under one domain to - * access resources in another domain. Web browsers implement a security restriction known as - * same-origin policy that prevents a web page from calling APIs in a different domain; CORS - * provides a secure way to allow one domain (the origin domain) to call APIs in another domain. - */ - struct CorsRule final - { - /** - * The origin domains that are permitted to make a request against the storage service via - * CORS. The origin domain is the domain from which the request originates. Note that the - * origin must be an exact case-sensitive match with the origin that the user age sends to the - * service. You can also use the wildcard character '*' to allow all origin domains to make - * requests via CORS. - */ - std::string AllowedOrigins; - /** - * The methods (HTTP request verbs) that the origin domain may use for a CORS request. (comma - * separated). - */ - std::string AllowedMethods; - /** - * The request headers that the origin domain may specify on the CORS request. - */ - std::string AllowedHeaders; - /** - * The response headers that may be sent in the response to the CORS request and exposed by - * the browser to the request issuer. - */ - std::string ExposedHeaders; - /** - * The maximum amount time that a browser should cache the preflight OPTIONS request. - */ - std::int32_t MaxAgeInSeconds = std::int32_t(); - }; - /** - * @brief Response type for #Azure::Storage::Queues::QueueServiceClient::SetProperties. - */ - struct SetServicePropertiesResult final - { - }; - /** - * @brief Storage Service Properties. - */ - struct QueueServiceProperties final - { - /** - * Azure Analytics Logging settings. - */ - AnalyticsLogging Logging; - /** - * A summary of request statistics grouped by API in hourly aggregates for queues. - */ - Metrics HourMetrics; - /** - * A summary of request statistics grouped by API in minute aggregates for queues. - */ - Metrics MinuteMetrics; - /** - * The set of CORS rules. - */ - std::vector Cors; - }; - /** - * @brief The status of the secondary location. - */ - class GeoReplicationStatus final - : public Core::_internal::ExtendableEnumeration { - public: - /** Constructs a new GeoReplicationStatus instance */ - GeoReplicationStatus() = default; - /** Constructs a new GeoReplicationStatus from a string. */ - explicit GeoReplicationStatus(std::string value) : ExtendableEnumeration(std::move(value)) {} - - /** Constant value of type GeoReplicationStatus: Live */ - AZ_STORAGE_QUEUES_DLLEXPORT const static GeoReplicationStatus Live; - /** Constant value of type GeoReplicationStatus: Bootstrap */ - AZ_STORAGE_QUEUES_DLLEXPORT const static GeoReplicationStatus Bootstrap; - /** Constant value of type GeoReplicationStatus: Unavailable */ - AZ_STORAGE_QUEUES_DLLEXPORT const static GeoReplicationStatus Unavailable; - }; - /** - * @brief Geo-Replication information for the Secondary Storage Service. - */ - struct GeoReplication final - { - /** - * The status of the secondary location. - */ - GeoReplicationStatus Status; - /** - * A GMT date/time value, to the second. All primary writes preceding this value are - * guaranteed to be available for read operations at the secondary. Primary writes after this - * point in time may or may not be available for reads. - */ - Nullable LastSyncedOn; - }; - /** - * @brief Stats for the storage service. - */ - struct ServiceStatistics final - { - /** - * Geo-Replication information for the Secondary Storage Service. - */ - Models::GeoReplication GeoReplication; - }; - namespace _detail { - /** - * @brief Key information. - */ - struct KeyInfo final - { - /** - * The date-time the key is active in ISO 8601 UTC time. - */ - Nullable Start; - /** - * The date-time the key expires in ISO 8601 UTC time. - */ - std::string Expiry; - /** - * The delegated user tenant id in Azure AD. - */ - Nullable DelegatedUserTid; - }; - } // namespace _detail - /** - * @brief A user delegation key. - */ - struct UserDelegationKey final - { - /** - * The Azure Active Directory object ID in GUID format. - */ - std::string SignedObjectId; - /** - * The Azure Active Directory tenant ID in GUID format. - */ - std::string SignedTenantId; - /** - * The date-time the key is active. - */ - DateTime SignedStartsOn; - /** - * The date-time the key expires. - */ - DateTime SignedExpiresOn; - /** - * Abbreviation of the Azure Storage service that accepts the key. - */ - std::string SignedService; - /** - * The service version that created the key. - */ - std::string SignedVersion; - /** - * The delegated user tenant id in Azure AD. Return if DelegatedUserTid is specified. - */ - Nullable SignedDelegatedUserTid; - /** - * The key as a base64 string. - */ - std::string Value; - }; - /** - * @brief An Azure Storage Queue. - */ - struct QueueItem final - { - /** - * The name of the Queue. - */ - std::string Name; - /** - * A set of name-value pairs associated with this queue. - */ - Core::CaseInsensitiveMap Metadata; - }; - /** - * @brief Include this parameter to specify that the queues' metadata be returned as part of the - * response body. - */ - enum class ListQueuesIncludeFlags - { - None = 0, - Metadata = 1, - }; - inline ListQueuesIncludeFlags operator|(ListQueuesIncludeFlags lhs, ListQueuesIncludeFlags rhs) - { - using type = std::underlying_type_t; - return static_cast(static_cast(lhs) | static_cast(rhs)); - } - inline ListQueuesIncludeFlags& operator|=( - ListQueuesIncludeFlags& lhs, - ListQueuesIncludeFlags rhs) - { - lhs = lhs | rhs; - return lhs; - } - inline ListQueuesIncludeFlags operator&(ListQueuesIncludeFlags lhs, ListQueuesIncludeFlags rhs) - { - using type = std::underlying_type_t; - return static_cast(static_cast(lhs) & static_cast(rhs)); - } - inline ListQueuesIncludeFlags& operator&=( - ListQueuesIncludeFlags& lhs, - ListQueuesIncludeFlags rhs) - { - lhs = lhs & rhs; - return lhs; - } - namespace _detail { - /** - * @brief The object returned when calling List Queues on a Queue Service. - */ - struct ListQueuesResult final - { - std::string ServiceEndpoint; - std::string Prefix; - /** - * Array of QueueItem. - */ - std::vector Items; - Nullable ContinuationToken; - }; - } // namespace _detail - /** - * @brief Response type for #Azure::Storage::Queues::QueueClient::Create. - */ - struct CreateQueueResult final - { - /** - * Indicates if the queue was successfully created by this operation. - */ - bool Created = bool(); - }; - /** - * @brief Response type for #Azure::Storage::Queues::QueueClient::Delete. - */ - struct DeleteQueueResult final - { - /** - * Indicates if the queue was successfully deleted by this operation. - */ - bool Deleted = true; - }; - namespace _detail { - /** - * @brief Response type for #Azure::Storage::Queues::QueueClient::GetProperties. - */ - struct QueueProperties final - { - /** - * A set of name-value pairs associated with this queue. - */ - Core::CaseInsensitiveMap Metadata; - /** - * The approximate number of messages in the queue. This number is not lower than the actual - * number of messages in the queue, but could be higher. - */ - std::int64_t ApproximateMessageCount = std::int64_t(); - }; - } // namespace _detail - /** - * @brief Response type for #Azure::Storage::Queues::QueueClient::SetMetadata. - */ - struct SetQueueMetadataResult final - { - }; - /** - * @brief Signed identifier. - */ - struct SignedIdentifier final - { - /** - * A unique id. - */ - std::string Id; - /** - * The date-time the policy is active. - */ - Nullable StartsOn; - /** - * The date-time the policy expires. - */ - Nullable ExpiresOn; - /** - * The permissions for the acl policy. - */ - std::string Permissions; - }; - /** - * @brief Response type for #Azure::Storage::Queues::QueueClient::GetAccessPolicy. - */ - struct QueueAccessPolicy final - { - /** - * A collection of signed identifiers. - */ - std::vector SignedIdentifiers; - }; - /** - * @brief Response type for #Azure::Storage::Queues::QueueClient::SetAccessPolicy. - */ - struct SetQueueAccessPolicyResult final - { - }; - /** - * @brief The object returned in the QueueMessageList array when calling Get Messages on a - * Queue. - */ - struct QueueMessage final - { - /** - * The Id of the Message. - */ - std::string MessageId; - /** - * The time the Message was inserted into the Queue. - */ - DateTime InsertedOn; - /** - * The time that the Message will expire and be automatically deleted. - */ - DateTime ExpiresOn; - /** - * This value is required to delete the Message. If deletion fails using this popreceipt then - * the message has been dequeued by another client. - */ - std::string PopReceipt; - /** - * The time that the message will again become visible in the Queue. - */ - DateTime NextVisibleOn; - /** - * The number of times the message has been dequeued. - */ - std::int64_t DequeueCount = std::int64_t(); - /** - * The content of the Message. - */ - std::string MessageText; - }; - /** - * @brief Response type for #Azure::Storage::Queues::QueueClient::ReceiveMessages. - */ - struct ReceivedMessages final - { - /** - * The object returned when calling Get Messages on a Queue. - */ - std::vector Messages; - }; - /** - * @brief Response type for #Azure::Storage::Queues::QueueClient::ClearMessages. - */ - struct ClearMessagesResult final - { - }; - namespace _detail { - /** - * @brief A Message object which can be stored in a Queue. - */ - struct QueueMessageInternal final - { - /** - * The content of the message. - */ - std::string MessageText; - }; - } // namespace _detail - /** - * @brief The object returned in the QueueMessageList array when calling Put Message on a Queue. - */ - struct EnqueueMessageResult final - { - /** - * The Id of the Message. - */ - std::string MessageId; - /** - * The time the Message was inserted into the Queue. - */ - DateTime InsertedOn; - /** - * The time that the Message will expire and be automatically deleted. - */ - DateTime ExpiresOn; - /** - * This value is required to delete the Message. If deletion fails using this popreceipt then - * the message has been dequeued by another client. - */ - std::string PopReceipt; - /** - * The time that the message will again become visible in the Queue. - */ - DateTime NextVisibleOn; - }; - /** - * @brief The object returned in the QueueMessageList array when calling Peek Messages on a - * Queue. - */ - struct PeekedQueueMessage final - { - /** - * The Id of the Message. - */ - std::string MessageId; - /** - * The time the Message was inserted into the Queue. - */ - DateTime InsertedOn; - /** - * The time that the Message will expire and be automatically deleted. - */ - DateTime ExpiresOn; - /** - * The number of times the message has been dequeued. - */ - std::int64_t DequeueCount = std::int64_t(); - /** - * The content of the Message. - */ - std::string MessageText; - }; - /** - * @brief Response type for #Azure::Storage::Queues::QueueClient::PeekMessages. - */ - struct PeekedMessages final - { - /** - * The object returned when calling Peek Messages on a Queue. - */ - std::vector Messages; - }; - /** - * @brief Response type for #Azure::Storage::Queues::QueueClient::DeleteMessage. - */ - struct DeleteMessageResult final - { - }; - /** - * @brief Response type for #Azure::Storage::Queues::QueueClient::UpdateMessage. - */ - struct UpdateMessageResult final - { - /** - * The pop receipt of the queue message. - */ - std::string PopReceipt; - /** - * A UTC date/time value that represents when the message will be visible on the queue. - */ - DateTime NextVisibleOn; - }; - } // namespace Models - namespace _detail { - class ServiceClient final { - public: - struct SetServicePropertiesOptions final - { - Models::QueueServiceProperties QueueServiceProperties; - }; - static Response SetProperties( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const SetServicePropertiesOptions& options, - const Core::Context& context); - struct GetServicePropertiesOptions final - { - }; - static Response GetProperties( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const GetServicePropertiesOptions& options, - const Core::Context& context); - struct GetServiceStatisticsOptions final - { - }; - static Response GetStatistics( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const GetServiceStatisticsOptions& options, - const Core::Context& context); - struct GetServiceUserDelegationKeyOptions final - { - Models::_detail::KeyInfo KeyInfo; - }; - static Response GetUserDelegationKey( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const GetServiceUserDelegationKeyOptions& options, - const Core::Context& context); - struct ListServiceQueuesSegmentOptions final - { - Nullable Prefix; - Nullable Marker; - Nullable MaxResults; - Nullable Include; - }; - static Response ListQueuesSegment( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const ListServiceQueuesSegmentOptions& options, - const Core::Context& context); - }; - class QueueClient final { - public: - struct CreateQueueOptions final - { - std::map Metadata; - }; - static Response Create( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const CreateQueueOptions& options, - const Core::Context& context); - struct DeleteQueueOptions final - { - }; - static Response Delete( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const DeleteQueueOptions& options, - const Core::Context& context); - struct GetQueuePropertiesOptions final - { - }; - static Response GetProperties( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const GetQueuePropertiesOptions& options, - const Core::Context& context); - struct SetQueueMetadataOptions final - { - std::map Metadata; - }; - static Response SetMetadata( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const SetQueueMetadataOptions& options, - const Core::Context& context); - struct GetQueueAccessPolicyOptions final - { - }; - static Response GetAccessPolicy( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const GetQueueAccessPolicyOptions& options, - const Core::Context& context); - struct SetQueueAccessPolicyOptions final - { - std::vector QueueAcl; - }; - static Response SetAccessPolicy( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const SetQueueAccessPolicyOptions& options, - const Core::Context& context); - struct ReceiveQueueMessagesOptions final - { - Nullable NumberOfMessages; - Nullable Visibilitytimeout; - }; - static Response ReceiveMessages( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const ReceiveQueueMessagesOptions& options, - const Core::Context& context); - struct ClearQueueMessagesOptions final - { - }; - static Response ClearMessages( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const ClearQueueMessagesOptions& options, - const Core::Context& context); - struct EnqueueQueueMessageOptions final - { - Models::_detail::QueueMessageInternal QueueMessage; - Nullable Visibilitytimeout; - Nullable MessageTimeToLive; - }; - static Response EnqueueMessage( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const EnqueueQueueMessageOptions& options, - const Core::Context& context); - struct PeekQueueMessagesOptions final - { - Nullable NumberOfMessages; - }; - static Response PeekMessages( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const PeekQueueMessagesOptions& options, - const Core::Context& context); - struct UpdateQueueMessageOptions final - { - Models::_detail::QueueMessageInternal QueueMessage; - std::string PopReceipt; - std::int32_t Visibilitytimeout = std::int32_t(); - }; - static Response UpdateMessage( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const UpdateQueueMessageOptions& options, - const Core::Context& context); - struct DeleteQueueMessageOptions final - { - std::string PopReceipt; - }; - static Response DeleteMessage( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const DeleteQueueMessageOptions& options, - const Core::Context& context); - struct UpdateQueueMessageVisibilityOptions final - { - std::string PopReceipt; - std::int32_t Visibilitytimeout = std::int32_t(); - }; - static Response UpdateMessageVisibility( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const UpdateQueueMessageVisibilityOptions& options, - const Core::Context& context); - }; - } // namespace _detail -}}} // namespace Azure::Storage::Queues \ No newline at end of file diff --git a/sdk/storage/azure-storage-queues/src/generated/queues.cpp b/sdk/storage/azure-storage-queues/src/generated/queues.cpp new file mode 100644 index 0000000000..feb5a1ecd2 --- /dev/null +++ b/sdk/storage/azure-storage-queues/src/generated/queues.cpp @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) TypeSpec Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +#include "queues_models.hpp" + +using namespace Azure::Storage::Queues::_detail::Models; + +const GeoReplicationStatus GeoReplicationStatus::Live{"live"}; +const GeoReplicationStatus GeoReplicationStatus::Bootstrap{"bootstrap"}; +const GeoReplicationStatus GeoReplicationStatus::Unavailable{"unavailable"}; + +const ListQueuesIncludeType ListQueuesIncludeType::Metadata{"metadata"}; diff --git a/sdk/storage/azure-storage-queues/src/generated/queues_client.cpp b/sdk/storage/azure-storage-queues/src/generated/queues_client.cpp new file mode 100644 index 0000000000..95232707f2 --- /dev/null +++ b/sdk/storage/azure-storage-queues/src/generated/queues_client.cpp @@ -0,0 +1,3423 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) TypeSpec Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +#include "queues_client.hpp" + +#include "../private/package_version.hpp" + +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace Azure::Storage::Queues::_detail; + +QueuesClient::QueuesClient( + Core::Url endpoint, + std::shared_ptr pipeline, + const QueuesClientOptions& options) + : m_pipeline(std::move(pipeline)), m_url(std::move(endpoint)), m_xMsVersion(options.XMsVersion) +{ + if (!m_pipeline) + { + throw std::invalid_argument("pipeline must not be null"); + } +} + +std::string QueuesClient::GetUrl() const { return m_url.GetAbsoluteUrl(); } + +Azure::Response +QueuesClient::SetPropertiesService( + const Models::QueueServiceProperties& queueServiceProperties, + const QueuesClientSetPropertiesServiceOptions& options, + const Core::Context& context) const +{ + auto url = m_url; + + url.AppendQueryParameter("comp", "properties"); + url.AppendQueryParameter("restype", "service"); + + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + std::string xmlBody; + { + using namespace _internal; + XmlWriter writer; + + writer.Write(XmlNode{XmlNodeType::StartTag, "StorageServiceProperties"}); + if (queueServiceProperties.Logging.HasValue()) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "Logging"}); + writer.Write(XmlNode{ + XmlNodeType::StartTag, "Version", queueServiceProperties.Logging.Value().Version}); + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "Delete", + queueServiceProperties.Logging.Value().Delete ? "true" : "false"}); + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "Read", + queueServiceProperties.Logging.Value().Read ? "true" : "false"}); + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "Write", + queueServiceProperties.Logging.Value().Write ? "true" : "false"}); + writer.Write(XmlNode{XmlNodeType::StartTag, "RetentionPolicy"}); + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "Enabled", + queueServiceProperties.Logging.Value().RetentionPolicy.Enabled ? "true" : "false"}); + if (queueServiceProperties.Logging.Value().RetentionPolicy.Days.HasValue()) + { + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "Days", + std::to_string(queueServiceProperties.Logging.Value().RetentionPolicy.Days.Value())}); + } + writer.Write(XmlNode{XmlNodeType::EndTag}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + if (queueServiceProperties.HourMetrics.HasValue()) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "HourMetrics"}); + if (queueServiceProperties.HourMetrics.Value().Version.HasValue()) + { + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "Version", + queueServiceProperties.HourMetrics.Value().Version.Value()}); + } + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "Enabled", + queueServiceProperties.HourMetrics.Value().Enabled ? "true" : "false"}); + if (queueServiceProperties.HourMetrics.Value().IncludeApis.HasValue()) + { + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "IncludeAPIs", + queueServiceProperties.HourMetrics.Value().IncludeApis.Value() ? "true" : "false"}); + } + if (queueServiceProperties.HourMetrics.Value().RetentionPolicy.HasValue()) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "RetentionPolicy"}); + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "Enabled", + queueServiceProperties.HourMetrics.Value().RetentionPolicy.Value().Enabled ? "true" + : "false"}); + if (queueServiceProperties.HourMetrics.Value().RetentionPolicy.Value().Days.HasValue()) + { + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "Days", + std::to_string(queueServiceProperties.HourMetrics.Value() + .RetentionPolicy.Value() + .Days.Value())}); + } + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + if (queueServiceProperties.MinuteMetrics.HasValue()) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "MinuteMetrics"}); + if (queueServiceProperties.MinuteMetrics.Value().Version.HasValue()) + { + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "Version", + queueServiceProperties.MinuteMetrics.Value().Version.Value()}); + } + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "Enabled", + queueServiceProperties.MinuteMetrics.Value().Enabled ? "true" : "false"}); + if (queueServiceProperties.MinuteMetrics.Value().IncludeApis.HasValue()) + { + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "IncludeAPIs", + queueServiceProperties.MinuteMetrics.Value().IncludeApis.Value() ? "true" : "false"}); + } + if (queueServiceProperties.MinuteMetrics.Value().RetentionPolicy.HasValue()) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "RetentionPolicy"}); + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "Enabled", + queueServiceProperties.MinuteMetrics.Value().RetentionPolicy.Value().Enabled + ? "true" + : "false"}); + if (queueServiceProperties.MinuteMetrics.Value().RetentionPolicy.Value().Days.HasValue()) + { + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "Days", + std::to_string(queueServiceProperties.MinuteMetrics.Value() + .RetentionPolicy.Value() + .Days.Value())}); + } + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + if (queueServiceProperties.Cors.HasValue()) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "Cors"}); + for (auto const& item : queueServiceProperties.Cors.Value()) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "CorsRule"}); + writer.Write(XmlNode{XmlNodeType::StartTag, "AllowedOrigins", item.AllowedOrigins}); + writer.Write(XmlNode{XmlNodeType::StartTag, "AllowedMethods", item.AllowedMethods}); + writer.Write(XmlNode{XmlNodeType::StartTag, "AllowedHeaders", item.AllowedHeaders}); + writer.Write(XmlNode{XmlNodeType::StartTag, "ExposedHeaders", item.ExposedHeaders}); + writer.Write(XmlNode{ + XmlNodeType::StartTag, "MaxAgeInSeconds", std::to_string(item.MaxAgeInSeconds)}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + writer.Write(XmlNode{XmlNodeType::EndTag}); + + writer.Write(XmlNode{XmlNodeType::End}); + xmlBody = writer.GetDocument(); + } + + Core::IO::MemoryBodyStream requestBody( + reinterpret_cast(xmlBody.data()), xmlBody.length()); + + Core::Http::Request request(Core::Http::HttpMethod::Put, url, &requestBody); + + request.SetHeader("Content-Type", "application/xml"); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + request.SetHeader("Content-Length", std::to_string(requestBody.Length())); + + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::Accepted) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::SetPropertiesServiceResult response{}; + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + + return Response(std::move(response), std::move(rawResponse)); +} + +Azure::Response +QueuesClient::GetPropertiesService( + const QueuesClientGetPropertiesServiceOptions& options, + const Core::Context& context) const +{ + auto url = m_url; + + url.AppendQueryParameter("comp", "properties"); + url.AppendQueryParameter("restype", "service"); + + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + Core::Http::Request request(Core::Http::HttpMethod::Get, url); + + request.SetHeader("Accept", "application/xml"); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::GetPropertiesServiceResult response{}; + { + using namespace _internal; + const auto& responseBody = rawResponse->GetBody(); + XmlReader reader(reinterpret_cast(responseBody.data()), responseBody.size()); + try + { + for (auto node = reader.Read(); node.Type != XmlNodeType::End; node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "StorageServiceProperties") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "Logging") + { + if (!response.Logging.HasValue()) + { + response.Logging = Models::Logging{}; + } + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "Version") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.Logging.Value().Version = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "Delete") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.Logging.Value().Delete = (node.Value == "true"); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "Read") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.Logging.Value().Read = (node.Value == "true"); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "Write") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.Logging.Value().Write = (node.Value == "true"); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "RetentionPolicy") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag + || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "Enabled") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.Logging.Value().RetentionPolicy.Enabled + = (node.Value == "true"); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "Days") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.Logging.Value().RetentionPolicy.Days + = std::stoi(node.Value); + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "HourMetrics") + { + if (!response.HourMetrics.HasValue()) + { + response.HourMetrics = Models::Metrics{}; + } + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "Version") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.HourMetrics.Value().Version = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "Enabled") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.HourMetrics.Value().Enabled = (node.Value == "true"); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "IncludeAPIs") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.HourMetrics.Value().IncludeApis = (node.Value == "true"); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "RetentionPolicy") + { + if (!response.HourMetrics.Value().RetentionPolicy.HasValue()) + { + response.HourMetrics.Value().RetentionPolicy = Models::RetentionPolicy{}; + } + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag + || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "Enabled") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.HourMetrics.Value().RetentionPolicy.Value().Enabled + = (node.Value == "true"); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "Days") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.HourMetrics.Value().RetentionPolicy.Value().Days + = std::stoi(node.Value); + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "MinuteMetrics") + { + if (!response.MinuteMetrics.HasValue()) + { + response.MinuteMetrics = Models::Metrics{}; + } + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "Version") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.MinuteMetrics.Value().Version = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "Enabled") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.MinuteMetrics.Value().Enabled = (node.Value == "true"); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "IncludeAPIs") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.MinuteMetrics.Value().IncludeApis = (node.Value == "true"); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "RetentionPolicy") + { + if (!response.MinuteMetrics.Value().RetentionPolicy.HasValue()) + { + response.MinuteMetrics.Value().RetentionPolicy = Models::RetentionPolicy{}; + } + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag + || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "Enabled") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.MinuteMetrics.Value().RetentionPolicy.Value().Enabled + = (node.Value == "true"); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "Days") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.MinuteMetrics.Value().RetentionPolicy.Value().Days + = std::stoi(node.Value); + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "Cors") + { + if (!response.Cors.HasValue()) + { + response.Cors = std::vector{}; + } + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "CorsRule") + { + Models::CorsRule responseCorsValueItem{}; + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "AllowedOrigins") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseCorsValueItem.AllowedOrigins = node.Value; + } + } + } + else if ( + node.Type == XmlNodeType::StartTag && node.Name == "AllowedMethods") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseCorsValueItem.AllowedMethods = node.Value; + } + } + } + else if ( + node.Type == XmlNodeType::StartTag && node.Name == "AllowedHeaders") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseCorsValueItem.AllowedHeaders = node.Value; + } + } + } + else if ( + node.Type == XmlNodeType::StartTag && node.Name == "ExposedHeaders") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseCorsValueItem.ExposedHeaders = node.Value; + } + } + } + else if ( + node.Type == XmlNodeType::StartTag && node.Name == "MaxAgeInSeconds") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseCorsValueItem.MaxAgeInSeconds = std::stoi(node.Value); + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + response.Cors.Value().emplace_back(std::move(responseCorsValueItem)); + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + } + } + } + catch (Core::RequestFailedException const&) + { + throw; + } + catch (std::exception const& ex) + { + throw Core::RequestFailedException(ex.what()); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + + return Response(std::move(response), std::move(rawResponse)); +} + +Azure::Response +QueuesClient::GetStatisticsService( + const QueuesClientGetStatisticsServiceOptions& options, + const Core::Context& context) const +{ + auto url = m_url; + + url.AppendQueryParameter("comp", "stats"); + url.AppendQueryParameter("restype", "service"); + + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + Core::Http::Request request(Core::Http::HttpMethod::Get, url); + + request.SetHeader("Accept", "application/xml"); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::GetStatisticsServiceResult response{}; + { + using namespace _internal; + const auto& responseBody = rawResponse->GetBody(); + XmlReader reader(reinterpret_cast(responseBody.data()), responseBody.size()); + try + { + for (auto node = reader.Read(); node.Type != XmlNodeType::End; node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "StorageServiceStats") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "GeoReplication") + { + if (!response.GeoReplication.HasValue()) + { + response.GeoReplication = Models::GeoReplication{}; + } + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "Status") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.GeoReplication.Value().Status + = Models::GeoReplicationStatus(node.Value); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "LastSyncTime") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.GeoReplication.Value().LastSyncTime + = DateTime::Parse(node.Value, DateTime::DateFormat::Rfc1123); + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + } + } + } + catch (Core::RequestFailedException const&) + { + throw; + } + catch (std::exception const& ex) + { + throw Core::RequestFailedException(ex.what()); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + + return Response(std::move(response), std::move(rawResponse)); +} + +Azure::Response +QueuesClient::GetUserDelegationKeyService( + const Models::KeyInfo& keyInfo, + const QueuesClientGetUserDelegationKeyServiceOptions& options, + const Core::Context& context) const +{ + auto url = m_url; + + url.AppendQueryParameter("comp", "userdelegationkey"); + url.AppendQueryParameter("restype", "service"); + + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + std::string xmlBody; + { + using namespace _internal; + XmlWriter writer; + + writer.Write(XmlNode{XmlNodeType::StartTag, "KeyInfo"}); + if (keyInfo.Start.HasValue()) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "Start", keyInfo.Start.Value()}); + } + writer.Write(XmlNode{XmlNodeType::StartTag, "Expiry", keyInfo.Expiry}); + if (keyInfo.DelegatedUserTid.HasValue()) + { + writer.Write( + XmlNode{XmlNodeType::StartTag, "DelegatedUserTid", keyInfo.DelegatedUserTid.Value()}); + } + writer.Write(XmlNode{XmlNodeType::EndTag}); + + writer.Write(XmlNode{XmlNodeType::End}); + xmlBody = writer.GetDocument(); + } + + Core::IO::MemoryBodyStream requestBody( + reinterpret_cast(xmlBody.data()), xmlBody.length()); + + Core::Http::Request request(Core::Http::HttpMethod::Post, url, &requestBody); + + request.SetHeader("Content-Type", "application/xml"); + request.SetHeader("Accept", "application/xml"); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + request.SetHeader("Content-Length", std::to_string(requestBody.Length())); + + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::GetUserDelegationKeyServiceResult response{}; + { + using namespace _internal; + const auto& responseBody = rawResponse->GetBody(); + XmlReader reader(reinterpret_cast(responseBody.data()), responseBody.size()); + try + { + for (auto node = reader.Read(); node.Type != XmlNodeType::End; node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "UserDelegationKey") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "SignedOid") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.SignedOid = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "SignedTid") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.SignedTid = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "SignedStart") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.SignedStart + = DateTime::Parse(node.Value, DateTime::DateFormat::Rfc3339); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "SignedExpiry") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.SignedExpiry + = DateTime::Parse(node.Value, DateTime::DateFormat::Rfc3339); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "SignedService") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.SignedService = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "SignedVersion") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.SignedVersion = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "SignedDelegatedUserTid") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.SignedDelegatedUserTid = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "Value") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.Value = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + } + } + } + catch (Core::RequestFailedException const&) + { + throw; + } + catch (std::exception const& ex) + { + throw Core::RequestFailedException(ex.what()); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + + return Response( + std::move(response), std::move(rawResponse)); +} + +Azure::Response +QueuesClient::GetQueuesService( + const QueuesClientGetQueuesServiceOptions& options, + const Core::Context& context) const +{ + auto url = m_url; + + url.AppendQueryParameter("comp", "list"); + + if (options.Prefix.HasValue()) + { + url.AppendQueryParameter("prefix", Core::Url::Encode(options.Prefix.Value())); + } + + if (options.Marker.HasValue()) + { + url.AppendQueryParameter("marker", Core::Url::Encode(options.Marker.Value())); + } + + if (options.Maxresults.HasValue()) + { + url.AppendQueryParameter("maxresults", std::to_string(options.Maxresults.Value())); + } + + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + if (options.Include.HasValue()) + { + std::string valueStr; + const size_t size = options.Include.Value().size(); + for (size_t i = 0; i < size; ++i) + { + if (i != 0) + { + valueStr += ','; + } + + valueStr += Core::Url::Encode(options.Include.Value()[i].ToString()); + } + + url.AppendQueryParameter("include", valueStr); + } + + Core::Http::Request request(Core::Http::HttpMethod::Get, url); + + request.SetHeader("Accept", "application/xml"); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::GetQueuesServiceResult response{}; + { + using namespace _internal; + const auto& responseBody = rawResponse->GetBody(); + XmlReader reader(reinterpret_cast(responseBody.data()), responseBody.size()); + try + { + for (auto node = reader.Read(); node.Type != XmlNodeType::End; node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "EnumerationResults") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::Attribute && node.Name == "ServiceEndpoint") + { + response.ServiceEndpoint = node.Value; + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "Prefix") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.Prefix = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "Marker") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.Marker = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "MaxResults") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.MaxResults = std::stoi(node.Value); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "Queues") + { + if (!response.QueueItems.HasValue()) + { + response.QueueItems = std::vector{}; + } + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "Queue") + { + Models::QueueItem responseQueueItemsValueItem{}; + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "Name") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseQueueItemsValueItem.Name = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "Metadata") + { + if (!responseQueueItemsValueItem.Metadata.HasValue()) + { + responseQueueItemsValueItem.Metadata + = std::map{}; + } + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag) + { + auto const key = node.Name; + responseQueueItemsValueItem.Metadata.Value()[key] = std::string{}; + for (node = reader.Read(); node.Type != XmlNodeType::EndTag + && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseQueueItemsValueItem.Metadata.Value()[key] = node.Value; + } + } + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + response.QueueItems.Value().emplace_back( + std::move(responseQueueItemsValueItem)); + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "NextMarker") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + response.NextMarker = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + } + } + } + catch (Core::RequestFailedException const&) + { + throw; + } + catch (std::exception const& ex) + { + throw Core::RequestFailedException(ex.what()); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + + return Response(std::move(response), std::move(rawResponse)); +} + +Azure::Response QueuesClient:: + CreateQueue(const QueuesClientCreateQueueOptions& options, const Core::Context& context) const +{ + auto url = m_url; + + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + Core::Http::Request request(Core::Http::HttpMethod::Put, url); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + if (options.Metadata.HasValue()) + { + for (auto const& header : options.Metadata.Value()) + { + request.SetHeader(std::string("x-ms-meta-") + header.first, header.second); + } + } + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::Created + && httpStatusCode != Core::Http::HttpStatusCode::NoContent) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::CreateQueueResult response{}; + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + + return Response(std::move(response), std::move(rawResponse)); +} + +Azure::Response +QueuesClient::GetPropertiesQueue( + const QueuesClientGetPropertiesQueueOptions& options, + const Core::Context& context) const +{ + auto url = m_url; + + url.AppendQueryParameter("comp", "metadata"); + + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + Core::Http::Request request(Core::Http::HttpMethod::Get, url); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::GetPropertiesQueueResult response{}; + { + auto header = rawResponse->GetHeaders().find("x-ms-approximate-messages-count"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + { + std::size_t parsedLength = 0; + auto parsedValue = std::stoll(headerValue, &parsedLength); + if (parsedLength != headerValue.size() + || parsedValue < (std::numeric_limits::min)() + || parsedValue > (std::numeric_limits::max)()) + { + throw std::out_of_range("Invalid integer response header."); + } + response.ApproximateMessagesCount = static_cast(parsedValue); + } + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + for (auto const& header : rawResponse->GetHeaders()) + { + if (header.first.size() > 10 + && Core::_internal::StringExtensions::LocaleInvariantCaseInsensitiveEqual( + header.first.substr(0, 10), "x-ms-meta-")) + { + if (!response.Metadata.HasValue()) + { + response.Metadata = Core::CaseInsensitiveMap{}; + } + response.Metadata.Value()[header.first.substr(10)] = header.second; + } + } + + return Response(std::move(response), std::move(rawResponse)); +} + +Azure::Response QueuesClient:: + DeleteQueue(const QueuesClientDeleteQueueOptions& options, const Core::Context& context) const +{ + auto url = m_url; + + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + Core::Http::Request request(Core::Http::HttpMethod::Delete, url); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::NoContent) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::DeleteQueueResult response{}; + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + + return Response(std::move(response), std::move(rawResponse)); +} + +Azure::Response +QueuesClient::SetMetadataQueue( + const QueuesClientSetMetadataQueueOptions& options, + const Core::Context& context) const +{ + auto url = m_url; + + url.AppendQueryParameter("comp", "metadata"); + + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + Core::Http::Request request(Core::Http::HttpMethod::Put, url); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + if (options.Metadata.HasValue()) + { + for (auto const& header : options.Metadata.Value()) + { + request.SetHeader(std::string("x-ms-meta-") + header.first, header.second); + } + } + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::NoContent) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::SetMetadataQueueResult response{}; + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + + return Response(std::move(response), std::move(rawResponse)); +} + +Azure::Response +QueuesClient::GetAccessPolicyQueue( + const QueuesClientGetAccessPolicyQueueOptions& options, + const Core::Context& context) const +{ + auto url = m_url; + + url.AppendQueryParameter("comp", "acl"); + + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + Core::Http::Request request(Core::Http::HttpMethod::Get, url); + + request.SetHeader("Accept", "application/xml"); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::GetAccessPolicyQueueResult response{}; + { + using namespace _internal; + const auto& responseBody = rawResponse->GetBody(); + XmlReader reader(reinterpret_cast(responseBody.data()), responseBody.size()); + try + { + for (auto node = reader.Read(); node.Type != XmlNodeType::End; node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "SignedIdentifiers") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "SignedIdentifier") + { + Models::SignedIdentifier responseItemsItem{}; + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "Id") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.Id = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "AccessPolicy") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag + || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "Start") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.AccessPolicy.Start + = DateTime::Parse(node.Value, DateTime::DateFormat::Rfc3339); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "Expiry") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.AccessPolicy.Expiry + = DateTime::Parse(node.Value, DateTime::DateFormat::Rfc3339); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "Permission") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.AccessPolicy.Permission = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + response.Items.emplace_back(std::move(responseItemsItem)); + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + } + } + } + catch (Core::RequestFailedException const&) + { + throw; + } + catch (std::exception const& ex) + { + throw Core::RequestFailedException(ex.what()); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + + return Response(std::move(response), std::move(rawResponse)); +} + +Azure::Response +QueuesClient::SetAccessPolicyQueue( + const QueuesClientSetAccessPolicyQueueOptions& options, + const Core::Context& context) const +{ + auto url = m_url; + + url.AppendQueryParameter("comp", "acl"); + + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + std::string xmlBody; + if (options.QueueAcl.HasValue()) + { + using namespace _internal; + XmlWriter writer; + + if (options.QueueAcl.HasValue()) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "SignedIdentifiers"}); + for (auto const& item : options.QueueAcl.Value().Items) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "SignedIdentifier"}); + writer.Write(XmlNode{XmlNodeType::StartTag, "Id", item.Id}); + writer.Write(XmlNode{XmlNodeType::StartTag, "AccessPolicy"}); + if (item.AccessPolicy.Start.HasValue()) + { + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "Start", + item.AccessPolicy.Start.Value().ToString( + DateTime::DateFormat::Rfc3339, DateTime::TimeFractionFormat::AllDigits)}); + } + if (item.AccessPolicy.Expiry.HasValue()) + { + writer.Write(XmlNode{ + XmlNodeType::StartTag, + "Expiry", + item.AccessPolicy.Expiry.Value().ToString( + DateTime::DateFormat::Rfc3339, DateTime::TimeFractionFormat::AllDigits)}); + } + if (item.AccessPolicy.Permission.HasValue()) + { + writer.Write( + XmlNode{XmlNodeType::StartTag, "Permission", item.AccessPolicy.Permission.Value()}); + } + writer.Write(XmlNode{XmlNodeType::EndTag}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + writer.Write(XmlNode{XmlNodeType::End}); + xmlBody = writer.GetDocument(); + } + + Core::IO::MemoryBodyStream requestBody( + reinterpret_cast(xmlBody.data()), xmlBody.length()); + + Core::Http::Request request(Core::Http::HttpMethod::Put, url, &requestBody); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + if (options.QueueAcl.HasValue()) + { + request.SetHeader("Content-Type", "application/xml"); + } + request.SetHeader("Content-Length", std::to_string(requestBody.Length())); + + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::NoContent) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::SetAccessPolicyQueueResult response{}; + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + + return Response(std::move(response), std::move(rawResponse)); +} + +Azure::Response +QueuesClient::ReceiveMessagesQueue( + const QueuesClientReceiveMessagesQueueOptions& options, + const Core::Context& context) const +{ + auto url = m_url; + url.AppendPath("messages"); + + if (options.Numofmessages.HasValue()) + { + url.AppendQueryParameter("numofmessages", std::to_string(options.Numofmessages.Value())); + } + + if (options.Visibilitytimeout.HasValue()) + { + url.AppendQueryParameter( + "visibilitytimeout", std::to_string(options.Visibilitytimeout.Value())); + } + + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + Core::Http::Request request(Core::Http::HttpMethod::Get, url); + + request.SetHeader("Accept", "application/xml"); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::ReceiveMessagesQueueResult response{}; + { + using namespace _internal; + const auto& responseBody = rawResponse->GetBody(); + XmlReader reader(reinterpret_cast(responseBody.data()), responseBody.size()); + try + { + for (auto node = reader.Read(); node.Type != XmlNodeType::End; node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "QueueMessagesList") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "QueueMessage") + { + Models::ReceivedMessage responseItemsItem{}; + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "MessageId") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.MessageId = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "InsertionTime") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.InsertionTime + = DateTime::Parse(node.Value, DateTime::DateFormat::Rfc1123); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "ExpirationTime") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.ExpirationTime + = DateTime::Parse(node.Value, DateTime::DateFormat::Rfc1123); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "PopReceipt") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.PopReceipt = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "TimeNextVisible") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.TimeNextVisible + = DateTime::Parse(node.Value, DateTime::DateFormat::Rfc1123); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "DequeueCount") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.DequeueCount = std::stoll(node.Value); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "MessageText") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.MessageText = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + response.Items.emplace_back(std::move(responseItemsItem)); + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + } + } + } + catch (Core::RequestFailedException const&) + { + throw; + } + catch (std::exception const& ex) + { + throw Core::RequestFailedException(ex.what()); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + + return Response(std::move(response), std::move(rawResponse)); +} + +Azure::Response QueuesClient::ClearQueue( + const QueuesClientClearQueueOptions& options, + const Core::Context& context) const +{ + auto url = m_url; + url.AppendPath("messages"); + + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + Core::Http::Request request(Core::Http::HttpMethod::Delete, url); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::NoContent) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::ClearQueueResult response{}; + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + + return Response(std::move(response), std::move(rawResponse)); +} + +Azure::Response +QueuesClient::SendMessageQueue( + const Models::QueueMessage& queueMessage, + const QueuesClientSendMessageQueueOptions& options, + const Core::Context& context) const +{ + auto url = m_url; + url.AppendPath("messages"); + + if (options.Visibilitytimeout.HasValue()) + { + url.AppendQueryParameter( + "visibilitytimeout", std::to_string(options.Visibilitytimeout.Value())); + } + + if (options.Messagettl.HasValue()) + { + url.AppendQueryParameter("messagettl", std::to_string(options.Messagettl.Value())); + } + + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + std::string xmlBody; + { + using namespace _internal; + XmlWriter writer; + + writer.Write(XmlNode{XmlNodeType::StartTag, "QueueMessage"}); + writer.Write(XmlNode{XmlNodeType::StartTag, "MessageText", queueMessage.MessageText}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + + writer.Write(XmlNode{XmlNodeType::End}); + xmlBody = writer.GetDocument(); + } + + Core::IO::MemoryBodyStream requestBody( + reinterpret_cast(xmlBody.data()), xmlBody.length()); + + Core::Http::Request request(Core::Http::HttpMethod::Post, url, &requestBody); + + request.SetHeader("Content-Type", "application/xml"); + request.SetHeader("Accept", "application/xml"); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + request.SetHeader("Content-Length", std::to_string(requestBody.Length())); + + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::Created) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::SendMessageQueueResult response{}; + { + using namespace _internal; + const auto& responseBody = rawResponse->GetBody(); + XmlReader reader(reinterpret_cast(responseBody.data()), responseBody.size()); + try + { + for (auto node = reader.Read(); node.Type != XmlNodeType::End; node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "QueueMessagesList") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "QueueMessage") + { + Models::SentMessage responseItemsItem{}; + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "MessageId") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.MessageId = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "InsertionTime") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.InsertionTime + = DateTime::Parse(node.Value, DateTime::DateFormat::Rfc1123); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "ExpirationTime") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.ExpirationTime + = DateTime::Parse(node.Value, DateTime::DateFormat::Rfc1123); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "PopReceipt") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.PopReceipt = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "TimeNextVisible") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.TimeNextVisible + = DateTime::Parse(node.Value, DateTime::DateFormat::Rfc1123); + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + response.Items.emplace_back(std::move(responseItemsItem)); + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + } + } + } + catch (Core::RequestFailedException const&) + { + throw; + } + catch (std::exception const& ex) + { + throw Core::RequestFailedException(ex.what()); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + + return Response(std::move(response), std::move(rawResponse)); +} + +Azure::Response +QueuesClient::PeekMessagesQueue( + const QueuesClientPeekMessagesQueueOptions& options, + const Core::Context& context) const +{ + auto url = m_url; + url.AppendPath("messages"); + + url.AppendQueryParameter("peekonly", "true"); + + if (options.Numofmessages.HasValue()) + { + url.AppendQueryParameter("numofmessages", std::to_string(options.Numofmessages.Value())); + } + + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + Core::Http::Request request(Core::Http::HttpMethod::Get, url); + + request.SetHeader("Accept", "application/xml"); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::Ok) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::PeekMessagesQueueResult response{}; + { + using namespace _internal; + const auto& responseBody = rawResponse->GetBody(); + XmlReader reader(reinterpret_cast(responseBody.data()), responseBody.size()); + try + { + for (auto node = reader.Read(); node.Type != XmlNodeType::End; node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "QueueMessagesList") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "QueueMessage") + { + Models::PeekedMessage responseItemsItem{}; + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::StartTag || node.Type == XmlNodeType::Attribute) + { + if (node.Type == XmlNodeType::StartTag && node.Name == "MessageId") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.MessageId = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "InsertionTime") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.InsertionTime + = DateTime::Parse(node.Value, DateTime::DateFormat::Rfc1123); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "ExpirationTime") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.ExpirationTime + = DateTime::Parse(node.Value, DateTime::DateFormat::Rfc1123); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "DequeueCount") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.DequeueCount = std::stoll(node.Value); + } + } + } + else if (node.Type == XmlNodeType::StartTag && node.Name == "MessageText") + { + for (node = reader.Read(); + node.Type != XmlNodeType::EndTag && node.Type != XmlNodeType::End; + node = reader.Read()) + { + if (node.Type == XmlNodeType::Text) + { + responseItemsItem.MessageText = node.Value; + } + } + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + response.Items.emplace_back(std::move(responseItemsItem)); + } + else if (node.Type == XmlNodeType::StartTag) + { + int depth = 1; + while (depth > 0) + { + node = reader.Read(); + if (node.Type == XmlNodeType::End) + { + throw std::runtime_error("Unexpected end of XML."); + } + if (node.Type == XmlNodeType::StartTag) + { + ++depth; + } + else if (node.Type == XmlNodeType::EndTag) + { + --depth; + } + } + } + } + } + } + } + } + catch (Core::RequestFailedException const&) + { + throw; + } + catch (std::exception const& ex) + { + throw Core::RequestFailedException(ex.what()); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + + return Response(std::move(response), std::move(rawResponse)); +} + +Azure::Response +QueuesClient::UpdateMessageQueue( + const std::string& messageId, + const std::string& popreceipt, + std::int32_t visibilitytimeout, + const QueuesClientUpdateMessageQueueOptions& options, + const Core::Context& context) const +{ + auto url = m_url; + url.AppendPath("messages"); + if (messageId.empty()) + { + throw std::invalid_argument("Parameter 'messageId' cannot be an empty string."); + } + url.AppendPath(Core::Url::Encode(messageId)); + + url.AppendQueryParameter("popreceipt", Core::Url::Encode(popreceipt)); + url.AppendQueryParameter("visibilitytimeout", std::to_string(visibilitytimeout)); + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + std::string xmlBody; + if (options.QueueMessage.HasValue()) + { + using namespace _internal; + XmlWriter writer; + + if (options.QueueMessage.HasValue()) + { + writer.Write(XmlNode{XmlNodeType::StartTag, "QueueMessage"}); + writer.Write( + XmlNode{XmlNodeType::StartTag, "MessageText", options.QueueMessage.Value().MessageText}); + writer.Write(XmlNode{XmlNodeType::EndTag}); + } + writer.Write(XmlNode{XmlNodeType::End}); + xmlBody = writer.GetDocument(); + } + + Core::IO::MemoryBodyStream requestBody( + reinterpret_cast(xmlBody.data()), xmlBody.length()); + + Core::Http::Request request(Core::Http::HttpMethod::Put, url, &requestBody); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + if (options.QueueMessage.HasValue()) + { + request.SetHeader("Content-Type", "application/xml"); + } + request.SetHeader("Content-Length", std::to_string(requestBody.Length())); + + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::NoContent) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::UpdateMessageQueueResult response{}; + { + auto header = rawResponse->GetHeaders().find("x-ms-popreceipt"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.PopReceipt = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-popreceipt"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-time-next-visible"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.TimeNextVisible = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: x-ms-time-next-visible"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + + return Response(std::move(response), std::move(rawResponse)); +} + +Azure::Response +QueuesClient::DeleteMessageQueue( + const std::string& messageId, + const std::string& popreceipt, + const QueuesClientDeleteMessageQueueOptions& options, + const Core::Context& context) const +{ + auto url = m_url; + url.AppendPath("messages"); + if (messageId.empty()) + { + throw std::invalid_argument("Parameter 'messageId' cannot be an empty string."); + } + url.AppendPath(Core::Url::Encode(messageId)); + + url.AppendQueryParameter("popreceipt", Core::Url::Encode(popreceipt)); + if (options.Timeout.HasValue()) + { + url.AppendQueryParameter("timeout", std::to_string(options.Timeout.Value())); + } + + Core::Http::Request request(Core::Http::HttpMethod::Delete, url); + + request.SetHeader("x-ms-version", m_xMsVersion); + if (options.XMsClientRequestId.HasValue()) + { + request.SetHeader("x-ms-client-request-id", options.XMsClientRequestId.Value()); + } + + auto rawResponse = m_pipeline->Send(request, context); + const auto httpStatusCode = rawResponse->GetStatusCode(); + + if (httpStatusCode != Core::Http::HttpStatusCode::NoContent) + { + throw Core::RequestFailedException(rawResponse); + } + + Models::DeleteMessageQueueResult response{}; + { + auto header = rawResponse->GetHeaders().find("x-ms-version"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Version = headerValue; + } + else + { + throw std::out_of_range("Missing required response header: x-ms-version"); + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.RequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("x-ms-client-request-id"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.ClientRequestId = headerValue; + } + } + { + auto header = rawResponse->GetHeaders().find("Date"); + if (header != rawResponse->GetHeaders().end()) + { + auto const& headerValue = header->second; + response.Date = DateTime::Parse(headerValue, DateTime::DateFormat::Rfc1123); + } + else + { + throw std::out_of_range("Missing required response header: Date"); + } + } + + return Response(std::move(response), std::move(rawResponse)); +} diff --git a/sdk/storage/azure-storage-queues/src/generated/queues_client.hpp b/sdk/storage/azure-storage-queues/src/generated/queues_client.hpp new file mode 100644 index 0000000000..3aea69cfd4 --- /dev/null +++ b/sdk/storage/azure-storage-queues/src/generated/queues_client.hpp @@ -0,0 +1,272 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) TypeSpec Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +#pragma once + +#include "queues_client_options.hpp" +#include "queues_models.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace Azure { namespace Storage { namespace Queues { namespace _detail { + class QueuesClient final { + public: + /** + * @brief Constructs the QueuesClient. + * @param endpoint The URL address where the client will send the requests to. + * @param pipeline Existing HTTP pipeline; policies are not recreated. + * @param options Optional parameters. + * + */ + explicit QueuesClient( + Core::Url endpoint, + std::shared_ptr pipeline, + const QueuesClientOptions& options = {}); + + /** + * @brief Gets the QueuesClient URL endpoint. + * @return The QueuesClient's URL endpoint. + * + */ + std::string GetUrl() const; + + /** + * @brief Sets properties for a storage account's Queue service endpoint, including properties + * for Storage Analytics and CORS (Cross-Origin Resource Sharing) rules. + * @param queueServiceProperties The storage service properties to set. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return Operation result. + * + */ + Response SetPropertiesService( + const Models::QueueServiceProperties& queueServiceProperties, + const QueuesClientSetPropertiesServiceOptions& options = {}, + const Core::Context& context = {}) const; + + /** + * @brief Retrieves properties of a storage account's Queue service, including properties for + * Storage Analytics and CORS (Cross-Origin Resource Sharing) rules. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return The service properties. + * + */ + Response GetPropertiesService( + const QueuesClientGetPropertiesServiceOptions& options = {}, + const Core::Context& context = {}) const; + + /** + * @brief Retrieves statistics related to replication for the Queue service. It is only + * available on the secondary location endpoint when read-access geo-redundant replication is + * enabled for the storage account. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return Statistics returned to the C++ queue protocol client. + * + */ + Response GetStatisticsService( + const QueuesClientGetStatisticsServiceOptions& options = {}, + const Core::Context& context = {}) const; + + /** + * @brief Retrieves a user delegation key for the Queue service. This is only a valid operation + * when using bearer token authentication. + * @param keyInfo Key information. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return A user delegation key. + * + */ + Response GetUserDelegationKeyService( + const Models::KeyInfo& keyInfo, + const QueuesClientGetUserDelegationKeyServiceOptions& options = {}, + const Core::Context& context = {}) const; + + /** + * @brief Returns a list of queues. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return The list queues response. + * + */ + Response GetQueuesService( + const QueuesClientGetQueuesServiceOptions& options = {}, + const Core::Context& context = {}) const; + + /** + * @brief Creates a new queue. If a queue with the same name already exists, the operation + * succeeds when the metadata is identical. If the metadata differs, the operation fails. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return Operation result. + * + */ + Response CreateQueue( + const QueuesClientCreateQueueOptions& options = {}, + const Core::Context& context = {}) const; + + /** + * @brief Returns all user-defined metadata and system properties for the specified queue. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return Operation result. + * + */ + Response GetPropertiesQueue( + const QueuesClientGetPropertiesQueueOptions& options = {}, + const Core::Context& context = {}) const; + + /** + * @brief Permanently deletes the specified queue. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return Operation result. + * + */ + Response DeleteQueue( + const QueuesClientDeleteQueueOptions& options = {}, + const Core::Context& context = {}) const; + + /** + * @brief Sets user-defined metadata for the specified queue. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return Operation result. + * + */ + Response SetMetadataQueue( + const QueuesClientSetMetadataQueueOptions& options = {}, + const Core::Context& context = {}) const; + + /** + * @brief Gets the access policy for the specified queue. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return An array of signed identifiers. + * + */ + Response GetAccessPolicyQueue( + const QueuesClientGetAccessPolicyQueueOptions& options = {}, + const Core::Context& context = {}) const; + + /** + * @brief Sets the permissions for the specified queue. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return Operation result. + * + */ + Response SetAccessPolicyQueue( + const QueuesClientSetAccessPolicyQueueOptions& options = {}, + const Core::Context& context = {}) const; + + /** + * @brief Retrieves one or more messages from the front of the queue. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return The response of receive messages. + * + */ + Response ReceiveMessagesQueue( + const QueuesClientReceiveMessagesQueueOptions& options = {}, + const Core::Context& context = {}) const; + + /** + * @brief Deletes all messages from the specified queue. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return Operation result. + * + */ + Response ClearQueue( + const QueuesClientClearQueueOptions& options = {}, + const Core::Context& context = {}) const; + + /** + * @brief Adds a new message to the back of the message queue. A visibility timeout can also be + * specified to make the message invisible until the visibility timeout expires. + * @param queueMessage The queue message. The message must be in a format that can be included + * in an XML request with UTF-8 encoding. The encoded message can be up to 64 KB in size. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return The response of send message. + * + */ + Response SendMessageQueue( + const Models::QueueMessage& queueMessage, + const QueuesClientSendMessageQueueOptions& options = {}, + const Core::Context& context = {}) const; + + /** + * @brief Retrieves one or more messages from the front of the queue, but does not alter the + * visibility of the message. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return The response of peek messages. + * + */ + Response PeekMessagesQueue( + const QueuesClientPeekMessagesQueueOptions& options = {}, + const Core::Context& context = {}) const; + + /** + * @brief Updates the visibility timeout of a message. This operation can also be used to update + * the contents of a message. + * @param messageId The ID of the queue message. + * @param popreceipt An opaque value required to delete the message. If deletion fails using + * this PopReceipt then the message has been dequeued by another client. + * @param visibilitytimeout Specifies the new visibility timeout value, in seconds, relative to + * server time. A specified value must be larger than or equal to 1 second, and cannot be larger + * than 7 days. The visibility timeout of a message can be set to a value later than the expiry + * time. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return Operation result. + * + */ + Response UpdateMessageQueue( + const std::string& messageId, + const std::string& popreceipt, + std::int32_t visibilitytimeout, + const QueuesClientUpdateMessageQueueOptions& options = {}, + const Core::Context& context = {}) const; + + /** + * @brief Deletes the specified message. + * @param messageId The ID of the queue message. + * @param popreceipt An opaque value required to delete the message. If deletion fails using + * this PopReceipt then the message has been dequeued by another client. + * @param options Optional parameters. + * @param context The context for the operation can be used for request cancellation. + * @return Operation result. + * + */ + Response DeleteMessageQueue( + const std::string& messageId, + const std::string& popreceipt, + const QueuesClientDeleteMessageQueueOptions& options = {}, + const Core::Context& context = {}) const; + + private: + std::shared_ptr m_pipeline; + Core::Url m_url; + std::string m_xMsVersion; + }; +}}}} // namespace Azure::Storage::Queues::_detail diff --git a/sdk/storage/azure-storage-queues/src/generated/queues_client_options.hpp b/sdk/storage/azure-storage-queues/src/generated/queues_client_options.hpp new file mode 100644 index 0000000000..e8c20c2df9 --- /dev/null +++ b/sdk/storage/azure-storage-queues/src/generated/queues_client_options.hpp @@ -0,0 +1,344 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) TypeSpec Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +#pragma once + +#include "queues_models.hpp" + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace Azure { namespace Storage { namespace Queues { namespace _detail { + /** + * @brief QueuesClient options. + * + */ + struct QueuesClientOptions final + { + /// Specifies the version of the operation to use for this request. + std::string XMsVersion = "2026-04-06"; + }; + + /** + * @brief SetPropertiesService operation options. + * + */ + struct QueuesClientSetPropertiesServiceOptions final + { + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + }; + + /** + * @brief GetPropertiesService operation options. + * + */ + struct QueuesClientGetPropertiesServiceOptions final + { + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + }; + + /** + * @brief GetStatisticsService operation options. + * + */ + struct QueuesClientGetStatisticsServiceOptions final + { + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + }; + + /** + * @brief GetUserDelegationKeyService operation options. + * + */ + struct QueuesClientGetUserDelegationKeyServiceOptions final + { + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + }; + + /** + * @brief GetQueuesService operation options. + * + */ + struct QueuesClientGetQueuesServiceOptions final + { + /// The URL to fetch the next page of results. + std::string NextPageToken; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// Filters the results to return only queues whose name begins with the specified prefix. + Nullable Prefix; + + /// Identifies the portion of the list of queues to be returned with the next listing operation. + /// The operation returns the marker value if the listing operation did not return all queues + /// remaining. The marker value can be used as the value for the marker parameter in a + /// subsequent call to request the next page of list items. The marker value is opaque to the + /// client. + Nullable Marker; + + /// Specifies the maximum number of queues to return. If the request does not specify + /// maxresults, or specifies a value greater than 5000, the server will return up to 5000 items. + Nullable Maxresults; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + + /// Specify to include additional, optional information. + Nullable> Include; + }; + + /** + * @brief CreateQueue operation options. + * + */ + struct QueuesClientCreateQueueOptions final + { + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + + /// The metadata headers. + Nullable Metadata; + }; + + /** + * @brief GetPropertiesQueue operation options. + * + */ + struct QueuesClientGetPropertiesQueueOptions final + { + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + }; + + /** + * @brief DeleteQueue operation options. + * + */ + struct QueuesClientDeleteQueueOptions final + { + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + }; + + /** + * @brief SetMetadataQueue operation options. + * + */ + struct QueuesClientSetMetadataQueueOptions final + { + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + + /// The metadata headers. + Nullable Metadata; + }; + + /** + * @brief GetAccessPolicyQueue operation options. + * + */ + struct QueuesClientGetAccessPolicyQueueOptions final + { + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + }; + + /** + * @brief SetAccessPolicyQueue operation options. + * + */ + struct QueuesClientSetAccessPolicyQueueOptions final + { + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + + /// The access control list. + Nullable QueueAcl; + }; + + /** + * @brief ReceiveMessagesQueue operation options. + * + */ + struct QueuesClientReceiveMessagesQueueOptions final + { + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// A nonzero integer value that specifies the number of messages to retrieve from the queue, up + /// to a maximum of 32. If fewer are visible, the visible messages are returned. By default, a + /// single message is retrieved from the queue with this operation. + Nullable Numofmessages; + + /// Specifies the new visibility timeout value, in seconds, relative to server time. A specified + /// value must be larger than or equal to 1 second, and cannot be larger than 7 days. The + /// visibility timeout of a message can be set to a value later than the expiry time. + Nullable Visibilitytimeout; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + }; + + /** + * @brief ClearQueue operation options. + * + */ + struct QueuesClientClearQueueOptions final + { + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + }; + + /** + * @brief SendMessageQueue operation options. + * + */ + struct QueuesClientSendMessageQueueOptions final + { + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// Specifies the new visibility timeout value, in seconds, relative to server time. A specified + /// value must be larger than or equal to 1 second, and cannot be larger than 7 days. The + /// visibility timeout of a message can be set to a value later than the expiry time. + Nullable Visibilitytimeout; + + /// Specifies the time-to-live interval for the message, in seconds. Prior to version + /// 2017-07-29, the maximum time-to-live allowed is 7 days. For version 2017-07-29 or later, the + /// maximum time-to-live can be any positive number, as well as -1 indicating that the message + /// does not expire. If this parameter is omitted, the default time-to-live is 7 days. + Nullable Messagettl; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + }; + + /** + * @brief PeekMessagesQueue operation options. + * + */ + struct QueuesClientPeekMessagesQueueOptions final + { + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// A nonzero integer value that specifies the number of messages to retrieve from the queue, up + /// to a maximum of 32. If fewer are visible, the visible messages are returned. By default, a + /// single message is retrieved from the queue with this operation. + Nullable Numofmessages; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + }; + + /** + * @brief UpdateMessageQueue operation options. + * + */ + struct QueuesClientUpdateMessageQueueOptions final + { + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + + /// The queue message. The message must be in a format that can be included in an XML request + /// with UTF-8 encoding. The encoded message can be up to 64 KB in size. + Nullable QueueMessage; + }; + + /** + * @brief DeleteMessageQueue operation options. + * + */ + struct QueuesClientDeleteMessageQueueOptions final + { + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable XMsClientRequestId; + + /// The timeout parameter is expressed in seconds. For more information, see [Setting Timeouts + /// for Queue Service + /// Operations.](https://learn.microsoft.com/en-us/rest/api/storageservices/setting-timeouts-for-queue-service-operations) + Nullable Timeout; + }; +}}}} // namespace Azure::Storage::Queues::_detail diff --git a/sdk/storage/azure-storage-queues/src/generated/queues_models.hpp b/sdk/storage/azure-storage-queues/src/generated/queues_models.hpp new file mode 100644 index 0000000000..fda7ed359b --- /dev/null +++ b/sdk/storage/azure-storage-queues/src/generated/queues_models.hpp @@ -0,0 +1,765 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) TypeSpec Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +#pragma once + +#include "azure/storage/queues/dll_import_export.hpp" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace Azure { namespace Storage { namespace Queues { namespace _detail { namespace Models { + /** + * @brief The geo replication status. + * + */ + class GeoReplicationStatus final + : public Core::_internal::ExtendableEnumeration { + public: + /** + * @brief Constructs a new GeoReplicationStatus instance. + * + **/ + GeoReplicationStatus() = default; + + /** + * @brief Constructs a new GeoReplicationStatus instance from a string. + * @param geoReplicationStatus String value to construct the new instance from. + * + **/ + explicit GeoReplicationStatus(std::string geoReplicationStatus) + : ExtendableEnumeration(std::move(geoReplicationStatus)) + { + } + + /// The geo replication is live. + AZ_STORAGE_QUEUES_DLLEXPORT static const GeoReplicationStatus Live; + + /// The geo replication is bootstrap. + AZ_STORAGE_QUEUES_DLLEXPORT static const GeoReplicationStatus Bootstrap; + + /// The geo replication is unavailable. + AZ_STORAGE_QUEUES_DLLEXPORT static const GeoReplicationStatus Unavailable; + }; + + /** + * @brief Specify to include additional, optional information. + * + */ + class ListQueuesIncludeType final + : public Core::_internal::ExtendableEnumeration { + public: + /** + * @brief Constructs a new ListQueuesIncludeType instance. + * + **/ + ListQueuesIncludeType() = default; + + /** + * @brief Constructs a new ListQueuesIncludeType instance from a string. + * @param listQueuesIncludeType String value to construct the new instance from. + * + **/ + explicit ListQueuesIncludeType(std::string listQueuesIncludeType) + : ExtendableEnumeration(std::move(listQueuesIncludeType)) + { + } + + /// Include queue metadata. + AZ_STORAGE_QUEUES_DLLEXPORT static const ListQueuesIncludeType Metadata; + }; + + /** + * @brief SetPropertiesService operation result. + * + */ + struct SetPropertiesServiceResult final + { + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; + + /** + * @brief The retention policy. + * + */ + struct RetentionPolicy final + { + /// Whether to enable the retention policy. + bool Enabled = false; + + /// The number of days to retain the logs. + Nullable Days; + }; + + /** + * @brief Azure Analytics Logging settings. + * + */ + struct Logging final + { + /// The version of the logging properties. + std::string Version; + + /// Whether delete operation is logged. + bool Delete = false; + + /// Whether read operation is logged. + bool Read = false; + + /// Whether write operation is logged. + bool Write = false; + + /// The retention policy of the logs. + Models::RetentionPolicy RetentionPolicy; + }; + + /** + * @brief The metrics properties. + * + */ + struct Metrics final + { + /// The version of the metrics properties. + Nullable Version; + + /// Whether it is enabled. + bool Enabled = false; + + /// Whether to include API in the metrics. + Nullable IncludeApis; + + /// The retention policy of the metrics. + Nullable RetentionPolicy; + }; + + /** + * @brief The CORS rules. + * + */ + struct CorsRule final + { + /// The allowed origins. + std::string AllowedOrigins; + + /// The allowed methods. + std::string AllowedMethods; + + /// The allowed headers. + std::string AllowedHeaders; + + /// The exposed headers. + std::string ExposedHeaders; + + /// The maximum age in seconds. + std::int32_t MaxAgeInSeconds = 0; + }; + + /** + * @brief The service properties. + * + */ + struct QueueServiceProperties final + { + /// The logging properties. + Nullable Logging; + + /// The hour metrics properties. + Nullable HourMetrics; + + /// The minute metrics properties. + Nullable MinuteMetrics; + + /// The CORS properties. + Nullable> Cors; + }; + + /** + * @brief The service properties. + * + */ + struct GetPropertiesServiceResult final + { + /// The logging properties. + Nullable Logging; + + /// The hour metrics properties. + Nullable HourMetrics; + + /// The minute metrics properties. + Nullable MinuteMetrics; + + /// The CORS properties. + Nullable> Cors; + + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; + + /** + * @brief Geo replication information for the secondary storage location. + * + */ + struct GeoReplication final + { + /// The status of the secondary location. + GeoReplicationStatus Status; + + /// A GMT date/time value, to the second. All primary writes preceding this value are guaranteed + /// to be available for read operations at the secondary. Primary writes after this point in + /// time may or may not be available for reads. + Nullable LastSyncTime; + }; + + /** + * @brief Statistics returned to the C++ queue protocol client. + * + */ + struct GetStatisticsServiceResult final + { + /// The geo replication stats. + Nullable GeoReplication; + + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; + + /** + * @brief A user delegation key. + * + */ + struct GetUserDelegationKeyServiceResult final + { + /// The Entra ID object ID in GUID format. + std::string SignedOid; + + /// The Entra ID tenant ID in GUID format. + std::string SignedTid; + + /// The date-time the key is active. + DateTime SignedStart; + + /// The date-time the key expires. + DateTime SignedExpiry; + + /// The service that created the key. + std::string SignedService; + + /// The service version used when creating the key. + std::string SignedVersion; + + /// The delegated user tenant ID in Entra ID. Return if DelegatedUserTid is specified. + Nullable SignedDelegatedUserTid; + + /// The key as a base64 string. + std::string Value; + + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; + + /** + * @brief Key information for user delegation key. + * + */ + struct KeyInfo final + { + /// The date-time the key is active in ISO 8601 UTC time. + Nullable Start; + + /// The date-time the key expires in ISO 8601 UTC time. + std::string Expiry; + + /// The delegated user tenant ID in Entra ID. + Nullable DelegatedUserTid; + }; + + /** + * @brief An Azure Storage Queue. + * + */ + struct QueueItem final + { + /// The name of the queue. + std::string Name; + + /// The metadata of the queue. + Nullable> Metadata; + }; + + /** + * @brief The list queues response. + * + */ + struct GetQueuesServiceResult final + { + /// The service endpoint. + std::string ServiceEndpoint; + + /// The prefix of the queues. + std::string Prefix; + + /// Identifies the current position in the list queues operation. + Nullable Marker; + + /// The max results. + std::int32_t MaxResults = 0; + + /// The list of queues. + Nullable> QueueItems; + + /// Identifies the portion of the list of queues to be returned with the next listing operation. + std::string NextMarker; + + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; + + /** + * @brief CreateQueue operation result. + * + */ + struct CreateQueueResult final + { + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; + + /** + * @brief GetPropertiesQueue operation result. + * + */ + struct GetPropertiesQueueResult final + { + /// The metadata headers. + Nullable Metadata; + + /// The approximate number of messages in the queue. This number is not lower than the actual + /// number of messages in the queue, but could be higher. + Nullable ApproximateMessagesCount; + + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; + + /** + * @brief DeleteQueue operation result. + * + */ + struct DeleteQueueResult final + { + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; + + /** + * @brief SetMetadataQueue operation result. + * + */ + struct SetMetadataQueueResult final + { + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; + + /** + * @brief The access policy. + * + */ + struct AccessPolicy final + { + /// The date-time the policy is active. + Nullable Start; + + /// The date-time the policy expires. + Nullable Expiry; + + /// The permissions for the policy. + Nullable Permission; + }; + + /** + * @brief The signed identifier. + * + */ + struct SignedIdentifier final + { + /// The unique ID for the signed identifier. + std::string Id; + + /// The access policy for the signed identifier. + Models::AccessPolicy AccessPolicy; + }; + + /** + * @brief An array of signed identifiers. + * + */ + struct GetAccessPolicyQueueResult final + { + /// The list of signed identifiers. + std::vector Items; + + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; + + /** + * @brief SetAccessPolicyQueue operation result. + * + */ + struct SetAccessPolicyQueueResult final + { + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; + + /** + * @brief An array of signed identifiers. + * + */ + struct SignedIdentifiers final + { + /// The list of signed identifiers. + std::vector Items; + }; + + /** + * @brief The received queue message. + * + */ + struct ReceivedMessage final + { + /// The ID of the message. + std::string MessageId; + + /// The time the message was inserted into the queue. + DateTime InsertionTime; + + /// The time that the message will expire and be automatically deleted. + DateTime ExpirationTime; + + /// An opaque value required to delete the message. If deletion fails using this PopReceipt then + /// the message has been dequeued by another client. + std::string PopReceipt; + + /// The time that the message will again become visible in the queue. + DateTime TimeNextVisible; + + /// The number of times the message has been dequeued. + std::int64_t DequeueCount = 0; + + /// The content of the message. + std::string MessageText; + }; + + /** + * @brief The response of receive messages. + * + */ + struct ReceiveMessagesQueueResult final + { + /// The list of received messages. + std::vector Items; + + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; + + /** + * @brief ClearQueue operation result. + * + */ + struct ClearQueueResult final + { + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; + + /** + * @brief The sent queue message. + * + */ + struct SentMessage final + { + /// The ID of the message. + std::string MessageId; + + /// The time the message was inserted into the queue. + DateTime InsertionTime; + + /// The time that the message will expire and be automatically deleted. + DateTime ExpirationTime; + + /// An opaque value required to delete the message. If deletion fails using this PopReceipt then + /// the message has been dequeued by another client. + std::string PopReceipt; + + /// The time that the message will again become visible in the queue. + DateTime TimeNextVisible; + }; + + /** + * @brief The response of send message. + * + */ + struct SendMessageQueueResult final + { + /// The list of sent messages. + std::vector Items; + + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; + + /** + * @brief The queue message. + * + */ + struct QueueMessage final + { + /// The content of the message. + std::string MessageText; + }; + + /** + * @brief The peeked queue message. + * + */ + struct PeekedMessage final + { + /// The ID of the message. + std::string MessageId; + + /// The time the message was inserted into the queue. + DateTime InsertionTime; + + /// The time that the message will expire and be automatically deleted. + DateTime ExpirationTime; + + /// The number of times the message has been dequeued. + std::int64_t DequeueCount = 0; + + /// The content of the message. + std::string MessageText; + }; + + /** + * @brief The response of peek messages. + * + */ + struct PeekMessagesQueueResult final + { + /// The list of peeked messages. + std::vector Items; + + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; + + /** + * @brief UpdateMessageQueue operation result. + * + */ + struct UpdateMessageQueueResult final + { + /// The pop receipt of the queue message. + std::string PopReceipt; + + /// A UTC date/time value that represents when the message will be visible on the queue. + DateTime TimeNextVisible; + + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; + + /** + * @brief DeleteMessageQueue operation result. + * + */ + struct DeleteMessageQueueResult final + { + /// Specifies the version of the operation to use for this request. + std::string Version; + + /// An opaque, globally-unique, server-generated string identifier for the request. + Nullable RequestId; + + /// An opaque, globally-unique, client-generated string identifier for the request. + Nullable ClientRequestId; + + /// UTC date/time value generated by the service that indicates the time at which the response + /// was initiated. + DateTime Date; + }; +}}}}} // namespace Azure::Storage::Queues::_detail::Models diff --git a/sdk/storage/azure-storage-queues/src/private/queue_model_conversions.hpp b/sdk/storage/azure-storage-queues/src/private/queue_model_conversions.hpp new file mode 100644 index 0000000000..6c6f25344f --- /dev/null +++ b/sdk/storage/azure-storage-queues/src/private/queue_model_conversions.hpp @@ -0,0 +1,189 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#pragma once + +#include "../generated/queues_client.hpp" +#include "azure/storage/queues/queue_responses.hpp" + +namespace Azure { namespace Storage { namespace Queues { namespace _detail { + + namespace PublicModels = Azure::Storage::Queues::Models; + + inline Models::RetentionPolicy ToGenerated(PublicModels::RetentionPolicy value) + { + Models::RetentionPolicy result; + result.Enabled = value.IsEnabled; + result.Days = value.Days; + return result; + } + + inline PublicModels::RetentionPolicy ToPublic(Models::RetentionPolicy value) + { + PublicModels::RetentionPolicy result; + result.IsEnabled = value.Enabled; + result.Days = value.Days; + return result; + } + + inline Models::Metrics ToGenerated(PublicModels::Metrics value) + { + Models::Metrics result; + result.Version = std::move(value.Version); + result.Enabled = value.IsEnabled; + result.IncludeApis = value.IncludeApis; + result.RetentionPolicy = ToGenerated(std::move(value.RetentionPolicy)); + return result; + } + + inline PublicModels::Metrics ToPublic(Models::Metrics value) + { + PublicModels::Metrics result; + if (value.Version.HasValue()) + { + result.Version = std::move(value.Version.Value()); + } + result.IsEnabled = value.Enabled; + result.IncludeApis = value.IncludeApis; + if (value.RetentionPolicy.HasValue()) + { + result.RetentionPolicy = ToPublic(std::move(value.RetentionPolicy.Value())); + } + return result; + } + + inline Models::CorsRule ToGenerated(PublicModels::CorsRule value) + { + Models::CorsRule result; + result.AllowedOrigins = std::move(value.AllowedOrigins); + result.AllowedMethods = std::move(value.AllowedMethods); + result.AllowedHeaders = std::move(value.AllowedHeaders); + result.ExposedHeaders = std::move(value.ExposedHeaders); + result.MaxAgeInSeconds = value.MaxAgeInSeconds; + return result; + } + + inline PublicModels::CorsRule ToPublic(Models::CorsRule value) + { + PublicModels::CorsRule result; + result.AllowedOrigins = std::move(value.AllowedOrigins); + result.AllowedMethods = std::move(value.AllowedMethods); + result.AllowedHeaders = std::move(value.AllowedHeaders); + result.ExposedHeaders = std::move(value.ExposedHeaders); + result.MaxAgeInSeconds = value.MaxAgeInSeconds; + return result; + } + + inline Models::QueueServiceProperties ToGenerated(PublicModels::QueueServiceProperties value) + { + Models::QueueServiceProperties result; + Models::Logging logging; + logging.Version = std::move(value.Logging.Version); + logging.Delete = value.Logging.Delete; + logging.Read = value.Logging.Read; + logging.Write = value.Logging.Write; + logging.RetentionPolicy = ToGenerated(std::move(value.Logging.RetentionPolicy)); + result.Logging = std::move(logging); + result.HourMetrics = ToGenerated(std::move(value.HourMetrics)); + result.MinuteMetrics = ToGenerated(std::move(value.MinuteMetrics)); + std::vector cors; + cors.reserve(value.Cors.size()); + for (auto& rule : value.Cors) + { + cors.emplace_back(ToGenerated(std::move(rule))); + } + result.Cors = std::move(cors); + return result; + } + + inline PublicModels::QueueServiceProperties ToPublic(Models::GetPropertiesServiceResult value) + { + PublicModels::QueueServiceProperties result; + if (value.Logging.HasValue()) + { + auto& logging = value.Logging.Value(); + result.Logging.Version = std::move(logging.Version); + result.Logging.Delete = logging.Delete; + result.Logging.Read = logging.Read; + result.Logging.Write = logging.Write; + result.Logging.RetentionPolicy = ToPublic(std::move(logging.RetentionPolicy)); + } + if (value.HourMetrics.HasValue()) + { + result.HourMetrics = ToPublic(std::move(value.HourMetrics.Value())); + } + if (value.MinuteMetrics.HasValue()) + { + result.MinuteMetrics = ToPublic(std::move(value.MinuteMetrics.Value())); + } + if (value.Cors.HasValue()) + { + result.Cors.reserve(value.Cors.Value().size()); + for (auto& rule : value.Cors.Value()) + { + result.Cors.emplace_back(ToPublic(std::move(rule))); + } + } + return result; + } + + inline Models::SignedIdentifiers ToGenerated(PublicModels::QueueAccessPolicy const& value) + { + Models::SignedIdentifiers result; + result.Items.reserve(value.SignedIdentifiers.size()); + for (auto const& identifier : value.SignedIdentifiers) + { + Models::SignedIdentifier item; + item.Id = identifier.Id; + item.AccessPolicy.Start = identifier.StartsOn; + item.AccessPolicy.Expiry = identifier.ExpiresOn; + item.AccessPolicy.Permission = identifier.Permissions; + result.Items.emplace_back(std::move(item)); + } + return result; + } + + inline PublicModels::QueueAccessPolicy ToPublic(Models::GetAccessPolicyQueueResult value) + { + PublicModels::QueueAccessPolicy result; + result.SignedIdentifiers.reserve(value.Items.size()); + for (auto& identifier : value.Items) + { + PublicModels::SignedIdentifier item; + item.Id = std::move(identifier.Id); + item.StartsOn = identifier.AccessPolicy.Start; + item.ExpiresOn = identifier.AccessPolicy.Expiry; + if (identifier.AccessPolicy.Permission.HasValue()) + { + item.Permissions = std::move(identifier.AccessPolicy.Permission.Value()); + } + result.SignedIdentifiers.emplace_back(std::move(item)); + } + return result; + } + + inline PublicModels::QueueMessage ToPublic(Models::ReceivedMessage value) + { + PublicModels::QueueMessage result; + result.MessageId = std::move(value.MessageId); + result.InsertedOn = value.InsertionTime; + result.ExpiresOn = value.ExpirationTime; + result.PopReceipt = std::move(value.PopReceipt); + result.NextVisibleOn = value.TimeNextVisible; + result.DequeueCount = value.DequeueCount; + result.MessageText = std::move(value.MessageText); + return result; + } + + inline PublicModels::PeekedQueueMessage ToPublic(Models::PeekedMessage value) + { + PublicModels::PeekedQueueMessage result; + result.MessageId = std::move(value.MessageId); + result.InsertedOn = value.InsertionTime; + result.ExpiresOn = value.ExpirationTime; + result.DequeueCount = value.DequeueCount; + result.MessageText = std::move(value.MessageText); + return result; + } + +}}}} // namespace Azure::Storage::Queues::_detail diff --git a/sdk/storage/azure-storage-queues/src/queue_client.cpp b/sdk/storage/azure-storage-queues/src/queue_client.cpp index 1fdc9dd97f..5437b122c4 100644 --- a/sdk/storage/azure-storage-queues/src/queue_client.cpp +++ b/sdk/storage/azure-storage-queues/src/queue_client.cpp @@ -4,15 +4,19 @@ #include "azure/storage/queues/queue_client.hpp" #include "private/package_version.hpp" +#include "private/queue_model_conversions.hpp" #include #include #include #include #include +#include #include #include +#include + namespace Azure { namespace Storage { namespace Queues { QueueClient QueueClient::CreateFromConnectionString( @@ -99,14 +103,16 @@ namespace Azure { namespace Storage { namespace Queues { { try { - _detail::QueueClient::CreateQueueOptions protocolLayerOptions; - protocolLayerOptions.Metadata - = std::map(options.Metadata.begin(), options.Metadata.end()); - auto response - = _detail::QueueClient::Create(*m_pipeline, m_queueUrl, protocolLayerOptions, context); - response.Value.Created - = response.RawResponse->GetStatusCode() == Core::Http::HttpStatusCode::Created; - return response; + _detail::QueuesClientCreateQueueOptions protocolLayerOptions; + protocolLayerOptions.Metadata = options.Metadata; + auto response = _internal::InvokeStorageProtocol([&] { + return _detail::QueuesClient(m_queueUrl, m_pipeline) + .CreateQueue(protocolLayerOptions, context); + }); + Models::CreateQueueResult result; + result.Created = response.RawResponse->GetStatusCode() == Core::Http::HttpStatusCode::Created; + return Azure::Response( + std::move(result), std::move(response.RawResponse)); } catch (StorageException& e) { @@ -127,8 +133,9 @@ namespace Azure { namespace Storage { namespace Queues { (void)options; try { - _detail::QueueClient::DeleteQueueOptions protocolLayerOptions; - return _detail::QueueClient::Delete(*m_pipeline, m_queueUrl, protocolLayerOptions, context); + auto response = _internal::InvokeStorageProtocol( + [&] { return _detail::QueuesClient(m_queueUrl, m_pipeline).DeleteQueue({}, context); }); + return Azure::Response({}, std::move(response.RawResponse)); } catch (StorageException& e) { @@ -147,21 +154,28 @@ namespace Azure { namespace Storage { namespace Queues { const Azure::Core::Context& context) const { (void)options; - _detail::QueueClient::GetQueuePropertiesOptions protocolLayerOptions; - auto ret = _detail::QueueClient::GetProperties( - *m_pipeline, m_queueUrl, protocolLayerOptions, context); + auto ret = _internal::InvokeStorageProtocol([&] { + return _detail::QueuesClient(m_queueUrl, m_pipeline).GetPropertiesQueue({}, context); + }); Models::QueueProperties queueProperties; - queueProperties.Metadata = std::move(ret.Value.Metadata); - if (ret.Value.ApproximateMessageCount > static_cast(INT32_MAX)) + if (ret.Value.Metadata.HasValue()) + { + queueProperties.Metadata = std::move(ret.Value.Metadata.Value()); + } + if (!ret.Value.ApproximateMessagesCount.HasValue()) + { + throw std::out_of_range("Missing x-ms-approximate-messages-count response header."); + } + auto const count = ret.Value.ApproximateMessagesCount.Value(); + if (count > static_cast(INT32_MAX)) { queueProperties.ApproximateMessageCount = -1; } else { - queueProperties.ApproximateMessageCount - = static_cast(ret.Value.ApproximateMessageCount); + queueProperties.ApproximateMessageCount = static_cast(count); } - queueProperties.ApproximateMessageCountLong = ret.Value.ApproximateMessageCount; + queueProperties.ApproximateMessageCountLong = count; return Azure::Response( std::move(queueProperties), std::move(ret.RawResponse)); } @@ -172,11 +186,13 @@ namespace Azure { namespace Storage { namespace Queues { const Azure::Core::Context& context) const { (void)options; - _detail::QueueClient::SetQueueMetadataOptions protocolLayerOptions; - protocolLayerOptions.Metadata - = std::map(metadata.begin(), metadata.end()); - return _detail::QueueClient::SetMetadata( - *m_pipeline, m_queueUrl, protocolLayerOptions, context); + _detail::QueuesClientSetMetadataQueueOptions protocolLayerOptions; + protocolLayerOptions.Metadata = std::move(metadata); + auto response = _internal::InvokeStorageProtocol([&] { + return _detail::QueuesClient(m_queueUrl, m_pipeline) + .SetMetadataQueue(protocolLayerOptions, context); + }); + return Azure::Response({}, std::move(response.RawResponse)); } Azure::Response QueueClient::GetAccessPolicy( @@ -184,9 +200,11 @@ namespace Azure { namespace Storage { namespace Queues { const Azure::Core::Context& context) const { (void)options; - _detail::QueueClient::GetQueueAccessPolicyOptions protocolLayerOptions; - return _detail::QueueClient::GetAccessPolicy( - *m_pipeline, m_queueUrl, protocolLayerOptions, context); + auto response = _internal::InvokeStorageProtocol([&] { + return _detail::QueuesClient(m_queueUrl, m_pipeline).GetAccessPolicyQueue({}, context); + }); + return Azure::Response( + _detail::ToPublic(std::move(response.Value)), std::move(response.RawResponse)); } Azure::Response QueueClient::SetAccessPolicy( @@ -195,10 +213,13 @@ namespace Azure { namespace Storage { namespace Queues { const Azure::Core::Context& context) const { (void)options; - _detail::QueueClient::SetQueueAccessPolicyOptions protocolLayerOptions; - protocolLayerOptions.QueueAcl = accessPolicy.SignedIdentifiers; - return _detail::QueueClient::SetAccessPolicy( - *m_pipeline, m_queueUrl, protocolLayerOptions, context); + _detail::QueuesClientSetAccessPolicyQueueOptions protocolLayerOptions; + protocolLayerOptions.QueueAcl = _detail::ToGenerated(accessPolicy); + auto response = _internal::InvokeStorageProtocol([&] { + return _detail::QueuesClient(m_queueUrl, m_pipeline) + .SetAccessPolicyQueue(protocolLayerOptions, context); + }); + return Azure::Response({}, std::move(response.RawResponse)); } Azure::Response QueueClient::EnqueueMessage( @@ -206,52 +227,79 @@ namespace Azure { namespace Storage { namespace Queues { const EnqueueMessageOptions& options, const Azure::Core::Context& context) const { - auto messagesUrl = m_queueUrl; - messagesUrl.AppendPath("messages"); - _detail::QueueClient::EnqueueQueueMessageOptions protocolLayerOptions; - protocolLayerOptions.QueueMessage.MessageText = std::move(messageText); + _detail::QueuesClientSendMessageQueueOptions protocolLayerOptions; + _detail::Models::QueueMessage message; + message.MessageText = std::move(messageText); if (options.TimeToLive.HasValue()) { - protocolLayerOptions.MessageTimeToLive - = static_cast(options.TimeToLive.Value().count()); + protocolLayerOptions.Messagettl = static_cast(options.TimeToLive.Value().count()); } if (options.VisibilityTimeout.HasValue()) { protocolLayerOptions.Visibilitytimeout = static_cast(options.VisibilityTimeout.Value().count()); } - return _detail::QueueClient::EnqueueMessage( - *m_pipeline, messagesUrl, protocolLayerOptions, context); + auto response = _internal::InvokeStorageProtocol([&] { + return _detail::QueuesClient(m_queueUrl, m_pipeline) + .SendMessageQueue(message, protocolLayerOptions, context); + }); + Models::EnqueueMessageResult result; + if (!response.Value.Items.empty()) + { + auto& item = response.Value.Items.front(); + result.MessageId = std::move(item.MessageId); + result.InsertedOn = item.InsertionTime; + result.ExpiresOn = item.ExpirationTime; + result.PopReceipt = std::move(item.PopReceipt); + result.NextVisibleOn = item.TimeNextVisible; + } + return Azure::Response( + std::move(result), std::move(response.RawResponse)); } Azure::Response QueueClient::ReceiveMessages( const ReceiveMessagesOptions& options, const Azure::Core::Context& context) const { - auto messagesUrl = m_queueUrl; - messagesUrl.AppendPath("messages"); - _detail::QueueClient::ReceiveQueueMessagesOptions protocolLayerOptions; - protocolLayerOptions.NumberOfMessages = options.MaxMessages; + _detail::QueuesClientReceiveMessagesQueueOptions protocolLayerOptions; + protocolLayerOptions.Numofmessages = options.MaxMessages; if (options.VisibilityTimeout.HasValue()) { protocolLayerOptions.Visibilitytimeout = static_cast(options.VisibilityTimeout.Value().count()); } - return _detail::QueueClient::ReceiveMessages( - *m_pipeline, messagesUrl, protocolLayerOptions, context); + auto response = _internal::InvokeStorageProtocol([&] { + return _detail::QueuesClient(m_queueUrl, m_pipeline) + .ReceiveMessagesQueue(protocolLayerOptions, context); + }); + Models::ReceivedMessages result; + result.Messages.reserve(response.Value.Items.size()); + for (auto& item : response.Value.Items) + { + result.Messages.emplace_back(_detail::ToPublic(std::move(item))); + } + return Azure::Response( + std::move(result), std::move(response.RawResponse)); } Azure::Response QueueClient::PeekMessages( const PeekMessagesOptions& options, const Azure::Core::Context& context) const { - (void)options; - auto messagesUrl = m_queueUrl; - messagesUrl.AppendPath("messages"); - _detail::QueueClient::PeekQueueMessagesOptions protocolLayerOptions; - protocolLayerOptions.NumberOfMessages = options.MaxMessages; - return _detail::QueueClient::PeekMessages( - *m_pipeline, messagesUrl, protocolLayerOptions, context); + _detail::QueuesClientPeekMessagesQueueOptions protocolLayerOptions; + protocolLayerOptions.Numofmessages = options.MaxMessages; + auto response = _internal::InvokeStorageProtocol([&] { + return _detail::QueuesClient(m_queueUrl, m_pipeline) + .PeekMessagesQueue(protocolLayerOptions, context); + }); + Models::PeekedMessages result; + result.Messages.reserve(response.Value.Items.size()); + for (auto& item : response.Value.Items) + { + result.Messages.emplace_back(_detail::ToPublic(std::move(item))); + } + return Azure::Response( + std::move(result), std::move(response.RawResponse)); } Azure::Response QueueClient::UpdateMessage( @@ -261,26 +309,27 @@ namespace Azure { namespace Storage { namespace Queues { const UpdateMessageOptions& options, const Azure::Core::Context& context) const { - auto messageUrl = m_queueUrl; - messageUrl.AppendPath("messages"); - messageUrl.AppendPath(_internal::UrlEncodePath(messageId)); + _detail::QueuesClientUpdateMessageQueueOptions protocolLayerOptions; if (options.MessageText.HasValue()) { - _detail::QueueClient::UpdateQueueMessageOptions protocolLayerOptions; - protocolLayerOptions.QueueMessage.MessageText = options.MessageText.Value(); - protocolLayerOptions.PopReceipt = popReceipt; - protocolLayerOptions.Visibilitytimeout = static_cast(visibilityTimeout.count()); - return _detail::QueueClient::UpdateMessage( - *m_pipeline, messageUrl, protocolLayerOptions, context); - } - else - { - _detail::QueueClient::UpdateQueueMessageVisibilityOptions protocolLayerOptions; - protocolLayerOptions.PopReceipt = popReceipt; - protocolLayerOptions.Visibilitytimeout = static_cast(visibilityTimeout.count()); - return _detail::QueueClient::UpdateMessageVisibility( - *m_pipeline, messageUrl, protocolLayerOptions, context); + _detail::Models::QueueMessage message; + message.MessageText = options.MessageText.Value(); + protocolLayerOptions.QueueMessage = std::move(message); } + auto response = _internal::InvokeStorageProtocol([&] { + return _detail::QueuesClient(m_queueUrl, m_pipeline) + .UpdateMessageQueue( + messageId, + popReceipt, + static_cast(visibilityTimeout.count()), + protocolLayerOptions, + context); + }); + Models::UpdateMessageResult result; + result.PopReceipt = std::move(response.Value.PopReceipt); + result.NextVisibleOn = response.Value.TimeNextVisible; + return Azure::Response( + std::move(result), std::move(response.RawResponse)); } Azure::Response QueueClient::DeleteMessage( @@ -290,13 +339,11 @@ namespace Azure { namespace Storage { namespace Queues { const Azure::Core::Context& context) const { (void)options; - auto messageUrl = m_queueUrl; - messageUrl.AppendPath("messages"); - messageUrl.AppendPath(_internal::UrlEncodePath(messageId)); - _detail::QueueClient::DeleteQueueMessageOptions protocolLayerOptions; - protocolLayerOptions.PopReceipt = popReceipt; - return _detail::QueueClient::DeleteMessage( - *m_pipeline, messageUrl, protocolLayerOptions, context); + auto response = _internal::InvokeStorageProtocol([&] { + return _detail::QueuesClient(m_queueUrl, m_pipeline) + .DeleteMessageQueue(messageId, popReceipt, {}, context); + }); + return Azure::Response({}, std::move(response.RawResponse)); } Azure::Response QueueClient::ClearMessages( @@ -304,11 +351,9 @@ namespace Azure { namespace Storage { namespace Queues { const Azure::Core::Context& context) const { (void)options; - auto messagesUrl = m_queueUrl; - messagesUrl.AppendPath("messages"); - _detail::QueueClient::ClearQueueMessagesOptions protocolLayerOptions; - return _detail::QueueClient::ClearMessages( - *m_pipeline, messagesUrl, protocolLayerOptions, context); + auto response = _internal::InvokeStorageProtocol( + [&] { return _detail::QueuesClient(m_queueUrl, m_pipeline).ClearQueue({}, context); }); + return Azure::Response({}, std::move(response.RawResponse)); } }}} // namespace Azure::Storage::Queues diff --git a/sdk/storage/azure-storage-queues/src/queue_responses.cpp b/sdk/storage/azure-storage-queues/src/queue_responses.cpp index 8ed00b183d..50e4b9970b 100644 --- a/sdk/storage/azure-storage-queues/src/queue_responses.cpp +++ b/sdk/storage/azure-storage-queues/src/queue_responses.cpp @@ -7,6 +7,12 @@ namespace Azure { namespace Storage { namespace Queues { + namespace Models { + const GeoReplicationStatus GeoReplicationStatus::Live("live"); + const GeoReplicationStatus GeoReplicationStatus::Bootstrap("bootstrap"); + const GeoReplicationStatus GeoReplicationStatus::Unavailable("unavailable"); + } // namespace Models + void ListQueuesPagedResponse::OnNextPage(const Azure::Core::Context& context) { m_operationOptions.ContinuationToken = NextPageToken; diff --git a/sdk/storage/azure-storage-queues/src/queue_sas_builder.cpp b/sdk/storage/azure-storage-queues/src/queue_sas_builder.cpp index c53be91ec4..795c81a5dd 100644 --- a/sdk/storage/azure-storage-queues/src/queue_sas_builder.cpp +++ b/sdk/storage/azure-storage-queues/src/queue_sas_builder.cpp @@ -3,7 +3,7 @@ #include "azure/storage/queues/queue_sas_builder.hpp" -#include "azure/storage/queues/rest_client.hpp" +#include "azure/storage/queues/queue_options.hpp" #include #include diff --git a/sdk/storage/azure-storage-queues/src/queue_service_client.cpp b/sdk/storage/azure-storage-queues/src/queue_service_client.cpp index bb019efbd6..bf0339785c 100644 --- a/sdk/storage/azure-storage-queues/src/queue_service_client.cpp +++ b/sdk/storage/azure-storage-queues/src/queue_service_client.cpp @@ -4,12 +4,14 @@ #include "azure/storage/queues/queue_service_client.hpp" #include "private/package_version.hpp" +#include "private/queue_model_conversions.hpp" #include #include #include #include #include +#include #include #include @@ -105,22 +107,47 @@ namespace Azure { namespace Storage { namespace Queues { const ListQueuesOptions& options, const Azure::Core::Context& context) const { - _detail::ServiceClient::ListServiceQueuesSegmentOptions protocolLayerOptions; + _detail::QueuesClientGetQueuesServiceOptions protocolLayerOptions; protocolLayerOptions.Prefix = options.Prefix; protocolLayerOptions.Marker = options.ContinuationToken; - protocolLayerOptions.MaxResults = options.PageSizeHint; - protocolLayerOptions.Include = options.Include; - auto response = _detail::ServiceClient::ListQueuesSegment( - *m_pipeline, m_serviceUrl, protocolLayerOptions, _internal::WithReplicaStatus(context)); + protocolLayerOptions.Maxresults = options.PageSizeHint; + if ((options.Include & Models::ListQueuesIncludeFlags::Metadata) + == Models::ListQueuesIncludeFlags::Metadata) + { + protocolLayerOptions.Include = std::vector<_detail::Models::ListQueuesIncludeType>{ + _detail::Models::ListQueuesIncludeType::Metadata}; + } + auto response = _internal::InvokeStorageProtocol([&] { + return _detail::QueuesClient(m_serviceUrl, m_pipeline) + .GetQueuesService(protocolLayerOptions, _internal::WithReplicaStatus(context)); + }); ListQueuesPagedResponse pagedResponse; pagedResponse.ServiceEndpoint = std::move(response.Value.ServiceEndpoint); pagedResponse.Prefix = std::move(response.Value.Prefix); - pagedResponse.Queues = std::move(response.Value.Items); + if (response.Value.QueueItems.HasValue()) + { + pagedResponse.Queues.reserve(response.Value.QueueItems.Value().size()); + for (auto& item : response.Value.QueueItems.Value()) + { + Models::QueueItem queue; + queue.Name = std::move(item.Name); + if (item.Metadata.HasValue()) + { + for (auto& entry : item.Metadata.Value()) + { + queue.Metadata[entry.first] = std::move(entry.second); + } + } + pagedResponse.Queues.emplace_back(std::move(queue)); + } + } pagedResponse.m_queueServiceClient = std::make_shared(*this); pagedResponse.m_operationOptions = options; pagedResponse.CurrentPageToken = options.ContinuationToken.ValueOr(std::string()); - pagedResponse.NextPageToken = response.Value.ContinuationToken; + pagedResponse.NextPageToken = response.Value.NextMarker.empty() + ? Azure::Nullable() + : Azure::Nullable(std::move(response.Value.NextMarker)); pagedResponse.RawResponse = std::move(response.RawResponse); return pagedResponse; @@ -132,10 +159,12 @@ namespace Azure { namespace Storage { namespace Queues { const Azure::Core::Context& context) const { (void)options; - _detail::ServiceClient::SetServicePropertiesOptions protocolLayerOptions; - protocolLayerOptions.QueueServiceProperties = std::move(properties); - return _detail::ServiceClient::SetProperties( - *m_pipeline, m_serviceUrl, protocolLayerOptions, context); + auto protocolProperties = _detail::ToGenerated(std::move(properties)); + auto response = _internal::InvokeStorageProtocol([&] { + return _detail::QueuesClient(m_serviceUrl, m_pipeline) + .SetPropertiesService(protocolProperties, {}, context); + }); + return Azure::Response({}, std::move(response.RawResponse)); } Azure::Response QueueServiceClient::GetProperties( @@ -143,9 +172,12 @@ namespace Azure { namespace Storage { namespace Queues { const Azure::Core::Context& context) const { (void)options; - _detail::ServiceClient::GetServicePropertiesOptions protocolLayerOptions; - return _detail::ServiceClient::GetProperties( - *m_pipeline, m_serviceUrl, protocolLayerOptions, _internal::WithReplicaStatus(context)); + auto response = _internal::InvokeStorageProtocol([&] { + return _detail::QueuesClient(m_serviceUrl, m_pipeline) + .GetPropertiesService({}, _internal::WithReplicaStatus(context)); + }); + return Azure::Response( + _detail::ToPublic(std::move(response.Value)), std::move(response.RawResponse)); } Azure::Response QueueServiceClient::GetStatistics( @@ -153,9 +185,18 @@ namespace Azure { namespace Storage { namespace Queues { const Azure::Core::Context& context) const { (void)options; - _detail::ServiceClient::GetServiceStatisticsOptions protocolLayerOptions; - return _detail::ServiceClient::GetStatistics( - *m_pipeline, m_serviceUrl, protocolLayerOptions, context); + auto response = _internal::InvokeStorageProtocol([&] { + return _detail::QueuesClient(m_serviceUrl, m_pipeline).GetStatisticsService({}, context); + }); + Models::ServiceStatistics result; + if (response.Value.GeoReplication.HasValue()) + { + auto& replication = response.Value.GeoReplication.Value(); + result.GeoReplication.Status = Models::GeoReplicationStatus(replication.Status.ToString()); + result.GeoReplication.LastSyncedOn = replication.LastSyncTime; + } + return Azure::Response( + std::move(result), std::move(response.RawResponse)); } Azure::Response QueueServiceClient::CreateQueue( @@ -182,14 +223,27 @@ namespace Azure { namespace Storage { namespace Queues { const GetUserDelegationKeyOptions& options, const Azure::Core::Context& context) const { - _detail::ServiceClient::GetServiceUserDelegationKeyOptions protocolLayerOptions; - protocolLayerOptions.KeyInfo.Start = options.StartsOn.ToString( - Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate); - protocolLayerOptions.KeyInfo.Expiry = expiresOn.ToString( - Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate); - protocolLayerOptions.KeyInfo.DelegatedUserTid = options.DelegatedUserTid; - return _detail::ServiceClient::GetUserDelegationKey( - *m_pipeline, m_serviceUrl, protocolLayerOptions, context); + _detail::Models::KeyInfo keyInfo; + keyInfo.Start = options.StartsOn.ToString( + DateTime::DateFormat::Rfc3339, DateTime::TimeFractionFormat::Truncate); + keyInfo.Expiry + = expiresOn.ToString(DateTime::DateFormat::Rfc3339, DateTime::TimeFractionFormat::Truncate); + keyInfo.DelegatedUserTid = options.DelegatedUserTid; + auto response = _internal::InvokeStorageProtocol([&] { + return _detail::QueuesClient(m_serviceUrl, m_pipeline) + .GetUserDelegationKeyService(keyInfo, {}, context); + }); + Models::UserDelegationKey result; + result.SignedObjectId = std::move(response.Value.SignedOid); + result.SignedTenantId = std::move(response.Value.SignedTid); + result.SignedStartsOn = response.Value.SignedStart; + result.SignedExpiresOn = response.Value.SignedExpiry; + result.SignedService = std::move(response.Value.SignedService); + result.SignedVersion = std::move(response.Value.SignedVersion); + result.SignedDelegatedUserTid = std::move(response.Value.SignedDelegatedUserTid); + result.Value = std::move(response.Value.Value); + return Azure::Response( + std::move(result), std::move(response.RawResponse)); } }}} // namespace Azure::Storage::Queues diff --git a/sdk/storage/azure-storage-queues/src/rest_client.cpp b/sdk/storage/azure-storage-queues/src/rest_client.cpp deleted file mode 100644 index ad7231b184..0000000000 --- a/sdk/storage/azure-storage-queues/src/rest_client.cpp +++ /dev/null @@ -1,1550 +0,0 @@ - -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -// -// Code generated by Microsoft (R) AutoRest C++ Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace { -std::string ListQueuesIncludeFlagsToString( - const Azure::Storage::Queues::Models::ListQueuesIncludeFlags& val) -{ - const Azure::Storage::Queues::Models::ListQueuesIncludeFlags valueList[] = { - Azure::Storage::Queues::Models::ListQueuesIncludeFlags::Metadata, - }; - const char* stringList[] = { - "metadata", - }; - std::string ret; - for (size_t i = 0; i < 1; ++i) - { - if ((val & valueList[i]) == valueList[i]) - { - if (!ret.empty()) - { - ret += ","; - } - ret += stringList[i]; - } - } - return ret; -} -} // namespace -namespace Azure { namespace Storage { namespace Queues { - namespace Models { - const GeoReplicationStatus GeoReplicationStatus::Live("live"); - const GeoReplicationStatus GeoReplicationStatus::Bootstrap("bootstrap"); - const GeoReplicationStatus GeoReplicationStatus::Unavailable("unavailable"); - } // namespace Models - namespace _detail { - Response ServiceClient::SetProperties( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const SetServicePropertiesOptions& options, - const Core::Context& context) - { - std::string xmlBody; - { - _internal::XmlWriter writer; - writer.Write( - _internal::XmlNode{_internal::XmlNodeType::StartTag, "StorageServiceProperties"}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Logging"}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "Version", - options.QueueServiceProperties.Logging.Version}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "Delete", - options.QueueServiceProperties.Logging.Delete ? "true" : "false"}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "Read", - options.QueueServiceProperties.Logging.Read ? "true" : "false"}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "Write", - options.QueueServiceProperties.Logging.Write ? "true" : "false"}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "RetentionPolicy"}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "Enabled", - options.QueueServiceProperties.Logging.RetentionPolicy.IsEnabled ? "true" : "false"}); - if (options.QueueServiceProperties.Logging.RetentionPolicy.Days.HasValue()) - { - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "Days", - std::to_string(options.QueueServiceProperties.Logging.RetentionPolicy.Days.Value())}); - } - writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "HourMetrics"}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "Version", - options.QueueServiceProperties.HourMetrics.Version}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "Enabled", - options.QueueServiceProperties.HourMetrics.IsEnabled ? "true" : "false"}); - if (options.QueueServiceProperties.HourMetrics.IncludeApis.HasValue()) - { - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "IncludeAPIs", - options.QueueServiceProperties.HourMetrics.IncludeApis.Value() ? "true" : "false"}); - } - writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "RetentionPolicy"}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "Enabled", - options.QueueServiceProperties.HourMetrics.RetentionPolicy.IsEnabled ? "true" - : "false"}); - if (options.QueueServiceProperties.HourMetrics.RetentionPolicy.Days.HasValue()) - { - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "Days", - std::to_string( - options.QueueServiceProperties.HourMetrics.RetentionPolicy.Days.Value())}); - } - writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "MinuteMetrics"}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "Version", - options.QueueServiceProperties.MinuteMetrics.Version}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "Enabled", - options.QueueServiceProperties.MinuteMetrics.IsEnabled ? "true" : "false"}); - if (options.QueueServiceProperties.MinuteMetrics.IncludeApis.HasValue()) - { - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "IncludeAPIs", - options.QueueServiceProperties.MinuteMetrics.IncludeApis.Value() ? "true" : "false"}); - } - writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "RetentionPolicy"}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "Enabled", - options.QueueServiceProperties.MinuteMetrics.RetentionPolicy.IsEnabled ? "true" - : "false"}); - if (options.QueueServiceProperties.MinuteMetrics.RetentionPolicy.Days.HasValue()) - { - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "Days", - std::to_string( - options.QueueServiceProperties.MinuteMetrics.RetentionPolicy.Days.Value())}); - } - writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Cors"}); - for (const auto& i1 : options.QueueServiceProperties.Cors) - { - writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "CorsRule"}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, "AllowedOrigins", i1.AllowedOrigins}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, "AllowedMethods", i1.AllowedMethods}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, "AllowedHeaders", i1.AllowedHeaders}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, "ExposedHeaders", i1.ExposedHeaders}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "MaxAgeInSeconds", - std::to_string(i1.MaxAgeInSeconds)}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); - } - writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::End}); - xmlBody = writer.GetDocument(); - } - Core::IO::MemoryBodyStream requestBody( - reinterpret_cast(xmlBody.data()), xmlBody.length()); - auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url, &requestBody); - request.SetHeader("Content-Type", "application/xml; charset=UTF-8"); - request.SetHeader("Content-Length", std::to_string(requestBody.Length())); - request.GetUrl().AppendQueryParameter("restype", "service"); - request.GetUrl().AppendQueryParameter("comp", "properties"); - request.SetHeader("x-ms-version", "2026-04-06"); - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::Accepted) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::SetServicePropertiesResult response; - return Response( - std::move(response), std::move(pRawResponse)); - } - Response ServiceClient::GetProperties( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const GetServicePropertiesOptions& options, - const Core::Context& context) - { - auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter("restype", "service"); - request.GetUrl().AppendQueryParameter("comp", "properties"); - request.SetHeader("x-ms-version", "2026-04-06"); - (void)options; - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::Ok) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::QueueServiceProperties response; - { - const auto& responseBody = pRawResponse->GetBody(); - _internal::XmlReader reader( - reinterpret_cast(responseBody.data()), responseBody.size()); - enum class XmlTagEnum - { - kUnknown, - kStorageServiceProperties, - kLogging, - kVersion, - kDelete, - kRead, - kWrite, - kRetentionPolicy, - kEnabled, - kDays, - kHourMetrics, - kIncludeAPIs, - kMinuteMetrics, - kCors, - kCorsRule, - kAllowedOrigins, - kAllowedMethods, - kAllowedHeaders, - kExposedHeaders, - kMaxAgeInSeconds, - }; - const std::unordered_map XmlTagEnumMap{ - {"StorageServiceProperties", XmlTagEnum::kStorageServiceProperties}, - {"Logging", XmlTagEnum::kLogging}, - {"Version", XmlTagEnum::kVersion}, - {"Delete", XmlTagEnum::kDelete}, - {"Read", XmlTagEnum::kRead}, - {"Write", XmlTagEnum::kWrite}, - {"RetentionPolicy", XmlTagEnum::kRetentionPolicy}, - {"Enabled", XmlTagEnum::kEnabled}, - {"Days", XmlTagEnum::kDays}, - {"HourMetrics", XmlTagEnum::kHourMetrics}, - {"IncludeAPIs", XmlTagEnum::kIncludeAPIs}, - {"MinuteMetrics", XmlTagEnum::kMinuteMetrics}, - {"Cors", XmlTagEnum::kCors}, - {"CorsRule", XmlTagEnum::kCorsRule}, - {"AllowedOrigins", XmlTagEnum::kAllowedOrigins}, - {"AllowedMethods", XmlTagEnum::kAllowedMethods}, - {"AllowedHeaders", XmlTagEnum::kAllowedHeaders}, - {"ExposedHeaders", XmlTagEnum::kExposedHeaders}, - {"MaxAgeInSeconds", XmlTagEnum::kMaxAgeInSeconds}, - }; - std::vector xmlPath; - Models::CorsRule vectorElement1; - 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() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kLogging && xmlPath[2] == XmlTagEnum::kVersion) - { - response.Logging.Version = node.Value; - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kLogging && xmlPath[2] == XmlTagEnum::kDelete) - { - response.Logging.Delete = node.Value == std::string("true"); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kLogging && xmlPath[2] == XmlTagEnum::kRead) - { - response.Logging.Read = node.Value == std::string("true"); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kLogging && xmlPath[2] == XmlTagEnum::kWrite) - { - response.Logging.Write = node.Value == std::string("true"); - } - else if ( - xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kLogging && xmlPath[2] == XmlTagEnum::kRetentionPolicy - && xmlPath[3] == XmlTagEnum::kEnabled) - { - response.Logging.RetentionPolicy.IsEnabled = node.Value == std::string("true"); - } - else if ( - xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kLogging && xmlPath[2] == XmlTagEnum::kRetentionPolicy - && xmlPath[3] == XmlTagEnum::kDays) - { - response.Logging.RetentionPolicy.Days = std::stoi(node.Value); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kHourMetrics && xmlPath[2] == XmlTagEnum::kVersion) - { - response.HourMetrics.Version = node.Value; - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kHourMetrics && xmlPath[2] == XmlTagEnum::kEnabled) - { - response.HourMetrics.IsEnabled = node.Value == std::string("true"); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kHourMetrics && xmlPath[2] == XmlTagEnum::kIncludeAPIs) - { - response.HourMetrics.IncludeApis = node.Value == std::string("true"); - } - else if ( - xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kHourMetrics - && xmlPath[2] == XmlTagEnum::kRetentionPolicy && xmlPath[3] == XmlTagEnum::kEnabled) - { - response.HourMetrics.RetentionPolicy.IsEnabled = node.Value == std::string("true"); - } - else if ( - xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kHourMetrics - && xmlPath[2] == XmlTagEnum::kRetentionPolicy && xmlPath[3] == XmlTagEnum::kDays) - { - response.HourMetrics.RetentionPolicy.Days = std::stoi(node.Value); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kMinuteMetrics && xmlPath[2] == XmlTagEnum::kVersion) - { - response.MinuteMetrics.Version = node.Value; - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kMinuteMetrics && xmlPath[2] == XmlTagEnum::kEnabled) - { - response.MinuteMetrics.IsEnabled = node.Value == std::string("true"); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kMinuteMetrics - && xmlPath[2] == XmlTagEnum::kIncludeAPIs) - { - response.MinuteMetrics.IncludeApis = node.Value == std::string("true"); - } - else if ( - xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kMinuteMetrics - && xmlPath[2] == XmlTagEnum::kRetentionPolicy && xmlPath[3] == XmlTagEnum::kEnabled) - { - response.MinuteMetrics.RetentionPolicy.IsEnabled = node.Value == std::string("true"); - } - else if ( - xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kMinuteMetrics - && xmlPath[2] == XmlTagEnum::kRetentionPolicy && xmlPath[3] == XmlTagEnum::kDays) - { - response.MinuteMetrics.RetentionPolicy.Days = std::stoi(node.Value); - } - else if ( - xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kCors && xmlPath[2] == XmlTagEnum::kCorsRule - && xmlPath[3] == XmlTagEnum::kAllowedOrigins) - { - vectorElement1.AllowedOrigins = node.Value; - } - else if ( - xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kCors && xmlPath[2] == XmlTagEnum::kCorsRule - && xmlPath[3] == XmlTagEnum::kAllowedMethods) - { - vectorElement1.AllowedMethods = node.Value; - } - else if ( - xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kCors && xmlPath[2] == XmlTagEnum::kCorsRule - && xmlPath[3] == XmlTagEnum::kAllowedHeaders) - { - vectorElement1.AllowedHeaders = node.Value; - } - else if ( - xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kCors && xmlPath[2] == XmlTagEnum::kCorsRule - && xmlPath[3] == XmlTagEnum::kExposedHeaders) - { - vectorElement1.ExposedHeaders = node.Value; - } - else if ( - xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kCors && xmlPath[2] == XmlTagEnum::kCorsRule - && xmlPath[3] == XmlTagEnum::kMaxAgeInSeconds) - { - vectorElement1.MaxAgeInSeconds = std::stoi(node.Value); - } - } - else if (node.Type == _internal::XmlNodeType::Attribute) - { - } - else if (node.Type == _internal::XmlNodeType::EndTag) - { - if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties - && xmlPath[1] == XmlTagEnum::kCors && xmlPath[2] == XmlTagEnum::kCorsRule) - { - response.Cors.push_back(std::move(vectorElement1)); - vectorElement1 = Models::CorsRule(); - } - xmlPath.pop_back(); - } - } - } - return Response(std::move(response), std::move(pRawResponse)); - } - Response ServiceClient::GetStatistics( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const GetServiceStatisticsOptions& options, - const Core::Context& context) - { - auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter("restype", "service"); - request.GetUrl().AppendQueryParameter("comp", "stats"); - request.SetHeader("x-ms-version", "2026-04-06"); - (void)options; - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::Ok) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::ServiceStatistics response; - { - const auto& responseBody = pRawResponse->GetBody(); - _internal::XmlReader reader( - reinterpret_cast(responseBody.data()), responseBody.size()); - enum class XmlTagEnum - { - kUnknown, - kStorageServiceStats, - kGeoReplication, - kStatus, - kLastSyncTime, - }; - const std::unordered_map XmlTagEnumMap{ - {"StorageServiceStats", XmlTagEnum::kStorageServiceStats}, - {"GeoReplication", XmlTagEnum::kGeoReplication}, - {"Status", XmlTagEnum::kStatus}, - {"LastSyncTime", XmlTagEnum::kLastSyncTime}, - }; - std::vector xmlPath; - - 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() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceStats - && xmlPath[1] == XmlTagEnum::kGeoReplication && xmlPath[2] == XmlTagEnum::kStatus) - { - response.GeoReplication.Status = Models::GeoReplicationStatus(node.Value); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceStats - && xmlPath[1] == XmlTagEnum::kGeoReplication - && xmlPath[2] == XmlTagEnum::kLastSyncTime) - { - response.GeoReplication.LastSyncedOn - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - } - else if (node.Type == _internal::XmlNodeType::Attribute) - { - } - else if (node.Type == _internal::XmlNodeType::EndTag) - { - - xmlPath.pop_back(); - } - } - } - return Response(std::move(response), std::move(pRawResponse)); - } - Response ServiceClient::GetUserDelegationKey( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const GetServiceUserDelegationKeyOptions& options, - const Core::Context& context) - { - std::string xmlBody; - { - _internal::XmlWriter writer; - writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "KeyInfo"}); - if (options.KeyInfo.Start.HasValue()) - { - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, "Start", options.KeyInfo.Start.Value()}); - } - writer.Write( - _internal::XmlNode{_internal::XmlNodeType::StartTag, "Expiry", options.KeyInfo.Expiry}); - if (options.KeyInfo.DelegatedUserTid.HasValue()) - { - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "DelegatedUserTid", - options.KeyInfo.DelegatedUserTid.Value()}); - } - writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::End}); - xmlBody = writer.GetDocument(); - } - Core::IO::MemoryBodyStream requestBody( - reinterpret_cast(xmlBody.data()), xmlBody.length()); - auto request = Core::Http::Request(Core::Http::HttpMethod::Post, url, &requestBody); - request.SetHeader("Content-Type", "application/xml; charset=UTF-8"); - request.SetHeader("Content-Length", std::to_string(requestBody.Length())); - request.GetUrl().AppendQueryParameter("restype", "service"); - request.GetUrl().AppendQueryParameter("comp", "userdelegationkey"); - request.SetHeader("x-ms-version", "2026-04-06"); - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::Ok) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::UserDelegationKey response; - { - const auto& responseBody = pRawResponse->GetBody(); - _internal::XmlReader reader( - reinterpret_cast(responseBody.data()), responseBody.size()); - enum class XmlTagEnum - { - kUnknown, - kUserDelegationKey, - kSignedOid, - kSignedTid, - kSignedStart, - kSignedExpiry, - kSignedService, - kSignedVersion, - kSignedDelegatedUserTid, - kValue, - }; - const std::unordered_map XmlTagEnumMap{ - {"UserDelegationKey", XmlTagEnum::kUserDelegationKey}, - {"SignedOid", XmlTagEnum::kSignedOid}, - {"SignedTid", XmlTagEnum::kSignedTid}, - {"SignedStart", XmlTagEnum::kSignedStart}, - {"SignedExpiry", XmlTagEnum::kSignedExpiry}, - {"SignedService", XmlTagEnum::kSignedService}, - {"SignedVersion", XmlTagEnum::kSignedVersion}, - {"SignedDelegatedUserTid", XmlTagEnum::kSignedDelegatedUserTid}, - {"Value", XmlTagEnum::kValue}, - }; - std::vector xmlPath; - - 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::kUserDelegationKey - && xmlPath[1] == XmlTagEnum::kSignedOid) - { - response.SignedObjectId = node.Value; - } - else if ( - xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kUserDelegationKey - && xmlPath[1] == XmlTagEnum::kSignedTid) - { - response.SignedTenantId = node.Value; - } - else if ( - xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kUserDelegationKey - && xmlPath[1] == XmlTagEnum::kSignedStart) - { - response.SignedStartsOn - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc3339); - } - else if ( - xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kUserDelegationKey - && xmlPath[1] == XmlTagEnum::kSignedExpiry) - { - response.SignedExpiresOn - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc3339); - } - else if ( - xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kUserDelegationKey - && xmlPath[1] == XmlTagEnum::kSignedService) - { - response.SignedService = node.Value; - } - else if ( - xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kUserDelegationKey - && xmlPath[1] == XmlTagEnum::kSignedVersion) - { - response.SignedVersion = node.Value; - } - else if ( - xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kUserDelegationKey - && xmlPath[1] == XmlTagEnum::kSignedDelegatedUserTid) - { - response.SignedDelegatedUserTid = node.Value; - } - else if ( - xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kUserDelegationKey - && xmlPath[1] == XmlTagEnum::kValue) - { - response.Value = node.Value; - } - } - else if (node.Type == _internal::XmlNodeType::Attribute) - { - } - else if (node.Type == _internal::XmlNodeType::EndTag) - { - - xmlPath.pop_back(); - } - } - } - return Response(std::move(response), std::move(pRawResponse)); - } - Response ServiceClient::ListQueuesSegment( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const ListServiceQueuesSegmentOptions& options, - const Core::Context& context) - { - auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter("comp", "list"); - if (options.Prefix.HasValue() && !options.Prefix.Value().empty()) - { - request.GetUrl().AppendQueryParameter( - "prefix", _internal::UrlEncodeQueryParameter(options.Prefix.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() - && !ListQueuesIncludeFlagsToString(options.Include.Value()).empty()) - { - request.GetUrl().AppendQueryParameter( - "include", - _internal::UrlEncodeQueryParameter( - ListQueuesIncludeFlagsToString(options.Include.Value()))); - } - request.SetHeader("x-ms-version", "2026-04-06"); - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::Ok) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::_detail::ListQueuesResult response; - { - const auto& responseBody = pRawResponse->GetBody(); - _internal::XmlReader reader( - reinterpret_cast(responseBody.data()), responseBody.size()); - enum class XmlTagEnum - { - kUnknown, - kEnumerationResults, - kPrefix, - kQueues, - kQueue, - kName, - kMetadata, - kNextMarker, - }; - const std::unordered_map XmlTagEnumMap{ - {"EnumerationResults", XmlTagEnum::kEnumerationResults}, - {"Prefix", XmlTagEnum::kPrefix}, - {"Queues", XmlTagEnum::kQueues}, - {"Queue", XmlTagEnum::kQueue}, - {"Name", XmlTagEnum::kName}, - {"Metadata", XmlTagEnum::kMetadata}, - {"NextMarker", XmlTagEnum::kNextMarker}, - }; - std::vector xmlPath; - Models::QueueItem vectorElement1; - std::string mapKey2; - std::string mapValue3; - 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); - if (xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kQueues && xmlPath[2] == XmlTagEnum::kQueue - && xmlPath[3] == XmlTagEnum::kMetadata) - { - mapKey2 = node.Name; - } - } - 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() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kQueues && xmlPath[2] == XmlTagEnum::kQueue - && xmlPath[3] == XmlTagEnum::kName) - { - vectorElement1.Name = node.Value; - } - else if ( - xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kQueues && xmlPath[2] == XmlTagEnum::kQueue - && xmlPath[3] == XmlTagEnum::kMetadata) - { - mapValue3 = node.Value; - } - else if ( - xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kNextMarker) - { - response.ContinuationToken = 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 (node.Type == _internal::XmlNodeType::EndTag) - { - if (xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kQueues && xmlPath[2] == XmlTagEnum::kQueue - && xmlPath[3] == XmlTagEnum::kMetadata) - { - vectorElement1.Metadata[std::move(mapKey2)] = std::move(mapValue3); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kEnumerationResults - && xmlPath[1] == XmlTagEnum::kQueues && xmlPath[2] == XmlTagEnum::kQueue) - { - response.Items.push_back(std::move(vectorElement1)); - vectorElement1 = Models::QueueItem(); - } - xmlPath.pop_back(); - } - } - } - return Response( - std::move(response), std::move(pRawResponse)); - } - Response QueueClient::Create( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const CreateQueueOptions& options, - const Core::Context& context) - { - auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); - for (const auto& p : options.Metadata) - { - request.SetHeader("x-ms-meta-" + p.first, p.second); - } - request.SetHeader("x-ms-version", "2026-04-06"); - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (!(httpStatusCode == Core::Http::HttpStatusCode::Created - || httpStatusCode == Core::Http::HttpStatusCode::NoContent)) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::CreateQueueResult response; - return Response(std::move(response), std::move(pRawResponse)); - } - Response QueueClient::Delete( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const DeleteQueueOptions& options, - const Core::Context& context) - { - auto request = Core::Http::Request(Core::Http::HttpMethod::Delete, url); - request.SetHeader("x-ms-version", "2026-04-06"); - (void)options; - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::NoContent) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::DeleteQueueResult response; - return Response(std::move(response), std::move(pRawResponse)); - } - Response QueueClient::GetProperties( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const GetQueuePropertiesOptions& options, - const Core::Context& context) - { - auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter("comp", "metadata"); - request.SetHeader("x-ms-version", "2026-04-06"); - (void)options; - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::Ok) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::_detail::QueueProperties response; - for (auto i = pRawResponse->GetHeaders().lower_bound("x-ms-meta-"); - i != pRawResponse->GetHeaders().end() && i->first.substr(0, 10) == "x-ms-meta-"; - ++i) - { - response.Metadata.emplace(i->first.substr(10), i->second); - } - response.ApproximateMessageCount - = std::stoll(pRawResponse->GetHeaders().at("x-ms-approximate-messages-count")); - return Response( - std::move(response), std::move(pRawResponse)); - } - Response QueueClient::SetMetadata( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const SetQueueMetadataOptions& options, - const Core::Context& context) - { - auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); - request.GetUrl().AppendQueryParameter("comp", "metadata"); - for (const auto& p : options.Metadata) - { - request.SetHeader("x-ms-meta-" + p.first, p.second); - } - request.SetHeader("x-ms-version", "2026-04-06"); - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::NoContent) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::SetQueueMetadataResult response; - return Response(std::move(response), std::move(pRawResponse)); - } - Response QueueClient::GetAccessPolicy( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const GetQueueAccessPolicyOptions& options, - const Core::Context& context) - { - auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter("comp", "acl"); - request.SetHeader("x-ms-version", "2026-04-06"); - (void)options; - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::Ok) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::QueueAccessPolicy response; - { - const auto& responseBody = pRawResponse->GetBody(); - _internal::XmlReader reader( - reinterpret_cast(responseBody.data()), responseBody.size()); - enum class XmlTagEnum - { - kUnknown, - kSignedIdentifiers, - kSignedIdentifier, - kId, - kAccessPolicy, - kStart, - kExpiry, - kPermission, - }; - const std::unordered_map XmlTagEnumMap{ - {"SignedIdentifiers", XmlTagEnum::kSignedIdentifiers}, - {"SignedIdentifier", XmlTagEnum::kSignedIdentifier}, - {"Id", XmlTagEnum::kId}, - {"AccessPolicy", XmlTagEnum::kAccessPolicy}, - {"Start", XmlTagEnum::kStart}, - {"Expiry", XmlTagEnum::kExpiry}, - {"Permission", XmlTagEnum::kPermission}, - }; - std::vector xmlPath; - Models::SignedIdentifier vectorElement1; - 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() == 3 && xmlPath[0] == XmlTagEnum::kSignedIdentifiers - && xmlPath[1] == XmlTagEnum::kSignedIdentifier && xmlPath[2] == XmlTagEnum::kId) - { - vectorElement1.Id = node.Value; - } - else if ( - xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kSignedIdentifiers - && xmlPath[1] == XmlTagEnum::kSignedIdentifier - && xmlPath[2] == XmlTagEnum::kAccessPolicy && xmlPath[3] == XmlTagEnum::kStart) - { - vectorElement1.StartsOn - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc3339); - } - else if ( - xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kSignedIdentifiers - && xmlPath[1] == XmlTagEnum::kSignedIdentifier - && xmlPath[2] == XmlTagEnum::kAccessPolicy && xmlPath[3] == XmlTagEnum::kExpiry) - { - vectorElement1.ExpiresOn - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc3339); - } - else if ( - xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kSignedIdentifiers - && xmlPath[1] == XmlTagEnum::kSignedIdentifier - && xmlPath[2] == XmlTagEnum::kAccessPolicy && xmlPath[3] == XmlTagEnum::kPermission) - { - vectorElement1.Permissions = node.Value; - } - } - else if (node.Type == _internal::XmlNodeType::Attribute) - { - } - else if (node.Type == _internal::XmlNodeType::EndTag) - { - if (xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kSignedIdentifiers - && xmlPath[1] == XmlTagEnum::kSignedIdentifier) - { - response.SignedIdentifiers.push_back(std::move(vectorElement1)); - vectorElement1 = Models::SignedIdentifier(); - } - xmlPath.pop_back(); - } - } - } - return Response(std::move(response), std::move(pRawResponse)); - } - Response QueueClient::SetAccessPolicy( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const SetQueueAccessPolicyOptions& options, - const Core::Context& context) - { - std::string xmlBody; - { - _internal::XmlWriter writer; - writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "SignedIdentifiers"}); - for (const auto& i1 : options.QueueAcl) - { - writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "SignedIdentifier"}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Id", i1.Id}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "AccessPolicy"}); - if (i1.StartsOn.HasValue()) - { - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "Start", - i1.StartsOn.Value().ToString( - Azure::DateTime::DateFormat::Rfc3339, - Azure::DateTime::TimeFractionFormat::AllDigits)}); - } - if (i1.ExpiresOn.HasValue()) - { - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, - "Expiry", - i1.ExpiresOn.Value().ToString( - Azure::DateTime::DateFormat::Rfc3339, - Azure::DateTime::TimeFractionFormat::AllDigits)}); - } - writer.Write( - _internal::XmlNode{_internal::XmlNodeType::StartTag, "Permission", i1.Permissions}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); - } - writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::End}); - xmlBody = writer.GetDocument(); - } - Core::IO::MemoryBodyStream requestBody( - reinterpret_cast(xmlBody.data()), xmlBody.length()); - auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url, &requestBody); - request.SetHeader("Content-Type", "application/xml; charset=UTF-8"); - request.SetHeader("Content-Length", std::to_string(requestBody.Length())); - request.GetUrl().AppendQueryParameter("comp", "acl"); - request.SetHeader("x-ms-version", "2026-04-06"); - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::NoContent) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::SetQueueAccessPolicyResult response; - return Response( - std::move(response), std::move(pRawResponse)); - } - Response QueueClient::ReceiveMessages( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const ReceiveQueueMessagesOptions& options, - const Core::Context& context) - { - auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); - if (options.NumberOfMessages.HasValue()) - { - request.GetUrl().AppendQueryParameter( - "numofmessages", std::to_string(options.NumberOfMessages.Value())); - } - if (options.Visibilitytimeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - "visibilitytimeout", std::to_string(options.Visibilitytimeout.Value())); - } - request.SetHeader("x-ms-version", "2026-04-06"); - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::Ok) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::ReceivedMessages response; - { - const auto& responseBody = pRawResponse->GetBody(); - _internal::XmlReader reader( - reinterpret_cast(responseBody.data()), responseBody.size()); - enum class XmlTagEnum - { - kUnknown, - kQueueMessagesList, - kQueueMessage, - kMessageId, - kInsertionTime, - kExpirationTime, - kPopReceipt, - kTimeNextVisible, - kDequeueCount, - kMessageText, - }; - const std::unordered_map XmlTagEnumMap{ - {"QueueMessagesList", XmlTagEnum::kQueueMessagesList}, - {"QueueMessage", XmlTagEnum::kQueueMessage}, - {"MessageId", XmlTagEnum::kMessageId}, - {"InsertionTime", XmlTagEnum::kInsertionTime}, - {"ExpirationTime", XmlTagEnum::kExpirationTime}, - {"PopReceipt", XmlTagEnum::kPopReceipt}, - {"TimeNextVisible", XmlTagEnum::kTimeNextVisible}, - {"DequeueCount", XmlTagEnum::kDequeueCount}, - {"MessageText", XmlTagEnum::kMessageText}, - }; - std::vector xmlPath; - Models::QueueMessage vectorElement1; - 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() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage && xmlPath[2] == XmlTagEnum::kMessageId) - { - vectorElement1.MessageId = node.Value; - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage - && xmlPath[2] == XmlTagEnum::kInsertionTime) - { - vectorElement1.InsertedOn - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage - && xmlPath[2] == XmlTagEnum::kExpirationTime) - { - vectorElement1.ExpiresOn - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage && xmlPath[2] == XmlTagEnum::kPopReceipt) - { - vectorElement1.PopReceipt = node.Value; - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage - && xmlPath[2] == XmlTagEnum::kTimeNextVisible) - { - vectorElement1.NextVisibleOn - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage - && xmlPath[2] == XmlTagEnum::kDequeueCount) - { - vectorElement1.DequeueCount = std::stoll(node.Value); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage - && xmlPath[2] == XmlTagEnum::kMessageText) - { - vectorElement1.MessageText = node.Value; - } - } - else if (node.Type == _internal::XmlNodeType::Attribute) - { - } - else if (node.Type == _internal::XmlNodeType::EndTag) - { - if (xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage) - { - response.Messages.push_back(std::move(vectorElement1)); - vectorElement1 = Models::QueueMessage(); - } - xmlPath.pop_back(); - } - } - } - return Response(std::move(response), std::move(pRawResponse)); - } - Response QueueClient::ClearMessages( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const ClearQueueMessagesOptions& options, - const Core::Context& context) - { - auto request = Core::Http::Request(Core::Http::HttpMethod::Delete, url); - request.SetHeader("x-ms-version", "2026-04-06"); - (void)options; - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::NoContent) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::ClearMessagesResult response; - return Response(std::move(response), std::move(pRawResponse)); - } - Response QueueClient::EnqueueMessage( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const EnqueueQueueMessageOptions& options, - const Core::Context& context) - { - std::string xmlBody; - { - _internal::XmlWriter writer; - writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "QueueMessage"}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, "MessageText", options.QueueMessage.MessageText}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::End}); - xmlBody = writer.GetDocument(); - } - Core::IO::MemoryBodyStream requestBody( - reinterpret_cast(xmlBody.data()), xmlBody.length()); - auto request = Core::Http::Request(Core::Http::HttpMethod::Post, url, &requestBody); - request.SetHeader("Content-Type", "application/xml; charset=UTF-8"); - request.SetHeader("Content-Length", std::to_string(requestBody.Length())); - if (options.Visibilitytimeout.HasValue()) - { - request.GetUrl().AppendQueryParameter( - "visibilitytimeout", std::to_string(options.Visibilitytimeout.Value())); - } - if (options.MessageTimeToLive.HasValue()) - { - request.GetUrl().AppendQueryParameter( - "messagettl", std::to_string(options.MessageTimeToLive.Value())); - } - request.SetHeader("x-ms-version", "2026-04-06"); - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::Created) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::EnqueueMessageResult response; - { - const auto& responseBody = pRawResponse->GetBody(); - _internal::XmlReader reader( - reinterpret_cast(responseBody.data()), responseBody.size()); - enum class XmlTagEnum - { - kUnknown, - kQueueMessagesList, - kQueueMessage, - kMessageId, - kInsertionTime, - kExpirationTime, - kPopReceipt, - kTimeNextVisible, - }; - const std::unordered_map XmlTagEnumMap{ - {"QueueMessagesList", XmlTagEnum::kQueueMessagesList}, - {"QueueMessage", XmlTagEnum::kQueueMessage}, - {"MessageId", XmlTagEnum::kMessageId}, - {"InsertionTime", XmlTagEnum::kInsertionTime}, - {"ExpirationTime", XmlTagEnum::kExpirationTime}, - {"PopReceipt", XmlTagEnum::kPopReceipt}, - {"TimeNextVisible", XmlTagEnum::kTimeNextVisible}, - }; - std::vector xmlPath; - - 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() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage && xmlPath[2] == XmlTagEnum::kMessageId) - { - response.MessageId = node.Value; - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage - && xmlPath[2] == XmlTagEnum::kInsertionTime) - { - response.InsertedOn - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage - && xmlPath[2] == XmlTagEnum::kExpirationTime) - { - response.ExpiresOn - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage && xmlPath[2] == XmlTagEnum::kPopReceipt) - { - response.PopReceipt = node.Value; - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage - && xmlPath[2] == XmlTagEnum::kTimeNextVisible) - { - response.NextVisibleOn - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - } - else if (node.Type == _internal::XmlNodeType::Attribute) - { - } - else if (node.Type == _internal::XmlNodeType::EndTag) - { - - xmlPath.pop_back(); - } - } - } - return Response(std::move(response), std::move(pRawResponse)); - } - Response QueueClient::PeekMessages( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const PeekQueueMessagesOptions& options, - const Core::Context& context) - { - auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); - request.GetUrl().AppendQueryParameter("peekonly", "true"); - if (options.NumberOfMessages.HasValue()) - { - request.GetUrl().AppendQueryParameter( - "numofmessages", std::to_string(options.NumberOfMessages.Value())); - } - request.SetHeader("x-ms-version", "2026-04-06"); - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::Ok) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::PeekedMessages response; - { - const auto& responseBody = pRawResponse->GetBody(); - _internal::XmlReader reader( - reinterpret_cast(responseBody.data()), responseBody.size()); - enum class XmlTagEnum - { - kUnknown, - kQueueMessagesList, - kQueueMessage, - kMessageId, - kInsertionTime, - kExpirationTime, - kDequeueCount, - kMessageText, - }; - const std::unordered_map XmlTagEnumMap{ - {"QueueMessagesList", XmlTagEnum::kQueueMessagesList}, - {"QueueMessage", XmlTagEnum::kQueueMessage}, - {"MessageId", XmlTagEnum::kMessageId}, - {"InsertionTime", XmlTagEnum::kInsertionTime}, - {"ExpirationTime", XmlTagEnum::kExpirationTime}, - {"DequeueCount", XmlTagEnum::kDequeueCount}, - {"MessageText", XmlTagEnum::kMessageText}, - }; - std::vector xmlPath; - Models::PeekedQueueMessage vectorElement1; - 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() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage && xmlPath[2] == XmlTagEnum::kMessageId) - { - vectorElement1.MessageId = node.Value; - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage - && xmlPath[2] == XmlTagEnum::kInsertionTime) - { - vectorElement1.InsertedOn - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage - && xmlPath[2] == XmlTagEnum::kExpirationTime) - { - vectorElement1.ExpiresOn - = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage - && xmlPath[2] == XmlTagEnum::kDequeueCount) - { - vectorElement1.DequeueCount = std::stoll(node.Value); - } - else if ( - xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage - && xmlPath[2] == XmlTagEnum::kMessageText) - { - vectorElement1.MessageText = node.Value; - } - } - else if (node.Type == _internal::XmlNodeType::Attribute) - { - } - else if (node.Type == _internal::XmlNodeType::EndTag) - { - if (xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kQueueMessagesList - && xmlPath[1] == XmlTagEnum::kQueueMessage) - { - response.Messages.push_back(std::move(vectorElement1)); - vectorElement1 = Models::PeekedQueueMessage(); - } - xmlPath.pop_back(); - } - } - } - return Response(std::move(response), std::move(pRawResponse)); - } - Response QueueClient::UpdateMessage( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const UpdateQueueMessageOptions& options, - const Core::Context& context) - { - std::string xmlBody; - { - _internal::XmlWriter writer; - writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "QueueMessage"}); - writer.Write(_internal::XmlNode{ - _internal::XmlNodeType::StartTag, "MessageText", options.QueueMessage.MessageText}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); - writer.Write(_internal::XmlNode{_internal::XmlNodeType::End}); - xmlBody = writer.GetDocument(); - } - Core::IO::MemoryBodyStream requestBody( - reinterpret_cast(xmlBody.data()), xmlBody.length()); - auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url, &requestBody); - request.SetHeader("Content-Type", "application/xml; charset=UTF-8"); - request.SetHeader("Content-Length", std::to_string(requestBody.Length())); - if (!options.PopReceipt.empty()) - { - request.GetUrl().AppendQueryParameter( - "popreceipt", _internal::UrlEncodeQueryParameter(options.PopReceipt)); - } - request.GetUrl().AppendQueryParameter( - "visibilitytimeout", std::to_string(options.Visibilitytimeout)); - request.SetHeader("x-ms-version", "2026-04-06"); - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::NoContent) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::UpdateMessageResult response; - response.PopReceipt = pRawResponse->GetHeaders().at("x-ms-popreceipt"); - response.NextVisibleOn = DateTime::Parse( - pRawResponse->GetHeaders().at("x-ms-time-next-visible"), - Azure::DateTime::DateFormat::Rfc1123); - return Response(std::move(response), std::move(pRawResponse)); - } - Response QueueClient::DeleteMessage( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const DeleteQueueMessageOptions& options, - const Core::Context& context) - { - auto request = Core::Http::Request(Core::Http::HttpMethod::Delete, url); - if (!options.PopReceipt.empty()) - { - request.GetUrl().AppendQueryParameter( - "popreceipt", _internal::UrlEncodeQueryParameter(options.PopReceipt)); - } - request.SetHeader("x-ms-version", "2026-04-06"); - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::NoContent) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::DeleteMessageResult response; - return Response(std::move(response), std::move(pRawResponse)); - } - Response QueueClient::UpdateMessageVisibility( - Core::Http::_internal::HttpPipeline& pipeline, - const Core::Url& url, - const UpdateQueueMessageVisibilityOptions& options, - const Core::Context& context) - { - auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); - if (!options.PopReceipt.empty()) - { - request.GetUrl().AppendQueryParameter( - "popreceipt", _internal::UrlEncodeQueryParameter(options.PopReceipt)); - } - request.GetUrl().AppendQueryParameter( - "visibilitytimeout", std::to_string(options.Visibilitytimeout)); - request.SetHeader("x-ms-version", "2026-04-06"); - auto pRawResponse = pipeline.Send(request, context); - auto httpStatusCode = pRawResponse->GetStatusCode(); - if (httpStatusCode != Core::Http::HttpStatusCode::NoContent) - { - throw StorageException::CreateFromResponse(std::move(pRawResponse)); - } - Models::UpdateMessageResult response; - response.PopReceipt = pRawResponse->GetHeaders().at("x-ms-popreceipt"); - response.NextVisibleOn = DateTime::Parse( - pRawResponse->GetHeaders().at("x-ms-time-next-visible"), - Azure::DateTime::DateFormat::Rfc1123); - return Response(std::move(response), std::move(pRawResponse)); - } - } // namespace _detail -}}} // namespace Azure::Storage::Queues \ No newline at end of file diff --git a/sdk/storage/azure-storage-queues/swagger/README.md b/sdk/storage/azure-storage-queues/swagger/README.md deleted file mode 100644 index c1e5cc7424..0000000000 --- a/sdk/storage/azure-storage-queues/swagger/README.md +++ /dev/null @@ -1,460 +0,0 @@ -# Azure Storage C++ Protocol Layer - -> see https://aka.ms/autorest - -## Configuration - -```yaml -package-name: azure-storage-queues -namespace: Azure::Storage::Queues -output-folder: generated -clear-output-folder: true -input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/refs/heads/main/specification/storage/data-plane/Microsoft.QueueStorage/stable/2026-04-06/queue.json -``` - -## ModelFour Options - -```yaml -modelerfour: - naming: - property: pascal - parameter: pascal -``` - -## Customizations for Track 2 Generator - -See the [AutoRest samples](https://github.com/Azure/autorest/tree/master/Samples/3b-custom-transformations) -for more about how we're customizing things. - -### Fix Generator Warnings - -```yaml -directive: - - from: swagger-document - where: $.info - transform: > - delete $["x-ms-code-generation-settings"]; - - from: swagger-document - where: $.definitions - transform: > - delete $.DequeuedMessagesList.items.xml; - delete $.PeekedMessagesList.items.xml; - delete $.EnqueuedMessageList.items.xml; - delete $.SignedIdentifiers.items.xml; - delete $.StorageServiceProperties.properties.Cors.items.xml; -``` - -### Delete Unused Query Parameters and Headers - -```yaml -directive: - - from: swagger-document - where: $["x-ms-paths"].*.*.parameters - transform: > - $ = $.filter(p => !(p["$ref"] && (p["$ref"].endsWith("#/parameters/Timeout") || p["$ref"].endsWith("#/parameters/ClientRequestId")))); - - from: swagger-document - where: $["x-ms-paths"].*.*.responses.*.headers - transform: > - for (const h in $) { - if (["x-ms-client-request-id", "x-ms-request-id", "x-ms-version", "Date"].includes(h)) { - delete $[h]; - } - } -``` - -### API Version - -```yaml -directive: - - from: swagger-document - where: $.definitions - transform: > - $.ApiVersion = { - "type": "string", - "x-ms-export": true, - "x-namespace": "_detail", - "x-ms-enum": { - "name": "ApiVersion", - "modelAsString": false - }, - "enum": ["2026-04-06"], - "description": "The version used for the operations to Azure storage services." - }; - - from: swagger-document - where: $.parameters - transform: > - $.ApiVersionParameter.enum = ["2026-04-06"]; -``` - -### Rename Operations - -```yaml -directive: - - from: swagger-document - where: $["x-ms-paths"] - transform: > - $["/{queueName}/messages"].get.operationId = "Queue_ReceiveMessages"; - $["/{queueName}/messages"].delete.operationId = "Queue_ClearMessages"; - $["/{queueName}/messages"].post.operationId = "Queue_EnqueueMessage"; - $["/{queueName}/messages?peekonly=true"].get.operationId = "Queue_PeekMessages"; - $["/{queueName}/messages/{messageid}"].put.operationId = "Queue_UpdateMessage"; - $["/{queueName}/messages/{messageid}"].delete.operationId = "Queue_DeleteMessage"; -``` - -### Define names for return types - -```yaml -directive: - - from: swagger-document - where: $ - transform: > - const operationReturnTypeNames = new Map(Object.entries({ - "Queue_ClearMessages": "ClearMessagesResult", - "Queue_UpdateMessage": "UpdateMessageResult", - "Queue_DeleteMessage": "DeleteMessageResult", - "Service_SetProperties": "SetServicePropertiesResult", - })); - for (const url in $["x-ms-paths"]) { - for (const verb in $["x-ms-paths"][url]) { - const operation = $["x-ms-paths"][url][verb]; - if (!operationReturnTypeNames.has(operation.operationId)) { - continue; - } - const returnTypeName = operationReturnTypeNames.get(operation.operationId); - const status_codes = Object.keys(operation.responses).filter(s => s !== "default"); - const emptySchemaDefinition = { - "type": "object", - "x-ms-client-name": returnTypeName, - "x-ms-sealed": false, - "properties": { - "__placeHolder": {"type": "integer"} - } - }; - $.definitions[returnTypeName] = emptySchemaDefinition; - status_codes.map(i => { - operation.responses[i].schema = {"$ref": `#/definitions/${returnTypeName}`}; - }); - } - } - - from: swagger-document - where: $.definitions - transform: > - $.KeyInfo["x-namespace"] = "_detail"; -``` - -### Global Changes for Definitions, Types etc. - -```yaml -directive: - - from: swagger-document - where: $.parameters - transform: > - $.NumOfMessages.format = "int64"; - $.MaxResults["x-ms-client-name"] = "MaxResults"; -``` - -### GetServiceProperties - -```yaml -directive: - - from: swagger-document - where: $.definitions - transform: > - $.QueueServiceProperties = $.StorageServiceProperties; - delete $.StorageServiceProperties; - $.QueueServiceProperties.xml = { "name": "StorageServiceProperties" }; - $.RetentionPolicy.properties["Enabled"]["x-ms-client-name"] = "IsEnabled"; - $.AnalyticsLogging = $.Logging; - delete $.Logging; - $.AnalyticsLogging.xml = { "name": "Logging" }; - $.QueueServiceProperties.properties["Logging"]["$ref"] = "#/definitions/AnalyticsLogging"; - $.Metrics["type"] = "object"; - $.Metrics.properties["Enabled"]["x-ms-client-name"] = "IsEnabled"; - $.Metrics.properties["IncludeAPIs"]["x-ms-client-name"] = "IncludeApis"; - delete $.Metrics.required; - $.Metrics.properties["IncludeAPIs"]["x-nullable"] = true; - - from: swagger-document - where: $.parameters - transform: > - $.QueueServiceProperties = $.StorageServiceProperties; - $.QueueServiceProperties.name = "QueueServiceProperties"; - $.QueueServiceProperties.schema["$ref"] = "#/definitions/QueueServiceProperties"; - delete $.StorageServiceProperties; - - from: swagger-document - where: $["x-ms-paths"]["/?restype=service&comp=properties"] - transform: > - $.put.parameters[0]["$ref"] = "#/parameters/QueueServiceProperties"; - $.get.responses["200"].schema["$ref"] = "#/definitions/QueueServiceProperties"; -``` - -### GetServiceStatistics - -```yaml -directive: - - from: swagger-document - where: $.definitions - transform: > - $.ServiceStatistics = $.StorageServiceStats; - delete $.StorageServiceStats; - $.ServiceStatistics["xml"] = { "name": "StorageServiceStats" }; - $.GeoReplication.properties["LastSyncTime"]["x-ms-client-name"] = "LastSyncedOn"; - $.GeoReplication.required = ["Status"]; - $.GeoReplication.properties["Status"]["x-ms-enum"]["name"] = "GeoReplicationStatus"; - - from: swagger-document - where: $["x-ms-paths"]["/?restype=service&comp=stats"] - transform: > - $.get.responses["200"].schema["$ref"] = "#/definitions/ServiceStatistics"; -``` - -### GetUserDelegationKey - -```yaml -directive: - - from: swagger-document - where: $.definitions - transform: > - $.UserDelegationKey.properties["SignedOid"]["x-ms-client-name"] = "SignedObjectId"; - $.UserDelegationKey.properties["SignedTid"]["x-ms-client-name"] = "SignedTenantId"; - $.UserDelegationKey.properties["SignedStart"]["x-ms-client-name"] = "SignedStartsOn"; - $.UserDelegationKey.properties["SignedExpiry"]["x-ms-client-name"] = "SignedExpiresOn"; -``` - -### ListQueues - -```yaml -directive: - - from: swagger-document - where: $.parameters - transform: > - $.ListQueuesInclude.items["x-ms-enum"]["name"] = "ListQueuesIncludeFlags"; - - from: swagger-document - where: $.definitions - transform: > - $.Metadata = {"type": "object", "x-ms-format": "caseinsensitivemap", properties: {"__placeHolder" : {"type": "integer"}}}; - $.ListQueuesSegmentResponse["x-ms-client-name"] = "ListQueuesResult"; - $.ListQueuesSegmentResponse["x-namespace"] = "_detail"; - $.ListQueuesSegmentResponse.properties["QueueItems"]["x-ms-client-name"] = "Items"; - $.ListQueuesSegmentResponse.properties["QueueItems"]["x-ms-xml"] = {"name": "Queues"}; - $.ListQueuesSegmentResponse.properties["NextMarker"]["x-ms-client-name"] = "ContinuationToken"; - $.ListQueuesSegmentResponse.required = ["ServiceEndpoint", "Prefix"]; - delete $.ListQueuesSegmentResponse.properties["Marker"]; - delete $.ListQueuesSegmentResponse.properties["MaxResults"]; -``` - -### CreateQueue - -```yaml -directive: - - from: swagger-document - where: $.definitions - transform: > - $.CreateQueueResult = { - "type": "object", - "properties": { - "Created": {"type": "boolean", "x-ms-xml": {"name": ""}} - } - }; - - from: swagger-document - where: $["x-ms-paths"]["/{queueName}"].put.responses - transform: > - $["201"].schema = {"$ref": "#/definitions/CreateQueueResult"}; - $["204"].schema = {"$ref": "#/definitions/CreateQueueResult"}; -``` - -### DeleteQueue - -```yaml -directive: - - from: swagger-document - where: $["x-ms-paths"]["/{queueName}"].delete.responses["204"] - transform: > - $.schema = { - "type": "object", - "x-ms-client-name": "DeleteQueueResult", - "x-ms-sealed": false, - "properties": { - "Deleted": {"type": "boolean", "x-ms-client-default": true, "x-ms-xml": {"name": ""}} - } - }; -``` - - -### GetQueueProperties - -```yaml -directive: - - from: swagger-document - where: $["x-ms-paths"]["/{queueName}?comp=metadata"].get.responses["200"].headers - transform: > - $["x-ms-meta"]["x-ms-format"] = "caseinsensitivemap"; - $["x-ms-approximate-messages-count"]["x-ms-client-name"] = "ApproximateMessageCount"; - - from: swagger-document - where: $["x-ms-paths"]["/{queueName}?comp=metadata"].get.responses["200"] - transform: > - $.schema = { - "type": "object", - "x-ms-client-name": "QueueProperties", - "x-ms-sealed": false, - "x-namespace": "_detail", - "properties": {"__placeHolder": {"type": "integer"}} - }; -``` - -### GetQueueAccessPolicy - -```yaml -directive: - - from: swagger-document - where: $.definitions - transform: > - delete $.SignedIdentifier.properties["AccessPolicy"]; - $.SignedIdentifier.properties = {...$.SignedIdentifier.properties, ...$.AccessPolicy.properties}; - $.SignedIdentifier.properties["Start"]["x-ms-client-name"] = "StartsOn"; - $.SignedIdentifier.properties["Start"]["x-ms-xml"] = {"name": "AccessPolicy/Start"}; - $.SignedIdentifier.properties["Expiry"]["x-ms-client-name"] = "ExpiresOn"; - $.SignedIdentifier.properties["Expiry"]["x-ms-xml"] = {"name": "AccessPolicy/Expiry"}; - $.SignedIdentifier.properties["Permission"]["x-ms-client-name"] = "Permissions"; - $.SignedIdentifier.properties["Permission"]["x-ms-xml"] = {"name": "AccessPolicy/Permission"}; - $.SignedIdentifier.required = ["Id", "Permission"]; - delete $.AccessPolicy; - - from: swagger-document - where: $["x-ms-paths"]["/{queueName}?comp=acl"].get.responses["200"] - transform: > - $.schema = { - "type": "object", - "x-ms-client-name": "QueueAccessPolicy", - "xml": {"name": "."}, - "x-ms-sealed": false, - "properties": { - "SignedIdentifiers": {"$ref": "#/definitions/SignedIdentifiers"} - } - } -``` - -### ReceiveMessages - -```yaml -directive: - - from: swagger-document - where: $.definitions - transform: > - $.DequeuedMessageItem["x-ms-client-name"] = "QueueMessage"; - $.DequeuedMessageItem.properties["InsertionTime"]["x-ms-client-name"] = "InsertedOn"; - $.DequeuedMessageItem.properties["ExpirationTime"]["x-ms-client-name"] = "ExpiresOn"; - $.DequeuedMessageItem.properties["TimeNextVisible"]["x-ms-client-name"] = "NextVisibleOn"; - - from: swagger-document - where: $["x-ms-paths"]["/{queueName}/messages"].get.responses["200"] - transform: > - $.schema = { - "type": "object", - "x-ms-client-name": "ReceivedMessages", - "xml": {"name": "."}, - "x-ms-sealed": false, - "properties": { - "Messages": {"$ref": "#/definitions/DequeuedMessagesList", "x-ms-xml": {"name": "QueueMessagesList"}} - } - } -``` - -### UpdateMessage - -```yaml -directive: - - from: swagger-document - where: $.definitions - transform: > - $.QueueMessage["x-ms-client-name"] = "QueueMessageInternal"; - $.QueueMessage.xml = {"name": "QueueMessage"}; - $.QueueMessage["x-namespace"] = "_detail"; -``` - -### EnqueueMessage - -```yaml -directive: - - from: swagger-document - where: $.definitions - transform: > - $.EnqueuedMessage["x-ms-client-name"] = "EnqueueMessageResult"; - $.EnqueuedMessage.properties["InsertionTime"]["x-ms-client-name"] = "InsertedOn"; - $.EnqueuedMessage.properties["ExpirationTime"]["x-ms-client-name"] = "ExpiresOn"; - $.EnqueuedMessage.properties["TimeNextVisible"]["x-ms-client-name"] = "NextVisibleOn"; - $.EnqueuedMessage.xml.name = "QueueMessagesList/QueueMessage"; - - from: swagger-document - where: $["x-ms-paths"]["/{queueName}/messages"].post.responses["201"] - transform: > - $.schema["$ref"] = "#/definitions/EnqueuedMessage"; -``` - -### PeekMessages - -```yaml -directive: - - from: swagger-document - where: $.definitions - transform: > - $.PeekedMessageItem["x-ms-client-name"] = "PeekedQueueMessage"; - $.PeekedMessageItem.properties["InsertionTime"]["x-ms-client-name"] = "InsertedOn"; - $.PeekedMessageItem.properties["ExpirationTime"]["x-ms-client-name"] = "ExpiresOn"; - - from: swagger-document - where: $["x-ms-paths"]["/{queueName}/messages?peekonly=true"].get.responses["200"] - transform: > - $.schema = { - "type": "object", - "x-ms-client-name": "PeekedMessages", - "xml": {"name": "."}, - "x-ms-sealed": false, - "properties": { - "Messages": {"$ref": "#/definitions/PeekedMessagesList", "x-ms-xml": {"name": "QueueMessagesList"}} - } - } -``` - -### UpdateMessage - -```yaml -directive: - - from: swagger-document - where: $["x-ms-paths"]["/{queueName}/messages/{messageid}"].put - transform: > - $.responses["204"].headers["x-ms-time-next-visible"]["x-ms-client-name"] = "NextVisibleOn"; -``` - -### UpdateMessageVisibility - -```yaml -directive: - - from: swagger-document - where: $["x-ms-paths"] - transform: > - $["/{queueName}/messages/{messageid}?updatevisibilityonly=true"] = {}; - $["/{queueName}/messages/{messageid}?updatevisibilityonly=true"].put = JSON.parse(JSON.stringify($["/{queueName}/messages/{messageid}"].put)); - - from: swagger-document - where: $["x-ms-paths"]["/{queueName}/messages/{messageid}?updatevisibilityonly=true"] - transform: > - $.put.operationId = "Queue_UpdateMessageVisibility"; - $.put.parameters.shift(); -``` - -### Description - -```yaml -directive: - - from: swagger-document - where: $.definitions - transform: > - $.ApiVersion.description = "The version used for the operations to Azure storage services."; - $.GeoReplication.description = "Geo-Replication information for the Secondary Storage Service"; - $.Metadata.description = "A set of name-value pairs associated with this queue."; - $.CreateQueueResult.properties["Created"].description = "Indicates if the queue was successfully created by this operation."; - $.UpdateMessageResult.description = "Response type for #Azure::Storage::Queues::QueueClient::UpdateMessage."; - $.SetServicePropertiesResult.description = "Response type for #Azure::Storage::Queues::QueueServiceClient::SetProperties."; - - from: swagger-document - where: $["x-ms-paths"]["/{queueName}"].delete.responses["204"] - transform: > - $.schema.properties["Deleted"].description = "Indicates if the queue was successfully deleted by this operation."; - - from: swagger-document - where: $["x-ms-paths"]["/{queueName}?comp=metadata"].get.responses["200"].headers - transform: > - $["x-ms-meta"]["description"] = "A set of name-value pairs associated with this queue."; -``` \ No newline at end of file diff --git a/sdk/storage/azure-storage-queues/test/ut/CMakeLists.txt b/sdk/storage/azure-storage-queues/test/ut/CMakeLists.txt index f01d02ef51..790cd80d3d 100644 --- a/sdk/storage/azure-storage-queues/test/ut/CMakeLists.txt +++ b/sdk/storage/azure-storage-queues/test/ut/CMakeLists.txt @@ -20,6 +20,7 @@ add_executable ( queue_client_messages_test.cpp queue_client_test.cpp queue_client_test.hpp + queue_models_test.cpp queue_sas_test.cpp queue_service_client_test.cpp queue_service_client_test.hpp diff --git a/sdk/storage/azure-storage-queues/test/ut/queue_models_test.cpp b/sdk/storage/azure-storage-queues/test/ut/queue_models_test.cpp new file mode 100644 index 0000000000..779720df4f --- /dev/null +++ b/sdk/storage/azure-storage-queues/test/ut/queue_models_test.cpp @@ -0,0 +1,135 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include + +#include + +namespace Azure { namespace Storage { namespace Test { + + TEST(QueueModels, Defaults) + { + namespace Models = Queues::Models; + Models::RetentionPolicy retention; + EXPECT_FALSE(retention.IsEnabled); + EXPECT_FALSE(retention.Days.HasValue()); + Models::AnalyticsLogging logging; + EXPECT_TRUE(logging.Version.empty()); + EXPECT_FALSE(logging.Delete); + EXPECT_FALSE(logging.Read); + EXPECT_FALSE(logging.Write); + EXPECT_FALSE(logging.RetentionPolicy.IsEnabled); + Models::Metrics metrics; + EXPECT_TRUE(metrics.Version.empty()); + EXPECT_FALSE(metrics.IsEnabled); + EXPECT_FALSE(metrics.IncludeApis.HasValue()); + EXPECT_FALSE(metrics.RetentionPolicy.IsEnabled); + EXPECT_EQ(Models::CorsRule().MaxAgeInSeconds, 0); + EXPECT_TRUE(Models::QueueServiceProperties().Cors.empty()); + EXPECT_TRUE(Models::GeoReplicationStatus().ToString().empty()); + EXPECT_FALSE(Models::GeoReplication().LastSyncedOn.HasValue()); + EXPECT_FALSE(Models::UserDelegationKey().SignedDelegatedUserTid.HasValue()); + EXPECT_TRUE(Models::QueueItem().Metadata.empty()); + EXPECT_FALSE(Models::CreateQueueResult().Created); + EXPECT_TRUE(Models::DeleteQueueResult().Deleted); + Models::SignedIdentifier identifier; + EXPECT_FALSE(identifier.StartsOn.HasValue()); + EXPECT_FALSE(identifier.ExpiresOn.HasValue()); + EXPECT_TRUE(identifier.Permissions.empty()); + EXPECT_TRUE(Models::QueueAccessPolicy().SignedIdentifiers.empty()); + EXPECT_EQ(Models::QueueMessage().DequeueCount, 0); + EXPECT_TRUE(Models::ReceivedMessages().Messages.empty()); + EXPECT_EQ(Models::PeekedQueueMessage().DequeueCount, 0); + EXPECT_TRUE(Models::PeekedMessages().Messages.empty()); + Models::QueueProperties properties; + EXPECT_TRUE(properties.Metadata.empty()); + EXPECT_EQ(properties.ApproximateMessageCount, 0); + EXPECT_EQ(properties.ApproximateMessageCountLong, 0); + Models::ServiceStatistics statistics; + EXPECT_TRUE(statistics.GeoReplication.Status.ToString().empty()); + EXPECT_FALSE(statistics.GeoReplication.LastSyncedOn.HasValue()); + Queues::ListQueuesOptions list; + EXPECT_FALSE(list.Prefix.HasValue()); + EXPECT_FALSE(list.ContinuationToken.HasValue()); + EXPECT_FALSE(list.PageSizeHint.HasValue()); + EXPECT_EQ(list.Include, Models::ListQueuesIncludeFlags::None); + } + + TEST(QueueModels, ServicePropertiesDefaults) + { + Queues::Models::QueueServiceProperties properties; + EXPECT_TRUE(properties.Cors.empty()); + EXPECT_TRUE(properties.Logging.Version.empty()); + EXPECT_FALSE(properties.Logging.Delete); + EXPECT_FALSE(properties.Logging.Read); + EXPECT_FALSE(properties.Logging.Write); + EXPECT_FALSE(properties.Logging.RetentionPolicy.IsEnabled); + EXPECT_FALSE(properties.Logging.RetentionPolicy.Days.HasValue()); + for (auto const* metrics : {&properties.HourMetrics, &properties.MinuteMetrics}) + { + EXPECT_TRUE(metrics->Version.empty()); + EXPECT_FALSE(metrics->IsEnabled); + EXPECT_FALSE(metrics->IncludeApis.HasValue()); + EXPECT_FALSE(metrics->RetentionPolicy.IsEnabled); + EXPECT_FALSE(metrics->RetentionPolicy.Days.HasValue()); + } + } + + TEST(QueueModels, MetadataIsCaseInsensitive) + { + Queues::Models::QueueItem item; + Queues::Models::QueueProperties properties; + for (auto* metadata : {&item.Metadata, &properties.Metadata}) + { + EXPECT_TRUE(metadata->emplace("MixedCase", "original").second); + auto const found = metadata->find("mixedcase"); + ASSERT_NE(found, metadata->end()); + EXPECT_EQ(found->second, "original"); + EXPECT_FALSE(metadata->emplace("MIXEDCASE", "duplicate").second); + EXPECT_EQ(metadata->size(), 1U); + (*metadata)["mIxEdCaSe"] = "updated"; + EXPECT_EQ(metadata->size(), 1U); + EXPECT_EQ(metadata->at("MIXEDCASE"), "updated"); + EXPECT_EQ(metadata->at("mixedcase"), "updated"); + } + } + + TEST(QueueModels, MessageResults) + { + auto const inserted = DateTime::Parse("2026-10-24T01:02:03Z", DateTime::DateFormat::Rfc3339); + auto const expires = DateTime::Parse("2026-10-25T01:02:03Z", DateTime::DateFormat::Rfc3339); + auto const visible = DateTime::Parse("2026-10-24T01:03:03Z", DateTime::DateFormat::Rfc3339); + Queues::Models::EnqueueMessageResult enqueued{ + "message-id", inserted, expires, "receipt", visible}; + EXPECT_EQ(enqueued.MessageId, "message-id"); + EXPECT_EQ(enqueued.InsertedOn, inserted); + EXPECT_EQ(enqueued.ExpiresOn, expires); + EXPECT_EQ(enqueued.PopReceipt, "receipt"); + EXPECT_EQ(enqueued.NextVisibleOn, visible); + Queues::Models::UpdateMessageResult updated{"updated-receipt", expires}; + EXPECT_EQ(updated.PopReceipt, "updated-receipt"); + EXPECT_EQ(updated.NextVisibleOn, expires); + EXPECT_EQ(enqueued.PopReceipt, "receipt"); + EXPECT_EQ(enqueued.NextVisibleOn, visible); + } + + TEST(QueueModels, Enumerations) + { + using Queues::Models::GeoReplicationStatus; + using Queues::Models::ListQueuesIncludeFlags; + EXPECT_EQ(GeoReplicationStatus::Live, GeoReplicationStatus("live")); + EXPECT_EQ(GeoReplicationStatus::Bootstrap, GeoReplicationStatus("bootstrap")); + EXPECT_EQ(GeoReplicationStatus::Unavailable, GeoReplicationStatus("unavailable")); + EXPECT_EQ(GeoReplicationStatus("custom").ToString(), "custom"); + auto flags = ListQueuesIncludeFlags::None; + EXPECT_EQ(static_cast(flags), 0); + EXPECT_EQ(static_cast(ListQueuesIncludeFlags::Metadata), 1); + flags |= ListQueuesIncludeFlags::Metadata; + EXPECT_EQ(flags, ListQueuesIncludeFlags::Metadata); + EXPECT_EQ(flags & ListQueuesIncludeFlags::Metadata, ListQueuesIncludeFlags::Metadata); + EXPECT_EQ(flags | ListQueuesIncludeFlags::None, ListQueuesIncludeFlags::Metadata); + flags &= ListQueuesIncludeFlags::None; + EXPECT_EQ(flags, ListQueuesIncludeFlags::None); + } + +}}} // namespace Azure::Storage::Test