From 1d5df378a5a2d9622ef3118a8bbf3aed549ed34e Mon Sep 17 00:00:00 2001 From: Ryan Spletzer Date: Wed, 3 Oct 2018 17:38:27 -0400 Subject: [PATCH 01/10] Changing topicName param to topicPath in CreateRuleAsync, fixing variable typo in CreateRuleAsync (#546) * Changing topicName to topicPath in CreateRuleAsync CreateRuleAsync uses topicName as a parameter whereas the rest of the methods use topicPath. Changing for consistency. * Fixing var typo in CreateRuleAsync * Updating ApiApprovals.ApproveAzureServiceBus.approved.txt * Adding back in trimmed whitespace to approved txt file to resolve unit test issue * Fixed topicPath description in comments --- .../Management/ManagementClient.cs | 10 +++++----- .../ApiApprovals.ApproveAzureServiceBus.approved.txt | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.Azure.ServiceBus/Management/ManagementClient.cs b/src/Microsoft.Azure.ServiceBus/Management/ManagementClient.cs index 7ec885d5..7d2a4fe4 100644 --- a/src/Microsoft.Azure.ServiceBus/Management/ManagementClient.cs +++ b/src/Microsoft.Azure.ServiceBus/Management/ManagementClient.cs @@ -634,7 +634,7 @@ public virtual async Task CreateSubscriptionAsync(Subsc /// /// Adds a new rule to the subscription under given topic. /// - /// The topic name relative to the service namespace base address. + /// The topic path relative to the service namespace base address. /// The name of the subscription. /// A object describing the attributes with which the messages are matched and acted upon. /// @@ -646,16 +646,16 @@ public virtual async Task CreateSubscriptionAsync(Subsc /// The server is busy. You should wait before you retry the operation. /// An internal error or unexpected exception occurs. /// of the recently created rule. - public virtual async Task CreateRuleAsync(string topicName, string subscriptionName, RuleDescription ruleDescription, CancellationToken cancellationToken = default) + public virtual async Task CreateRuleAsync(string topicPath, string subscriptionName, RuleDescription ruleDescription, CancellationToken cancellationToken = default) { - EntityNameHelper.CheckValidTopicName(topicName); - EntityNameHelper.CheckValidSubscriptionName(topicName); + EntityNameHelper.CheckValidTopicName(topicPath); + EntityNameHelper.CheckValidSubscriptionName(subscriptionName); ruleDescription = ruleDescription ?? throw new ArgumentNullException(nameof(ruleDescription)); var atomRequest = ruleDescription.Serialize().ToString(); var content = await PutEntity( - EntityNameHelper.FormatRulePath(topicName, subscriptionName, ruleDescription.Name), + EntityNameHelper.FormatRulePath(topicPath, subscriptionName, ruleDescription.Name), atomRequest, false, null, diff --git a/test/Microsoft.Azure.ServiceBus.UnitTests/API/ApiApprovals.ApproveAzureServiceBus.approved.txt b/test/Microsoft.Azure.ServiceBus.UnitTests/API/ApiApprovals.ApproveAzureServiceBus.approved.txt index 58825105..49a7aa03 100644 --- a/test/Microsoft.Azure.ServiceBus.UnitTests/API/ApiApprovals.ApproveAzureServiceBus.approved.txt +++ b/test/Microsoft.Azure.ServiceBus.UnitTests/API/ApiApprovals.ApproveAzureServiceBus.approved.txt @@ -657,7 +657,7 @@ namespace Microsoft.Azure.ServiceBus.Management public System.Threading.Tasks.Task CloseAsync() { } public virtual System.Threading.Tasks.Task CreateQueueAsync(string queuePath, System.Threading.CancellationToken cancellationToken = null) { } public virtual System.Threading.Tasks.Task CreateQueueAsync(Microsoft.Azure.ServiceBus.Management.QueueDescription queueDescription, System.Threading.CancellationToken cancellationToken = null) { } - public virtual System.Threading.Tasks.Task CreateRuleAsync(string topicName, string subscriptionName, Microsoft.Azure.ServiceBus.RuleDescription ruleDescription, System.Threading.CancellationToken cancellationToken = null) { } + public virtual System.Threading.Tasks.Task CreateRuleAsync(string topicPath, string subscriptionName, Microsoft.Azure.ServiceBus.RuleDescription ruleDescription, System.Threading.CancellationToken cancellationToken = null) { } public virtual System.Threading.Tasks.Task CreateSubscriptionAsync(string topicPath, string subscriptionName, System.Threading.CancellationToken cancellationToken = null) { } public virtual System.Threading.Tasks.Task CreateSubscriptionAsync(Microsoft.Azure.ServiceBus.Management.SubscriptionDescription subscriptionDescription, System.Threading.CancellationToken cancellationToken = null) { } public virtual System.Threading.Tasks.Task CreateSubscriptionAsync(Microsoft.Azure.ServiceBus.Management.SubscriptionDescription subscriptionDescription, Microsoft.Azure.ServiceBus.RuleDescription defaultRule, System.Threading.CancellationToken cancellationToken = null) { } From 93ab7b0bafdc5379f29bfb3df8ef0ecbf426fff6 Mon Sep 17 00:00:00 2001 From: Sean Feldman Date: Thu, 4 Oct 2018 03:40:26 +0200 Subject: [PATCH 02/10] Fix #579 - correct error message (#580) Fixes #579 For an empty list do not throw argument null exception --- .../Core/MessageReceiver.cs | 30 +++++++++---------- .../Resources.Designer.cs | 9 ++++++ src/Microsoft.Azure.ServiceBus/Resources.resx | 3 ++ 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/Microsoft.Azure.ServiceBus/Core/MessageReceiver.cs b/src/Microsoft.Azure.ServiceBus/Core/MessageReceiver.cs index 79fe5643..4356235d 100644 --- a/src/Microsoft.Azure.ServiceBus/Core/MessageReceiver.cs +++ b/src/Microsoft.Azure.ServiceBus/Core/MessageReceiver.cs @@ -97,7 +97,7 @@ public MessageReceiver( { throw Fx.Exception.ArgumentNullOrWhiteSpace(connectionString); } - + this.OwnsConnection = true; } @@ -158,7 +158,7 @@ internal MessageReceiver( string sessionId = null, bool isSessionReceiver = false) : base(nameof(MessageReceiver), entityPath, retryPolicy ?? RetryPolicy.Default) - { + { MessagingEventSource.Log.MessageReceiverCreateStart(serviceBusConnection?.Endpoint.Authority, entityPath, receiveMode.ToString()); if (string.IsNullOrWhiteSpace(entityPath)) @@ -512,7 +512,7 @@ public async Task CompleteAsync(IEnumerable lockTokens) var lockTokenList = lockTokens.ToList(); if (lockTokenList.Count == 0) { - throw Fx.Exception.ArgumentNull(nameof(lockTokens)); + throw Fx.Exception.Argument(nameof(lockTokens), Resources.ListOfLockTokensCannotBeEmty); } MessagingEventSource.Log.MessageCompleteStart(this.ClientId, lockTokenList.Count, lockTokenList); @@ -1523,13 +1523,13 @@ async Task CreateLinkAsync(TimeSpan timeout) var endpointUri = new Uri(this.ServiceBusConnection.Endpoint, this.Path); var claims = new[] { ClaimConstants.Listen }; var amqpSendReceiveLinkCreator = new AmqpSendReceiveLinkCreator( - this.Path, - this.ServiceBusConnection, - endpointUri, - new string[] { endpointUri.AbsoluteUri }, - claims, - this.CbsTokenProvider, - amqpLinkSettings, + this.Path, + this.ServiceBusConnection, + endpointUri, + new string[] { endpointUri.AbsoluteUri }, + claims, + this.CbsTokenProvider, + amqpLinkSettings, this.ClientId); Tuple linkDetails = await amqpSendReceiveLinkCreator.CreateAndOpenAmqpLinkAsync().ConfigureAwait(false); @@ -1561,13 +1561,13 @@ async Task CreateRequestResponseLinkAsync(TimeSpan time var endpointUri = new Uri(this.ServiceBusConnection.Endpoint, entityPath); string[] claims = { ClaimConstants.Manage, ClaimConstants.Listen }; var amqpRequestResponseLinkCreator = new AmqpRequestResponseLinkCreator( - entityPath, - this.ServiceBusConnection, + entityPath, + this.ServiceBusConnection, endpointUri, new string[] { endpointUri.AbsoluteUri }, - claims, - this.CbsTokenProvider, - amqpLinkSettings, + claims, + this.CbsTokenProvider, + amqpLinkSettings, this.ClientId); var linkDetails = await amqpRequestResponseLinkCreator.CreateAndOpenAmqpLinkAsync().ConfigureAwait(false); diff --git a/src/Microsoft.Azure.ServiceBus/Resources.Designer.cs b/src/Microsoft.Azure.ServiceBus/Resources.Designer.cs index f7201c8b..0c5c460d 100644 --- a/src/Microsoft.Azure.ServiceBus/Resources.Designer.cs +++ b/src/Microsoft.Azure.ServiceBus/Resources.Designer.cs @@ -195,6 +195,15 @@ internal static string InvalidEncoding { } } + /// + /// Looks up a localized string similar to List of lock tokens cannot be empty. + /// + internal static string ListOfLockTokensCannotBeEmty { + get { + return ResourceManager.GetString("ListOfLockTokensCannotBeEmty", resourceCulture); + } + } + /// /// Looks up a localized string similar to The specified value '{0}' is invalid. "maxConcurrentCalls" must be greater than zero.. /// diff --git a/src/Microsoft.Azure.ServiceBus/Resources.resx b/src/Microsoft.Azure.ServiceBus/Resources.resx index fc6ab148..f121157b 100644 --- a/src/Microsoft.Azure.ServiceBus/Resources.resx +++ b/src/Microsoft.Azure.ServiceBus/Resources.resx @@ -159,6 +159,9 @@ The provided token does not specify the 'ExpiresOn' value. + + List of lock tokens cannot be empty + '{0}' is not a supported type. From 1b5602331d93cfea6b43f90221eb90296e0ca7e6 Mon Sep 17 00:00:00 2001 From: Neeraj Makam Date: Wed, 3 Oct 2018 19:39:15 -0700 Subject: [PATCH 03/10] Updating Readme for Management operations ManagementClient has been released and we no longer need to redirect to the separate management library. --- README.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/README.md b/README.md index 95565476..b2a13982 100644 --- a/README.md +++ b/README.md @@ -50,11 +50,3 @@ In order to run the unit tests, you will need to do the following: 1. Add an Environment Variable named `azure-service-bus-dotnet/connectionstring` and set the value as the connection string of the newly created namespace. **Please note that if you are using Visual Studio, you must restart Visual Studio in order to use new Environment Variables.** Once you have completed the above, you can run `dotnet test` from the `/test/Microsoft.Azure.ServiceBus.UnitTests` directory. - -### Can I manage Service Bus entities with this library? - -The standard way to manage Azure resources is by using [Azure Resource Manager](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-overview). In order to use functionality that previously existed in the .NET Framework Service Bus client library, you will need to use the `Microsoft.Azure.Management.ServiceBus` library. This will enable use cases that dynamically create/read/update/delete resources. The following links will provide more information on the new library and how to use it. - -* GitHub repo - [https://github.com/Azure/azure-sdk-for-net/tree/AutoRest/src/ResourceManagement/ServiceBus](https://github.com/Azure/azure-sdk-for-net/tree/AutoRest/src/ResourceManagement/ServiceBus) -* NuGet package - [https://www.nuget.org/packages/Microsoft.Azure.Management.ServiceBus/](https://www.nuget.org/packages/Microsoft.Azure.Management.ServiceBus/) -* Sample - [https://github.com/Azure-Samples/service-bus-dotnet-management](https://github.com/Azure-Samples/service-bus-dotnet-management) From dd9d607574d75bd611123d5e290585ddad95c50d Mon Sep 17 00:00:00 2001 From: Sean Feldman Date: Fri, 5 Oct 2018 03:57:00 +0200 Subject: [PATCH 04/10] Swithch to Microsoft SourceLink (#561) * Use Microsoft Source link * Package PDB file for sourcelink to work * Embed untracked sources in the package for sourcelink to work for sources that are not committed * Add repo URL / type / commit hash to the generated nuget package * SourceLink package should be set with PrivateAssets="All" --- .../Microsoft.Azure.ServiceBus.csproj | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj b/src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj index d1b2e44a..2cb47fef 100644 --- a/src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj +++ b/src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj @@ -15,6 +15,9 @@ https://github.com/Azure/azure-service-bus-dotnet https://raw.githubusercontent.com/Azure/azure-service-bus-dotnet/master/LICENSE true + true + true + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb True false false @@ -29,12 +32,7 @@ - - - - - - + From 435c25957c131c32d68b4966a1d4e83acaf01a0b Mon Sep 17 00:00:00 2001 From: Sean Feldman Date: Fri, 5 Oct 2018 04:30:37 +0200 Subject: [PATCH 05/10] Fix typo (#583) --- src/Microsoft.Azure.ServiceBus/Core/MessageReceiver.cs | 2 +- src/Microsoft.Azure.ServiceBus/Resources.Designer.cs | 4 ++-- src/Microsoft.Azure.ServiceBus/Resources.resx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.Azure.ServiceBus/Core/MessageReceiver.cs b/src/Microsoft.Azure.ServiceBus/Core/MessageReceiver.cs index 4356235d..0cce2be2 100644 --- a/src/Microsoft.Azure.ServiceBus/Core/MessageReceiver.cs +++ b/src/Microsoft.Azure.ServiceBus/Core/MessageReceiver.cs @@ -512,7 +512,7 @@ public async Task CompleteAsync(IEnumerable lockTokens) var lockTokenList = lockTokens.ToList(); if (lockTokenList.Count == 0) { - throw Fx.Exception.Argument(nameof(lockTokens), Resources.ListOfLockTokensCannotBeEmty); + throw Fx.Exception.Argument(nameof(lockTokens), Resources.ListOfLockTokensCannotBeEmpty); } MessagingEventSource.Log.MessageCompleteStart(this.ClientId, lockTokenList.Count, lockTokenList); diff --git a/src/Microsoft.Azure.ServiceBus/Resources.Designer.cs b/src/Microsoft.Azure.ServiceBus/Resources.Designer.cs index 0c5c460d..1c86b196 100644 --- a/src/Microsoft.Azure.ServiceBus/Resources.Designer.cs +++ b/src/Microsoft.Azure.ServiceBus/Resources.Designer.cs @@ -198,9 +198,9 @@ internal static string InvalidEncoding { /// /// Looks up a localized string similar to List of lock tokens cannot be empty. /// - internal static string ListOfLockTokensCannotBeEmty { + internal static string ListOfLockTokensCannotBeEmpty { get { - return ResourceManager.GetString("ListOfLockTokensCannotBeEmty", resourceCulture); + return ResourceManager.GetString("ListOfLockTokensCannotBeEmpty", resourceCulture); } } diff --git a/src/Microsoft.Azure.ServiceBus/Resources.resx b/src/Microsoft.Azure.ServiceBus/Resources.resx index f121157b..b47ded16 100644 --- a/src/Microsoft.Azure.ServiceBus/Resources.resx +++ b/src/Microsoft.Azure.ServiceBus/Resources.resx @@ -159,7 +159,7 @@ The provided token does not specify the 'ExpiresOn' value. - + List of lock tokens cannot be empty From e5552e8cd2cb3072808ab306de164462bfd6c553 Mon Sep 17 00:00:00 2001 From: Neeraj Makam Date: Fri, 12 Oct 2018 12:14:45 -0700 Subject: [PATCH 06/10] Removed Timer object from RetryPolicy which was getting leaked. Instead using Task.Delay (#587) This timer object was never being disposed and was getting leaked. Instead using Task.Delay to achieve the same. Fix for #535 --- src/Microsoft.Azure.ServiceBus/RetryPolicy.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.Azure.ServiceBus/RetryPolicy.cs b/src/Microsoft.Azure.ServiceBus/RetryPolicy.cs index 9172a192..f5acd3c9 100644 --- a/src/Microsoft.Azure.ServiceBus/RetryPolicy.cs +++ b/src/Microsoft.Azure.ServiceBus/RetryPolicy.cs @@ -5,7 +5,6 @@ namespace Microsoft.Azure.ServiceBus { using System; using System.Collections.Generic; - using System.Threading; using System.Threading.Tasks; using Primitives; @@ -22,14 +21,12 @@ public abstract class RetryPolicy static readonly TimeSpan DefaultRetryMaxBackoff = TimeSpan.FromSeconds(30); readonly object serverBusyLock = new object(); - Timer serverBusyResetTimer; // This is a volatile copy of IsServerBusy. IsServerBusy is synchronized with a lock, whereas encounteredServerBusy is kept volatile for performance reasons. volatile bool encounteredServerBusy; protected RetryPolicy() { - this.serverBusyResetTimer = new Timer(OnTimerCallback, this, TimeSpan.FromMilliseconds(-1), TimeSpan.FromMilliseconds(-1)); } /// @@ -164,7 +161,7 @@ internal void SetServerBusy(string exceptionMessage) this.ServerBusyExceptionMessage = string.IsNullOrWhiteSpace(exceptionMessage) ? Resources.DefaultServerBusyException : exceptionMessage; this.IsServerBusy = true; - this.serverBusyResetTimer.Change(RetryPolicy.ServerBusyBaseSleepTime, TimeSpan.FromMilliseconds(-1)); + TaskExtensionHelper.Schedule(ScheduleResetServerBusy); } } } @@ -183,17 +180,16 @@ internal void ResetServerBusy() this.encounteredServerBusy = false; this.ServerBusyExceptionMessage = Resources.DefaultServerBusyException; this.IsServerBusy = false; - this.serverBusyResetTimer.Change(TimeSpan.FromMilliseconds(-1), TimeSpan.FromMilliseconds(-1)); } } } protected abstract bool OnShouldRetry(TimeSpan remainingTime, int currentRetryCount, out TimeSpan retryInterval); - static void OnTimerCallback(object state) + private async Task ScheduleResetServerBusy() { - var thisPtr = (RetryPolicy)state; - thisPtr.ResetServerBusy(); + await Task.Delay(RetryPolicy.ServerBusyBaseSleepTime).ConfigureAwait(false); + ResetServerBusy(); } } } \ No newline at end of file From bf6acc9f25d69aadc9b5c328a0331329cd3bca6b Mon Sep 17 00:00:00 2001 From: Sean Feldman Date: Mon, 19 Nov 2018 18:28:30 -0700 Subject: [PATCH 07/10] Keep delivery count as-is when peeking a message (#590) Fixes #589 * Verification test * Differentiate between peek and receive operations * Indicate peek operation * Additional test case to verify behavior when message is received * Test delivery count on peek against real queue * Test delivery count on peeklock against real queue --- .../Amqp/AmqpMessageConverter.cs | 4 +- .../Core/MessageReceiver.cs | 2 +- .../AmqpConverterTests.cs | 34 ++++++++++++++ .../QueueClientTests.cs | 47 +++++++++++++++++++ 4 files changed, 84 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.Azure.ServiceBus/Amqp/AmqpMessageConverter.cs b/src/Microsoft.Azure.ServiceBus/Amqp/AmqpMessageConverter.cs index 27e32d6d..5d23960a 100644 --- a/src/Microsoft.Azure.ServiceBus/Amqp/AmqpMessageConverter.cs +++ b/src/Microsoft.Azure.ServiceBus/Amqp/AmqpMessageConverter.cs @@ -164,7 +164,7 @@ public static AmqpMessage SBMessageToAmqpMessage(SBMessage sbMessage) return amqpMessage; } - public static SBMessage AmqpMessageToSBMessage(AmqpMessage amqpMessage) + public static SBMessage AmqpMessageToSBMessage(AmqpMessage amqpMessage, bool isPeeked = false) { if (amqpMessage == null) { @@ -229,7 +229,7 @@ public static SBMessage AmqpMessageToSBMessage(AmqpMessage amqpMessage) if (amqpMessage.Header.DeliveryCount != null) { - sbMessage.SystemProperties.DeliveryCount = (int)(amqpMessage.Header.DeliveryCount.Value + 1); + sbMessage.SystemProperties.DeliveryCount = isPeeked ? (int)(amqpMessage.Header.DeliveryCount.Value) : (int)(amqpMessage.Header.DeliveryCount.Value + 1); } } diff --git a/src/Microsoft.Azure.ServiceBus/Core/MessageReceiver.cs b/src/Microsoft.Azure.ServiceBus/Core/MessageReceiver.cs index 0cce2be2..a50996a2 100644 --- a/src/Microsoft.Azure.ServiceBus/Core/MessageReceiver.cs +++ b/src/Microsoft.Azure.ServiceBus/Core/MessageReceiver.cs @@ -1102,7 +1102,7 @@ protected virtual async Task> OnPeekAsync(long fromSequenceNumber { var payload = (ArraySegment)entry[ManagementConstants.Properties.Message]; var amqpMessage = AmqpMessage.CreateAmqpStreamMessage(new BufferListStream(new[] { payload }), true); - message = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage); + message = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage, true); messages.Add(message); } diff --git a/test/Microsoft.Azure.ServiceBus.UnitTests/AmqpConverterTests.cs b/test/Microsoft.Azure.ServiceBus.UnitTests/AmqpConverterTests.cs index 47af2a8f..4031851b 100644 --- a/test/Microsoft.Azure.ServiceBus.UnitTests/AmqpConverterTests.cs +++ b/test/Microsoft.Azure.ServiceBus.UnitTests/AmqpConverterTests.cs @@ -131,5 +131,39 @@ void SB_message_with_no_TTL_results_in_empty_Ampq_TTL() Assert.Null(amqpMessage.Header.Ttl); } + + [Fact] + [DisplayTestMethodName] + void When_message_is_peeked_should_have_delivery_count_set_to_zero() + { + var messageBody = Encoding.UTF8.GetBytes("message1"); + + var amqpValue = new AmqpValue(); + amqpValue.Value = new ArraySegment(messageBody); + var amqpMessage = AmqpMessage.Create(amqpValue); + amqpMessage.Header.DeliveryCount = 2; + + var sbMessage = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage, isPeeked: true); + sbMessage.SystemProperties.SequenceNumber = 1L; + + Assert.Equal(2, sbMessage.SystemProperties.DeliveryCount); + } + + [Fact] + [DisplayTestMethodName] + void When_message_is_received_should_have_delivery_count_increased() + { + var messageBody = Encoding.UTF8.GetBytes("message1"); + + var amqpValue = new AmqpValue(); + amqpValue.Value = new ArraySegment(messageBody); + var amqpMessage = AmqpMessage.Create(amqpValue); + amqpMessage.Header.DeliveryCount = 2; + + var sbMessage = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage, isPeeked: false); + sbMessage.SystemProperties.SequenceNumber = 1L; + + Assert.Equal(3, sbMessage.SystemProperties.DeliveryCount); + } } } \ No newline at end of file diff --git a/test/Microsoft.Azure.ServiceBus.UnitTests/QueueClientTests.cs b/test/Microsoft.Azure.ServiceBus.UnitTests/QueueClientTests.cs index 5f791c39..b51f7b00 100644 --- a/test/Microsoft.Azure.ServiceBus.UnitTests/QueueClientTests.cs +++ b/test/Microsoft.Azure.ServiceBus.UnitTests/QueueClientTests.cs @@ -4,6 +4,7 @@ namespace Microsoft.Azure.ServiceBus.UnitTests { using System.Collections.Generic; + using System.Linq; using System.Threading.Tasks; using Xunit; @@ -31,6 +32,52 @@ async Task PeekLockTest(string queueName, int messageCount = 10) } } + [Theory] + [MemberData(nameof(TestPermutations))] + [DisplayTestMethodName] + async Task PeekDeliveryCountTest(string queueName) + { + var queueClient = new QueueClient(TestUtility.NamespaceConnectionString, queueName); + try + { + await TestUtility.SendMessagesAsync(queueClient.InnerSender, 1); + + var message = await TestUtility.PeekMessageAsync(queueClient.InnerReceiver); + + Assert.Equal(0, message.SystemProperties.DeliveryCount); + } + finally + { + var messageToDelete = await TestUtility.ReceiveMessagesAsync(queueClient.InnerReceiver, 1); + await TestUtility.CompleteMessagesAsync(queueClient.InnerReceiver, messageToDelete); + + await queueClient.CloseAsync(); + } + } + + [Theory] + [MemberData(nameof(TestPermutations))] + [DisplayTestMethodName] + async Task PeekLockDeliveryCountTest(string queueName) + { + var queueClient = new QueueClient(TestUtility.NamespaceConnectionString, queueName); + try + { + await TestUtility.SendMessagesAsync(queueClient.InnerSender, 1); + + var messages = await TestUtility.ReceiveMessagesAsync(queueClient.InnerReceiver, 1); + + await TestUtility.CompleteMessagesAsync(queueClient.InnerReceiver, messages); + + Assert.Equal(1, messages.First().SystemProperties.DeliveryCount); + } + finally + { + await queueClient.CloseAsync(); + } + } + + [Theory] [MemberData(nameof(TestPermutations))] [DisplayTestMethodName] From c3503864b280f91452066f4c2fdc3ded6fdc9269 Mon Sep 17 00:00:00 2001 From: Sean Feldman Date: Mon, 19 Nov 2018 18:30:59 -0700 Subject: [PATCH 08/10] Re-enable multi-targeting (#605) Fixes #600 * Re-enable multi-targeting * Revert changes made in 555cabf3c690f79540c7cb67bb63847976f9b21b * Fix errors for ManagementClient that was added when only netstandard2.0 was targeted. --- .../Microsoft.Azure.ServiceBus.csproj | 8 +++++++- .../Microsoft.Azure.ServiceBus.UnitTests.csproj | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj b/src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj index 2cb47fef..16a91a1c 100644 --- a/src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj +++ b/src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj @@ -5,7 +5,7 @@ 3.1.1 Microsoft © Microsoft Corporation. All rights reserved. - netstandard2.0 + netstandard2.0;net461 ../../build/keyfile.snk true true @@ -35,6 +35,12 @@ + + + + + + True diff --git a/test/Microsoft.Azure.ServiceBus.UnitTests/Microsoft.Azure.ServiceBus.UnitTests.csproj b/test/Microsoft.Azure.ServiceBus.UnitTests/Microsoft.Azure.ServiceBus.UnitTests.csproj index 74515c63..21380d4a 100644 --- a/test/Microsoft.Azure.ServiceBus.UnitTests/Microsoft.Azure.ServiceBus.UnitTests.csproj +++ b/test/Microsoft.Azure.ServiceBus.UnitTests/Microsoft.Azure.ServiceBus.UnitTests.csproj @@ -21,6 +21,7 @@ + @@ -57,6 +58,6 @@ - + From 129a46949f54f25695c475621f5d5eb6934fb25b Mon Sep 17 00:00:00 2001 From: Sean Feldman Date: Tue, 20 Nov 2018 21:09:22 -0700 Subject: [PATCH 09/10] MaximumDuplicateDetectionHistoryTimeWindow should be 7 days and not 1 (#593) * Fixes #592 - MaximumDuplicateDetectionHistoryTimeWindow should be 7 days and not 1 --- .../Management/ManagementClientConstants.cs | 2 +- .../Management/QueueDescription.cs | 12 ++++++------ .../Management/TopicDescription.cs | 14 +++++++------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Microsoft.Azure.ServiceBus/Management/ManagementClientConstants.cs b/src/Microsoft.Azure.ServiceBus/Management/ManagementClientConstants.cs index 298aa62b..fbfbde8a 100644 --- a/src/Microsoft.Azure.ServiceBus/Management/ManagementClientConstants.cs +++ b/src/Microsoft.Azure.ServiceBus/Management/ManagementClientConstants.cs @@ -33,7 +33,7 @@ internal class ManagementClientConstants public static readonly TimeSpan MinimumLockDuration = TimeSpan.FromSeconds(5); public static readonly TimeSpan MaximumLockDuration = TimeSpan.FromMinutes(5); public static readonly TimeSpan MinimumAllowedAutoDeleteOnIdle = TimeSpan.FromMinutes(5); - public static readonly TimeSpan MaximumDuplicateDetectionHistoryTimeWindow = TimeSpan.FromDays(1); + public static readonly TimeSpan MaximumDuplicateDetectionHistoryTimeWindow = TimeSpan.FromDays(7); public static readonly TimeSpan MinimumDuplicateDetectionHistoryTimeWindow = TimeSpan.FromSeconds(20); public static readonly int MinAllowedMaxDeliveryCount = 1; public static readonly int MaxUserMetadataLength = 1024; diff --git a/src/Microsoft.Azure.ServiceBus/Management/QueueDescription.cs b/src/Microsoft.Azure.ServiceBus/Management/QueueDescription.cs index e8dd924f..ed611529 100644 --- a/src/Microsoft.Azure.ServiceBus/Management/QueueDescription.cs +++ b/src/Microsoft.Azure.ServiceBus/Management/QueueDescription.cs @@ -35,7 +35,7 @@ public QueueDescription(string path) /// /// Path of the queue relative to the namespace base address. /// - /// Max length is 260 chars. Cannot start or end with a slash. + /// Max length is 260 chars. Cannot start or end with a slash. /// Cannot have restricted characters: '@','?','#','*' public string Path { @@ -81,7 +81,7 @@ public TimeSpan LockDuration /// /// /// If true, the receiver can only recieve messages using . - /// Defaults to false. + /// Defaults to false. /// public bool RequiresSession { get; set; } = false; @@ -91,7 +91,7 @@ public TimeSpan LockDuration /// /// This is the default value used when is not set on a /// message itself. Messages older than their TimeToLive value will expire and no longer be retained in the message store. - /// Subscribers will be unable to receive expired messages. + /// Subscribers will be unable to receive expired messages. /// Default value is . /// public TimeSpan DefaultMessageTimeToLive @@ -138,7 +138,7 @@ public TimeSpan AutoDeleteOnIdle /// The duration of duplicate detection history that is maintained by the service. /// /// - /// The default value is 1 minute. Max value is 1 day and minimum is 20 seconds. + /// The default value is 1 minute. Max value is 7 days and minimum is 20 seconds. /// public TimeSpan DuplicateDetectionHistoryTimeWindow { @@ -158,7 +158,7 @@ public TimeSpan DuplicateDetectionHistoryTimeWindow /// /// The maximum delivery count of a message before it is dead-lettered. /// - /// The delivery count is increased when a message is received in mode + /// The delivery count is increased when a message is received in mode /// and didn't complete the message before the message lock expired. /// Default value is 10. Minimum value is 1. public int MaxDeliveryCount @@ -206,7 +206,7 @@ internal set /// /// The path of the recipient entity to which all the messages sent to the queue are forwarded to. /// - /// If set, user cannot manually receive messages from this queue. The destination entity + /// If set, user cannot manually receive messages from this queue. The destination entity /// must be an already existing entity. public string ForwardTo { diff --git a/src/Microsoft.Azure.ServiceBus/Management/TopicDescription.cs b/src/Microsoft.Azure.ServiceBus/Management/TopicDescription.cs index 7f600b63..1265efbe 100644 --- a/src/Microsoft.Azure.ServiceBus/Management/TopicDescription.cs +++ b/src/Microsoft.Azure.ServiceBus/Management/TopicDescription.cs @@ -33,7 +33,7 @@ public TopicDescription(string path) /// /// This is the default value used when is not set on a /// message itself. Messages older than their TimeToLive value will expire and no longer be retained in the message store. - /// Subscribers will be unable to receive expired messages. + /// Subscribers will be unable to receive expired messages. /// Default value is . /// public TimeSpan DefaultMessageTimeToLive @@ -88,7 +88,7 @@ public TimeSpan AutoDeleteOnIdle /// The duration of duplicate detection history that is maintained by the service. /// /// - /// The default value is 1 minute. Max value is 1 day and minimum is 20 seconds. + /// The default value is 1 minute. Max value is 7 days and minimum is 20 seconds. /// public TimeSpan DuplicateDetectionHistoryTimeWindow { @@ -108,7 +108,7 @@ public TimeSpan DuplicateDetectionHistoryTimeWindow /// /// Path of the topic relative to the namespace base address. /// - /// Max length is 260 chars. Cannot start or end with a slash. + /// Max length is 260 chars. Cannot start or end with a slash. /// Cannot have restricted characters: '@','?','#','*' public string Path { @@ -153,8 +153,8 @@ internal set public bool EnablePartitioning { get; set; } = false; /// - /// Defines whether ordering needs to be maintained. If true, messages sent to topic will be - /// forwarded to the subscription in order. + /// Defines whether ordering needs to be maintained. If true, messages sent to topic will be + /// forwarded to the subscription in order. /// /// Defaults to false. public bool SupportOrdering { get; set; } = false; @@ -190,7 +190,7 @@ public string UserMetadata /// /// List of properties that were retrieved using GetTopic but are not understood by this version of client is stored here. - /// The list will be sent back when an already retrieved TopicDescription will be used in UpdateTopic call. + /// The list will be sent back when an already retrieved TopicDescription will be used in UpdateTopic call. /// internal List UnknownProperties { get; set; } @@ -207,7 +207,7 @@ public override bool Equals(object obj) public bool Equals(TopicDescription otherDescription) { - if (otherDescription is TopicDescription other + if (otherDescription is TopicDescription other && this.Path.Equals(other.Path, StringComparison.OrdinalIgnoreCase) && this.AutoDeleteOnIdle.Equals(other.AutoDeleteOnIdle) && this.DefaultMessageTimeToLive.Equals(other.DefaultMessageTimeToLive) From 5c916f59bf97d09931d8da28ca2164f153223fe0 Mon Sep 17 00:00:00 2001 From: Neeraj Makam Date: Wed, 21 Nov 2018 15:43:14 -0800 Subject: [PATCH 10/10] Updating version to 3.2.0 (#607) --- .../Microsoft.Azure.ServiceBus.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj b/src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj index 16a91a1c..64c86926 100644 --- a/src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj +++ b/src/Microsoft.Azure.ServiceBus/Microsoft.Azure.ServiceBus.csproj @@ -2,7 +2,7 @@ This is the next generation Azure Service Bus .NET Standard client library that focuses on queues & topics. For more information about Service Bus, see https://azure.microsoft.com/en-us/services/service-bus/ - 3.1.1 + 3.2.0 Microsoft © Microsoft Corporation. All rights reserved. netstandard2.0;net461 @@ -29,7 +29,7 @@ - +