Storage Queue API review feedback (#2801)

* fix

* sample

* CL

* service version

* fix

* ACL
This commit is contained in:
JinmingHu 2021-08-27 12:46:51 +08:00 committed by GitHub
parent 8cae42999e
commit b8013185d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 328 additions and 109 deletions

View File

@ -14,7 +14,6 @@
- QueueClient::Create
- QueueClient::CreateIfNotExists
- QueueClient::Delete
- QueueClient::DeleteIfExists
- QueueClient::GetProperties
- QueueClient::SetMetadata
- QueueClient::GetAccessPolicy

View File

@ -42,6 +42,7 @@ set(
AZURE_STORAGE_QUEUE_SOURCE
src/private/package_version.hpp
src/queue_client.cpp
src/queue_options.cpp
src/queue_responses.cpp
src/queue_rest_client.cpp
src/queue_sas_builder.cpp
@ -93,6 +94,7 @@ if(BUILD_STORAGE_SAMPLES)
target_sources(
azure-storage-sample
PRIVATE
sample/queue_encode_message.cpp
sample/queue_getting_started.cpp
)

View File

@ -53,6 +53,33 @@ namespace Azure { namespace Storage { namespace Queues {
std::string m_value;
}; // extensible enum GeoReplicationStatus
/**
* @brief A peeked message object stored in the queue.
*/
struct PeekedQueueMessage final
{
/**
* The content of the message.
*/
std::string MessageText;
/**
* A GUID value that identifies the message in the queue.
*/
std::string MessageId;
/**
* The time the message was inserted into the queue.
*/
Azure::DateTime InsertedOn;
/**
* The time that the message will expire and be automatically deleted from the queue.
*/
Azure::DateTime ExpiresOn;
/**
* The number of times the message has been dequeued.
*/
int64_t DequeueCount = 0;
}; // struct PeekedQueueMessage
/**
* @brief A queue item from the result of
* #Azure::Storage::Queues::QueueServiceClient::ListQueues.
@ -77,7 +104,7 @@ namespace Azure { namespace Storage { namespace Queues {
/**
* The content of the message.
*/
std::string Body;
std::string MessageText;
/**
* A GUID value that identifies the message in the queue.
*/
@ -91,13 +118,11 @@ namespace Azure { namespace Storage { namespace Queues {
*/
Azure::DateTime ExpiresOn;
/**
* An opaque string that is required to delete or update a message. Empty if it's a peeked
* message.
* An opaque string that is required to delete or update a message.
*/
std::string PopReceipt;
/**
* The time that the message will again become visible in the queue. Invalid if it's a peeked
* message.
* The time that the message will again become visible in the queue.
*/
Azure::DateTime NextVisibleOn;
/**
@ -134,11 +159,11 @@ namespace Azure { namespace Storage { namespace Queues {
/**
* Date and time since when this policy is active.
*/
Azure::DateTime StartsOn;
Azure::Nullable<Azure::DateTime> StartsOn;
/**
* Date and time the policy expires.
*/
Azure::DateTime ExpiresOn;
Azure::Nullable<Azure::DateTime> ExpiresOn;
/**
* The permissions for this ACL policy.
*/
@ -346,7 +371,7 @@ namespace Azure { namespace Storage { namespace Queues {
/**
* A vector of peeked messages.
*/
std::vector<QueueMessage> Messages;
std::vector<PeekedQueueMessage> Messages;
}; // struct PeekMessagesResult
/**
@ -1740,7 +1765,7 @@ namespace Azure { namespace Storage { namespace Queues {
struct EnqueueMessageOptions final
{
Azure::Nullable<int32_t> Timeout;
std::string Body;
std::string MessageText;
Azure::Nullable<std::chrono::seconds> VisibilityTimeout;
Azure::Nullable<std::chrono::seconds> TimeToLive;
}; // struct EnqueueMessageOptions
@ -1993,7 +2018,7 @@ namespace Azure { namespace Storage { namespace Queues {
struct UpdateMessageOptions final
{
std::string Body;
std::string MessageText;
Azure::Nullable<int32_t> Timeout;
std::string PopReceipt;
std::chrono::seconds VisibilityTimeout;
@ -2199,7 +2224,7 @@ namespace Azure { namespace Storage { namespace Queues {
if (path.size() == 2 && path[0] == XmlTagName::k_QueueMessagesList
&& path[1] == XmlTagName::k_QueueMessage)
{
ret.Messages.emplace_back(QueueMessageFromXml(reader));
ret.Messages.emplace_back(PeekedQueueMessageFromXml(reader));
path.pop_back();
}
}
@ -2322,6 +2347,93 @@ namespace Azure { namespace Storage { namespace Queues {
return ret;
}
static PeekedQueueMessage PeekedQueueMessageFromXml(_internal::XmlReader& reader)
{
PeekedQueueMessage ret;
enum class XmlTagName
{
k_MessageText,
k_MessageId,
k_InsertionTime,
k_ExpirationTime,
k_DequeueCount,
k_Unknown,
};
std::vector<XmlTagName> path;
while (true)
{
auto node = reader.Read();
if (node.Type == _internal::XmlNodeType::End)
{
break;
}
else if (node.Type == _internal::XmlNodeType::EndTag)
{
if (path.size() > 0)
{
path.pop_back();
}
else
{
break;
}
}
else if (node.Type == _internal::XmlNodeType::StartTag)
{
if (node.Name == "MessageText")
{
path.emplace_back(XmlTagName::k_MessageText);
}
else if (node.Name == "MessageId")
{
path.emplace_back(XmlTagName::k_MessageId);
}
else if (node.Name == "InsertionTime")
{
path.emplace_back(XmlTagName::k_InsertionTime);
}
else if (node.Name == "ExpirationTime")
{
path.emplace_back(XmlTagName::k_ExpirationTime);
}
else if (node.Name == "DequeueCount")
{
path.emplace_back(XmlTagName::k_DequeueCount);
}
else
{
path.emplace_back(XmlTagName::k_Unknown);
}
}
else if (node.Type == _internal::XmlNodeType::Text)
{
if (path.size() == 1 && path[0] == XmlTagName::k_MessageText)
{
ret.MessageText = node.Value;
}
else if (path.size() == 1 && path[0] == XmlTagName::k_MessageId)
{
ret.MessageId = node.Value;
}
else if (path.size() == 1 && path[0] == XmlTagName::k_InsertionTime)
{
ret.InsertedOn
= Azure::DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
}
else if (path.size() == 1 && path[0] == XmlTagName::k_ExpirationTime)
{
ret.ExpiresOn
= Azure::DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
}
else if (path.size() == 1 && path[0] == XmlTagName::k_DequeueCount)
{
ret.DequeueCount = std::stoll(node.Value);
}
}
}
return ret;
}
static QueueMessage QueueMessageFromXml(_internal::XmlReader& reader)
{
QueueMessage ret;
@ -2394,7 +2506,7 @@ namespace Azure { namespace Storage { namespace Queues {
{
if (path.size() == 1 && path[0] == XmlTagName::k_MessageText)
{
ret.Body = node.Value;
ret.MessageText = node.Value;
}
else if (path.size() == 1 && path[0] == XmlTagName::k_MessageId)
{
@ -2524,7 +2636,7 @@ namespace Azure { namespace Storage { namespace Queues {
writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "QueueMessage"});
writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "MessageText"});
writer.Write(
_internal::XmlNode{_internal::XmlNodeType::Text, std::string(), options.Body});
_internal::XmlNode{_internal::XmlNodeType::Text, std::string(), options.MessageText});
writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
}
@ -2548,7 +2660,7 @@ namespace Azure { namespace Storage { namespace Queues {
writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "QueueMessage"});
writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "MessageText"});
writer.Write(
_internal::XmlNode{_internal::XmlNodeType::Text, std::string(), options.Body});
_internal::XmlNode{_internal::XmlNodeType::Text, std::string(), options.MessageText});
writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
}
@ -2562,22 +2674,28 @@ namespace Azure { namespace Storage { namespace Queues {
writer.Write(_internal::XmlNode{_internal::XmlNodeType::Text, std::string(), options.Id});
writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "AccessPolicy"});
writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Start"});
writer.Write(_internal::XmlNode{
_internal::XmlNodeType::Text,
std::string(),
options.StartsOn.ToString(
Azure::DateTime::DateFormat::Rfc3339,
Azure::DateTime::TimeFractionFormat::AllDigits)});
writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Expiry"});
writer.Write(_internal::XmlNode{
_internal::XmlNodeType::Text,
std::string(),
options.ExpiresOn.ToString(
Azure::DateTime::DateFormat::Rfc3339,
Azure::DateTime::TimeFractionFormat::AllDigits)});
writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
if (options.StartsOn.HasValue())
{
writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Start"});
writer.Write(_internal::XmlNode{
_internal::XmlNodeType::Text,
std::string(),
options.StartsOn.Value().ToString(
Azure::DateTime::DateFormat::Rfc3339,
Azure::DateTime::TimeFractionFormat::AllDigits)});
writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
}
if (options.ExpiresOn.HasValue())
{
writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Expiry"});
writer.Write(_internal::XmlNode{
_internal::XmlNodeType::Text,
std::string(),
options.ExpiresOn.Value().ToString(
Azure::DateTime::DateFormat::Rfc3339,
Azure::DateTime::TimeFractionFormat::AllDigits)});
writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
}
writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Permission"});
writer.Write(
_internal::XmlNode{_internal::XmlNodeType::Text, std::string(), options.Permissions});

View File

@ -112,25 +112,15 @@ namespace Azure { namespace Storage { namespace Queues {
const CreateQueueOptions& options = CreateQueueOptions(),
const Azure::Core::Context& context = Azure::Core::Context()) const;
/**
* @brief Marks the specified queue for deletion.
*
* @param options Optional parameters to execute this function.
* @param context Context for cancelling long running operations.
* @return A DeleteQueueResult if successful.
*/
Azure::Response<Models::DeleteQueueResult> Delete(
const DeleteQueueOptions& options = DeleteQueueOptions(),
const Azure::Core::Context& context = Azure::Core::Context()) const;
/**
* @brief Marks the specified queue for deletion if it exists.
*
* @param options Optional parameters to execute this function.
* @param context Context for cancelling long running operations.
* @return A DeleteQueueResult if successful.
* @return DeleteQueueResult.Deleted will be true if successful, false if the queue doesn't
* exist.
*/
Azure::Response<Models::DeleteQueueResult> DeleteIfExists(
Azure::Response<Models::DeleteQueueResult> Delete(
const DeleteQueueOptions& options = DeleteQueueOptions(),
const Azure::Core::Context& context = Azure::Core::Context()) const;

View File

@ -17,6 +17,48 @@
namespace Azure { namespace Storage { namespace Queues {
/**
* @brief API version for Storage Queue service.
*/
class ServiceVersion final {
public:
/**
* @brief Construct a new Service Version object
*
* @param version The string version for Storage Queue Service.
*/
explicit ServiceVersion(std::string version) : m_version(std::move(version)) {}
/**
* @brief Enable comparing between two versions.
*
* @param other Another service version to be compared.
*/
bool operator==(const ServiceVersion& other) const { return m_version == other.m_version; }
/**
* @brief Enable comparing between two versions.
*
* @param other Another service version to be compared.
*/
bool operator!=(const ServiceVersion& other) const { return !(*this == other); }
/**
* @brief Returns string representation.
*
*/
std::string const& ToString() const { return m_version; }
/**
* @brief API version 2018-03-28.
*
*/
AZ_STORAGE_QUEUES_DLLEXPORT const static ServiceVersion V2018_03_28;
private:
std::string m_version;
};
struct QueueClientOptions final : Azure::Core::_internal::ClientOptions
{
/**
@ -31,7 +73,7 @@ namespace Azure { namespace Storage { namespace Queues {
/**
* API version used by this client.
*/
std::string ApiVersion = _detail::ApiVersion;
ServiceVersion ApiVersion{_detail::ApiVersion};
};
/**
@ -132,11 +174,6 @@ namespace Azure { namespace Storage { namespace Queues {
{
};
/**
* @brief A TTL value representing the queue message does not expire.
*/
constexpr static std::chrono::seconds MessageNeverExpires{-1};
/**
* Optional parameters for #Azure::Storage::Queues::QueueClient::EnqueueMessages.
*/
@ -152,6 +189,11 @@ namespace Azure { namespace Storage { namespace Queues {
* positive number, as well as MessageNeverExpires indicating that the message does not expire
*/
Azure::Nullable<std::chrono::seconds> TimeToLive;
/**
* @brief A TTL value representing the queue message does not expire.
*/
AZ_STORAGE_QUEUES_DLLEXPORT const static std::chrono::seconds MessageNeverExpires;
};
/**

View File

@ -0,0 +1,35 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
#include <cassert>
#include <iostream>
#include <azure/core/base64.hpp>
#include <azure/storage/queues.hpp>
#include "samples_common.hpp"
SAMPLE(QueuesEncodeMessage, QueuesEncodeMessage)
void QueuesEncodeMessage()
{
using namespace Azure::Storage::Queues;
std::string QueueName = "sample-queue";
auto queueClient = QueueClient::CreateFromConnectionString(GetConnectionString(), QueueName);
queueClient.CreateIfNotExists();
// Binary message cannot be enqueued directly, we encode the message with Base64.
std::vector<uint8_t> binaryMessage{0x00, 0x01, 0x02, 0x03};
std::string encodedMessage = Azure::Core::Convert::Base64Encode(binaryMessage);
queueClient.EnqueueMessage(encodedMessage);
auto receiveMessagesResult = queueClient.ReceiveMessages().Value;
auto& receivedMessage = receiveMessagesResult.Messages[0];
std::cout << receivedMessage.MessageText << std::endl;
// Sometimes messages are Base64 encoded. Some other queue clients automatically encode the
// message even it's in plaintext. We need to decode the message in that case.
auto decodedMessage = Azure::Core::Convert::Base64Decode(receivedMessage.MessageText);
assert(decodedMessage == binaryMessage);
}

View File

@ -20,6 +20,15 @@ void ProducerFunc()
std::string msg = "Message " + std::to_string(i);
queueClient.EnqueueMessage(msg);
}
for (int i = 5; i < 10; ++i)
{
std::string msg = "Message " + std::to_string(i);
EnqueueMessageOptions options;
options.TimeToLive = std::chrono::seconds(60 * 60 * 24);
options.VisibilityTimeout = std::chrono::seconds(1);
queueClient.EnqueueMessage(msg, options);
}
}
void ConsumerFunc()
@ -29,12 +38,12 @@ void ConsumerFunc()
int counter = 0;
while (counter < 5)
{
auto msgResponse = queueClient.ReceiveMessages();
if (!msgResponse.Value.Messages.empty())
auto receiveMessagesResult = queueClient.ReceiveMessages().Value;
if (!receiveMessagesResult.Messages.empty())
{
auto& msg = msgResponse.Value.Messages[0];
auto& msg = receiveMessagesResult.Messages[0];
std::cout << msg.Body << std::endl;
std::cout << msg.MessageText << std::endl;
++counter;
queueClient.DeleteMessage(msg.MessageId, msg.PopReceipt);
@ -52,10 +61,10 @@ void ConsumerFunc2()
{
ReceiveMessagesOptions receiveOptions;
receiveOptions.MaxMessages = 3;
auto msgResponse = queueClient.ReceiveMessages(receiveOptions);
for (auto& msg : msgResponse.Value.Messages)
auto receiveMessagesResult = queueClient.ReceiveMessages(receiveOptions).Value;
for (auto& msg : receiveMessagesResult.Messages)
{
std::cout << msg.Body << std::endl;
std::cout << msg.MessageText << std::endl;
++counter;
auto updateResponse
@ -75,4 +84,5 @@ void QueuesGettingStarted()
ProducerFunc();
ConsumerFunc();
ConsumerFunc2();
}

View File

@ -49,7 +49,7 @@ namespace Azure { namespace Storage { namespace Queues {
m_queueUrl.GetHost(), newOptions.SecondaryHostForRetryReads));
perRetryPolicies.emplace_back(std::make_unique<_internal::StoragePerRetryPolicy>());
perOperationPolicies.emplace_back(
std::make_unique<_internal::StorageServiceVersionPolicy>(newOptions.ApiVersion));
std::make_unique<_internal::StorageServiceVersionPolicy>(newOptions.ApiVersion.ToString()));
m_pipeline = std::make_shared<Azure::Core::Http::_internal::HttpPipeline>(
newOptions,
_internal::QueueServicePackageName,
@ -77,7 +77,7 @@ namespace Azure { namespace Storage { namespace Queues {
credential, tokenContext));
}
perOperationPolicies.emplace_back(
std::make_unique<_internal::StorageServiceVersionPolicy>(options.ApiVersion));
std::make_unique<_internal::StorageServiceVersionPolicy>(options.ApiVersion.ToString()));
m_pipeline = std::make_shared<Azure::Core::Http::_internal::HttpPipeline>(
options,
_internal::QueueServicePackageName,
@ -95,7 +95,7 @@ namespace Azure { namespace Storage { namespace Queues {
m_queueUrl.GetHost(), options.SecondaryHostForRetryReads));
perRetryPolicies.emplace_back(std::make_unique<_internal::StoragePerRetryPolicy>());
perOperationPolicies.emplace_back(
std::make_unique<_internal::StorageServiceVersionPolicy>(options.ApiVersion));
std::make_unique<_internal::StorageServiceVersionPolicy>(options.ApiVersion.ToString()));
m_pipeline = std::make_shared<Azure::Core::Http::_internal::HttpPipeline>(
options,
_internal::QueueServicePackageName,
@ -139,18 +139,11 @@ namespace Azure { namespace Storage { namespace Queues {
const Azure::Core::Context& context) const
{
(void)options;
_detail::QueueRestClient::Queue::DeleteQueueOptions protocolLayerOptions;
return _detail::QueueRestClient::Queue::Delete(
*m_pipeline, m_queueUrl, protocolLayerOptions, context);
}
Azure::Response<Models::DeleteQueueResult> QueueClient::DeleteIfExists(
const DeleteQueueOptions& options,
const Azure::Core::Context& context) const
{
try
{
return Delete(options, context);
_detail::QueueRestClient::Queue::DeleteQueueOptions protocolLayerOptions;
return _detail::QueueRestClient::Queue::Delete(
*m_pipeline, m_queueUrl, protocolLayerOptions, context);
}
catch (StorageException& e)
{
@ -216,7 +209,7 @@ namespace Azure { namespace Storage { namespace Queues {
auto messagesUrl = m_queueUrl;
messagesUrl.AppendPath("messages");
_detail::QueueRestClient::Queue::EnqueueMessageOptions protocolLayerOptions;
protocolLayerOptions.Body = std::move(messageText);
protocolLayerOptions.MessageText = std::move(messageText);
protocolLayerOptions.TimeToLive = options.TimeToLive;
protocolLayerOptions.VisibilityTimeout = options.VisibilityTimeout;
return _detail::QueueRestClient::Queue::EnqueueMessage(
@ -262,7 +255,7 @@ namespace Azure { namespace Storage { namespace Queues {
if (options.MessageText.HasValue())
{
_detail::QueueRestClient::Queue::UpdateMessageOptions protocolLayerOptions;
protocolLayerOptions.Body = options.MessageText.Value();
protocolLayerOptions.MessageText = options.MessageText.Value();
protocolLayerOptions.PopReceipt = popReceipt;
protocolLayerOptions.VisibilityTimeout = visibilityTimeout;
return _detail::QueueRestClient::Queue::UpdateMessage(

View File

@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
#include "azure/storage/queues/queue_options.hpp"
namespace Azure { namespace Storage { namespace Queues {
const ServiceVersion ServiceVersion::V2018_03_28(std::string("2018-03-28"));
const std::chrono::seconds EnqueueMessageOptions::MessageNeverExpires{-1};
}}} // namespace Azure::Storage::Queues

View File

@ -48,7 +48,7 @@ namespace Azure { namespace Storage { namespace Queues {
m_serviceUrl.GetHost(), newOptions.SecondaryHostForRetryReads));
perRetryPolicies.emplace_back(std::make_unique<_internal::StoragePerRetryPolicy>());
perOperationPolicies.emplace_back(
std::make_unique<_internal::StorageServiceVersionPolicy>(newOptions.ApiVersion));
std::make_unique<_internal::StorageServiceVersionPolicy>(newOptions.ApiVersion.ToString()));
m_pipeline = std::make_shared<Azure::Core::Http::_internal::HttpPipeline>(
newOptions,
_internal::QueueServicePackageName,
@ -76,7 +76,7 @@ namespace Azure { namespace Storage { namespace Queues {
credential, tokenContext));
}
perOperationPolicies.emplace_back(
std::make_unique<_internal::StorageServiceVersionPolicy>(options.ApiVersion));
std::make_unique<_internal::StorageServiceVersionPolicy>(options.ApiVersion.ToString()));
m_pipeline = std::make_shared<Azure::Core::Http::_internal::HttpPipeline>(
options,
_internal::QueueServicePackageName,
@ -96,7 +96,7 @@ namespace Azure { namespace Storage { namespace Queues {
m_serviceUrl.GetHost(), options.SecondaryHostForRetryReads));
perRetryPolicies.emplace_back(std::make_unique<_internal::StoragePerRetryPolicy>());
perOperationPolicies.emplace_back(
std::make_unique<_internal::StorageServiceVersionPolicy>(options.ApiVersion));
std::make_unique<_internal::StorageServiceVersionPolicy>(options.ApiVersion.ToString()));
m_pipeline = std::make_shared<Azure::Core::Http::_internal::HttpPipeline>(
options,
_internal::QueueServicePackageName,

View File

@ -24,7 +24,7 @@ namespace Azure { namespace Storage { namespace Test {
auto peekedMessage = queueClient.PeekMessages().Value.Messages[0];
EXPECT_EQ(peekedMessage.Body, message);
EXPECT_EQ(peekedMessage.MessageText, message);
EXPECT_EQ(peekedMessage.MessageId, res.MessageId);
EXPECT_EQ(peekedMessage.InsertedOn, res.InsertedOn);
EXPECT_EQ(peekedMessage.ExpiresOn, res.ExpiresOn);
@ -51,7 +51,7 @@ namespace Azure { namespace Storage { namespace Test {
EXPECT_TRUE(queueClient.PeekMessages().Value.Messages.empty());
enqueueOptions = Queues::EnqueueMessageOptions();
enqueueOptions.TimeToLive = Queues::MessageNeverExpires;
enqueueOptions.TimeToLive = Queues::EnqueueMessageOptions::MessageNeverExpires;
res = queueClient.EnqueueMessage(message, enqueueOptions).Value;
const Azure::DateTime neverExpireDateTime = Azure::DateTime::Parse(
@ -83,7 +83,7 @@ namespace Azure { namespace Storage { namespace Test {
receiveOptions.VisibilityTimeout = std::chrono::seconds(1);
auto receivedMessage = queueClient.ReceiveMessages(receiveOptions).Value.Messages[0];
EXPECT_EQ(receivedMessage.Body, message);
EXPECT_EQ(receivedMessage.MessageText, message);
EXPECT_EQ(receivedMessage.MessageId, res.MessageId);
EXPECT_EQ(receivedMessage.InsertedOn, res.InsertedOn);
EXPECT_EQ(receivedMessage.ExpiresOn, res.ExpiresOn);
@ -124,17 +124,17 @@ namespace Azure { namespace Storage { namespace Test {
receivedMessages = queueClient.ReceiveMessages(receiveOptions).Value.Messages;
EXPECT_EQ(receivedMessages.size(), static_cast<size_t>(receiveOptions.MaxMessages.Value()));
EXPECT_EQ(receivedMessages[0].Body, message1);
EXPECT_EQ(receivedMessages[0].MessageText, message1);
receivedMessages = queueClient.ReceiveMessages().Value.Messages;
EXPECT_EQ(receivedMessages.size(), size_t(1));
EXPECT_EQ(receivedMessages[0].Body, message2);
EXPECT_EQ(receivedMessages[0].MessageText, message2);
receiveOptions.MaxMessages = 10;
receivedMessages = queueClient.ReceiveMessages(receiveOptions).Value.Messages;
EXPECT_EQ(receivedMessages.size(), size_t(2));
EXPECT_EQ(receivedMessages[0].Body, message3);
EXPECT_EQ(receivedMessages[1].Body, message4);
EXPECT_EQ(receivedMessages[0].MessageText, message3);
EXPECT_EQ(receivedMessages[1].MessageText, message4);
queueClient.Delete();
}
@ -152,13 +152,11 @@ namespace Azure { namespace Storage { namespace Test {
auto peekedMessage = queueClient.PeekMessages().Value.Messages[0];
EXPECT_EQ(peekedMessage.Body, message);
EXPECT_EQ(peekedMessage.MessageText, message);
EXPECT_EQ(peekedMessage.MessageId, res.MessageId);
EXPECT_EQ(peekedMessage.InsertedOn, res.InsertedOn);
EXPECT_EQ(peekedMessage.ExpiresOn, res.ExpiresOn);
EXPECT_EQ(peekedMessage.DequeueCount, 0);
EXPECT_TRUE(peekedMessage.PopReceipt.empty());
EXPECT_EQ(peekedMessage.NextVisibleOn, Azure::DateTime());
queueClient.Delete();
}
@ -189,19 +187,19 @@ namespace Azure { namespace Storage { namespace Test {
peekedMessages = queueClient.PeekMessages(peekOptions).Value.Messages;
EXPECT_EQ(peekedMessages.size(), static_cast<size_t>(peekOptions.MaxMessages.Value()));
EXPECT_EQ(peekedMessages[0].Body, message1);
EXPECT_EQ(peekedMessages[0].MessageText, message1);
peekedMessages = queueClient.PeekMessages().Value.Messages;
EXPECT_EQ(peekedMessages.size(), size_t(1));
EXPECT_EQ(peekedMessages[0].Body, message1);
EXPECT_EQ(peekedMessages[0].MessageText, message1);
peekOptions.MaxMessages = 10;
peekedMessages = queueClient.PeekMessages(peekOptions).Value.Messages;
EXPECT_EQ(peekedMessages.size(), size_t(4));
EXPECT_EQ(peekedMessages[0].Body, message1);
EXPECT_EQ(peekedMessages[1].Body, message2);
EXPECT_EQ(peekedMessages[2].Body, message3);
EXPECT_EQ(peekedMessages[3].Body, message4);
EXPECT_EQ(peekedMessages[0].MessageText, message1);
EXPECT_EQ(peekedMessages[1].MessageText, message2);
EXPECT_EQ(peekedMessages[2].MessageText, message3);
EXPECT_EQ(peekedMessages[3].MessageText, message4);
queueClient.Delete();
}
@ -222,7 +220,7 @@ namespace Azure { namespace Storage { namespace Test {
EXPECT_TRUE(IsValidTime(updateRes.NextVisibleOn));
auto peekedMessage = queueClient.PeekMessages().Value.Messages[0];
EXPECT_EQ(peekedMessage.Body, message);
EXPECT_EQ(peekedMessage.MessageText, message);
Queues::UpdateMessageOptions updateOptions;
updateOptions.MessageText = updatedMessage;
@ -232,7 +230,7 @@ namespace Azure { namespace Storage { namespace Test {
std::this_thread::sleep_for(std::chrono::milliseconds(1200));
peekedMessage = queueClient.PeekMessages().Value.Messages[0];
EXPECT_EQ(peekedMessage.Body, updatedMessage);
EXPECT_EQ(peekedMessage.MessageText, updatedMessage);
queueClient.Delete();
}

View File

@ -10,7 +10,10 @@ namespace Azure { namespace Storage { namespace Queues { namespace Models {
bool operator==(const SignedIdentifier& lhs, const SignedIdentifier& rhs)
{
return lhs.Id == rhs.Id && lhs.StartsOn == rhs.StartsOn && lhs.ExpiresOn == rhs.ExpiresOn
return lhs.Id == rhs.Id && lhs.StartsOn.HasValue() == rhs.StartsOn.HasValue()
&& (!lhs.StartsOn.HasValue() || lhs.StartsOn.Value() == rhs.StartsOn.Value())
&& lhs.ExpiresOn.HasValue() == rhs.ExpiresOn.HasValue()
&& (!lhs.ExpiresOn.HasValue() || lhs.ExpiresOn.Value() == rhs.ExpiresOn.Value())
&& lhs.Permissions == rhs.Permissions;
}
@ -64,7 +67,7 @@ namespace Azure { namespace Storage { namespace Test {
queueClient = Azure::Storage::Queues::QueueClient::CreateFromConnectionString(
StandardStorageConnectionString(), LowercaseRandomString());
{
auto response = queueClient.DeleteIfExists();
auto response = queueClient.Delete();
EXPECT_FALSE(response.Value.Deleted);
}
{
@ -80,7 +83,7 @@ namespace Azure { namespace Storage { namespace Test {
EXPECT_FALSE(response.Value.Created);
}
{
auto response = queueClient.DeleteIfExists();
auto response = queueClient.Delete();
EXPECT_TRUE(response.Value.Deleted);
}
}
@ -130,18 +133,36 @@ namespace Azure { namespace Storage { namespace Test {
queueClient.Create();
std::vector<Queues::Models::SignedIdentifier> signedIdentifiers;
Queues::Models::SignedIdentifier identifier;
identifier.Id = RandomString(64);
identifier.StartsOn = std::chrono::system_clock::now() - std::chrono::minutes(1);
identifier.ExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(1);
identifier.Permissions = "r";
signedIdentifiers.emplace_back(identifier);
identifier.Id = RandomString(64);
identifier.StartsOn = std::chrono::system_clock::now() - std::chrono::minutes(2);
identifier.ExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(2);
/* cspell:disable-next-line */
identifier.Permissions = "raup";
signedIdentifiers.emplace_back(identifier);
{
Queues::Models::SignedIdentifier identifier;
identifier.Id = RandomString(64);
identifier.StartsOn = std::chrono::system_clock::now() - std::chrono::minutes(1);
identifier.ExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(1);
identifier.Permissions = "r";
signedIdentifiers.emplace_back(identifier);
}
{
Queues::Models::SignedIdentifier identifier;
identifier.Id = RandomString(64);
identifier.StartsOn = std::chrono::system_clock::now() - std::chrono::minutes(2);
identifier.ExpiresOn.Reset();
/* cspell:disable-next-line */
identifier.Permissions = "raup";
signedIdentifiers.emplace_back(identifier);
}
{
Queues::Models::SignedIdentifier identifier;
identifier.Id = RandomString(64);
identifier.Permissions = "r";
signedIdentifiers.emplace_back(identifier);
}
{
Queues::Models::SignedIdentifier identifier;
identifier.Id = RandomString(64);
identifier.StartsOn = std::chrono::system_clock::now() - std::chrono::minutes(1);
identifier.ExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(1);
signedIdentifiers.emplace_back(identifier);
}
EXPECT_NO_THROW(queueClient.SetAccessPolicy(signedIdentifiers));

View File

@ -84,7 +84,7 @@ namespace Azure { namespace Storage { namespace Test {
auto queueServiceClient = Queues::QueueServiceClient(queueServiceUrl + sas);
const std::string newQueueName = LowercaseRandomString();
EXPECT_NO_THROW(queueServiceClient.CreateQueue(newQueueName));
queueServiceClient0.GetQueueClient(newQueueName).DeleteIfExists();
queueServiceClient0.GetQueueClient(newQueueName).Delete();
};
auto verifyQueueDelete = [&](const std::string& sas) {