Skip to content

Commit

Permalink
release-5.0.3 (#544)
Browse files Browse the repository at this point in the history
* Changed icon url in nuget.spec (#520)

Added nuget.spec to the main project

* Changes the main window's text/title to ASB namespace. (#524)

* Changes the main window's text/title to ASB namespace when ASB connection is made.

This brings more visibility when working with mulitple ASB connections at the same time.

* Added SDK information for contributing (#533)

* Purge All Topics / Subscriptions (#531)

* basic implmentation for purge all subscriptions from all topics

* reordered and renamed Purge All context menu items

* purge confirmation prompts

* error handling for subscription purge operations

* changed to official speling for dead-letter

* bulk purge for queues

* moved BulkPurger to ServiceBus library and removed it's internal usage of old SDK

* merged ServiceBusPurger with BulkPurger - wip

* split ServiceBusPurger into entity specific classes

* removed old ServiceBusPurger

* moved concrete classes to own files

* PR feedback

* moved event hanlder arg classes to own files

* added missing ConfigureAwaits

* possible fix for scaling issue

* added Purge All option for individual queues / subscriptions

* added Purge All option for individual queues / subscriptions

* handling for queue / topic folders

* made DeleteForm to be displayed in the center of the parent regardless of the parent's position

Co-authored-by: Razvan Goga <[email protected]>

* fix alt-ctrl-del interpreted as delete (#536)

Co-authored-by: Taruia Matara <[email protected]>

* Bump System.Text.Encodings.Web from 4.6.0 to 4.7.2 in /src/Common (#537)

Bumps [System.Text.Encodings.Web](https://github.com/dotnet/corefx) from 4.6.0 to 4.7.2.
- [Release notes](https://github.com/dotnet/corefx/releases)
- [Commits](https://github.com/dotnet/corefx/commits)

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Change PurgeDeadletterQueueMessagesAsync purge strategy to PurgeStrategies.DeadletteredMessages. (#542)

* Add Async to listing methods

Co-authored-by: Erik Mogensen <[email protected]>
Co-authored-by: groozin <[email protected]>
Co-authored-by: Razvan Goga <[email protected]>
Co-authored-by: Razvan Goga <[email protected]>
Co-authored-by: Adam <[email protected]>
Co-authored-by: Taruia Matara <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: avalanchis <[email protected]>
Co-authored-by: Björn Göransson <[email protected]>
  • Loading branch information
10 people authored May 18, 2021
1 parent 4c17cef commit 8fd1d40
Show file tree
Hide file tree
Showing 27 changed files with 2,253 additions and 1,364 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
# Service Bus Explorer
The Service Bus Explorer allows users to connect to a Service Bus namespace and efficiently administer messaging entities. The tool provides advanced features like import/export functionality or the ability to test topic, queues, subscriptions, relay services, notification hubs and events hubs.

There are no dedicated developers so development is entirely based on voluntary effort.

![Service Bus Explorer](./media/service-bus-explorer.png)

# Installation
Expand All @@ -29,8 +31,8 @@ Here are some guidelines concerning contributions:
- `master` is only for releases
- Every pull request is built by AppVeyor and should preferably be linked to a GitHub issue.
- Write unit tests, if applicable
- We have started to migrate from the old SDK to the latest SDKs for Service Bus, Event Hubs, Relay and Notification Hubs. Therefore, new classes should not depend on the old SDK unless absolutely necessary.

If you just want to help out, feel free to pick one of our issues with the [`help wanted`](https://github.com/paolosalvatori/ServiceBusExplorer/labels/help%20wanted) label.

# Development Environment

Expand Down
56 changes: 39 additions & 17 deletions src/Common/Helpers/ServiceBusHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ public class ServiceBusHelper
private const string MessagePropertyFormat = " - Key=[{0}] Value=[{1}]";
private const string MessageDeferred = " - The message was deferred.";
private const string ReadMessageDeferred = " - Read deferred message.";
private const string MessageMovedToDeadLetterQueue = " - The message was moved to the DeadLetter queue.";
private const string MessageReadFromDeadLetterQueue = " - The message was read from the DeadLetter queue.";
private const string MessageMovedToDeadLetterQueue = " - The message was moved to the Dead-letter queue.";
private const string MessageReadFromDeadLetterQueue = " - The message was read from the Dead-letter queue.";
private const string NoMessageWasReceived = "Receiver[{0}]: no message was received.";
private const string SenderStatisticsHeader = "Sender[{0}]:";
private const string SenderStatisticsLine1 = " - Message Count=[{0}] Messages Sent/Sec=[{1:F1}] Total Elapsed Time (ms)=[{2}]";
Expand Down Expand Up @@ -3009,7 +3009,7 @@ await RetryHelper.RetryActionAsync(async () =>
if (senderThinkTime)
{
WriteToLog(string.Format(SleepingFor, thinkTime));

await Task.Delay(thinkTime);
}
}
Expand Down Expand Up @@ -3077,7 +3077,7 @@ await RetryHelper.RetryActionAsync(async () =>
if (senderThinkTime)
{
WriteToLog(string.Format(SleepingFor, thinkTime));

await Task.Delay(thinkTime);
}
}
Expand Down Expand Up @@ -3995,7 +3995,7 @@ public void SendBatch(MessageSender messageSender,
{
return;
}

for (var i = 0; i < messageList.Count; i++)
{
try
Expand Down Expand Up @@ -4233,7 +4233,7 @@ public bool ReceiveMessages(MessageReceiver messageReceiver,
var stopwatch = Stopwatch.StartNew();
var messageEnumerable = messageReceiver.ReceiveBatch(batchSize, TimeSpan.FromSeconds(timeout));
stopwatch.Stop();

messageList = messageEnumerable as IList<BrokeredMessage> ?? messageEnumerable.ToList();
if (messageInspector != null)
{
Expand All @@ -4251,7 +4251,7 @@ public bool ReceiveMessages(MessageReceiver messageReceiver,
stopwatch = Stopwatch.StartNew();
messageReceiver.CompleteBatch(messageList.Select(b => b.LockToken));
stopwatch.Stop();

if (stopwatch.ElapsedMilliseconds > maximumCompleteTime)
{
maximumCompleteTime = stopwatch.ElapsedMilliseconds;
Expand Down Expand Up @@ -4366,7 +4366,7 @@ public bool ReceiveMessages(MessageReceiver messageReceiver,
var stopwatch = Stopwatch.StartNew();
messageReceiver.CompleteBatch(messageList.Select(b => b.LockToken));
stopwatch.Stop();

if (stopwatch.ElapsedMilliseconds > maximumCompleteTime)
{
maximumCompleteTime = stopwatch.ElapsedMilliseconds;
Expand Down Expand Up @@ -5304,26 +5304,48 @@ public ServiceBusHelper2 GetServiceBusHelper2()
}

public async Task<QueueProperties> GetQueueProperties(QueueDescription oldQueueDescription)
{
return (await this.GetQueueProperties(new List<QueueDescription>() { oldQueueDescription }).ConfigureAwait(false)).FirstOrDefault();
}

public async Task<List<QueueProperties>> GetQueueProperties(List<QueueDescription> oldQueueDescriptions)
{
var administrationClient = new ServiceBusAdministrationClient(connectionString);
var result = new List<QueueProperties>();

return await administrationClient.GetQueueAsync(oldQueueDescription.Path);
foreach(QueueDescription oldQueueDescription in oldQueueDescriptions)
{
result.Add(await administrationClient.GetQueueAsync(oldQueueDescription.Path).ConfigureAwait(false));
}

return result;
}

public async Task<SubscriptionProperties> GetSubscriptionProperties(SubscriptionWrapper oldSubscriptionWrapper)
{
return (await this.GetSubscriptionProperties(new List<SubscriptionWrapper>() { oldSubscriptionWrapper }).ConfigureAwait(false)).FirstOrDefault();
}

public async Task<List<SubscriptionProperties>> GetSubscriptionProperties(List<SubscriptionWrapper> oldSubscriptionWrappers)
{
var managementClient = new ServiceBusAdministrationClient(connectionString);
var result = new List<SubscriptionProperties>();

foreach (SubscriptionWrapper oldSubscriptionWrapper in oldSubscriptionWrappers)
{
var topicResponse = await managementClient.GetTopicAsync(
oldSubscriptionWrapper.TopicDescription.Path)
.ConfigureAwait(false);

var topicResponse = await managementClient.GetTopicAsync(
oldSubscriptionWrapper.TopicDescription.Path)
.ConfigureAwait(false);
var subscriptionResponse = await managementClient.GetSubscriptionAsync(
topicResponse.Value.Name,
oldSubscriptionWrapper.SubscriptionDescription.Name)
.ConfigureAwait(false);

var subscriptionResponse = await managementClient.GetSubscriptionAsync(
topicResponse.Value.Name,
oldSubscriptionWrapper.SubscriptionDescription.Name)
.ConfigureAwait(false);
result.Add(subscriptionResponse.Value);
}

return subscriptionResponse.Value;
return result;
}
#endregion

Expand Down
2 changes: 1 addition & 1 deletion src/Common/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net462" />
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net462" />
<package id="System.Security.Cryptography.X509Certificates" version="4.3.2" targetFramework="net462" />
<package id="System.Text.Encodings.Web" version="4.6.0" targetFramework="net462" />
<package id="System.Text.Encodings.Web" version="4.7.2" targetFramework="net462" />
<package id="System.Text.Json" version="4.6.0" targetFramework="net462" />
<package id="System.Threading.Channels" version="4.6.0" targetFramework="net462" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net462" />
Expand Down
41 changes: 41 additions & 0 deletions src/ServiceBus/Helpers/PurgeOperationCompletedEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#region Copyright
//=======================================================================================
// Microsoft Azure Customer Advisory Team
//
// This sample is supplemental to the technical guidance published on my personal
// blog at http://blogs.msdn.com/b/paolos/.
//
// Author: Paolo Salvatori
//=======================================================================================
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// LICENSED UNDER THE APACHE LICENSE, VERSION 2.0 (THE "LICENSE"); YOU MAY NOT USE THESE
// FILES EXCEPT IN COMPLIANCE WITH THE LICENSE. YOU MAY OBTAIN A COPY OF THE LICENSE AT
// http://www.apache.org/licenses/LICENSE-2.0
// UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE DISTRIBUTED UNDER THE
// LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, EITHER EXPRESS OR IMPLIED. SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING
// PERMISSIONS AND LIMITATIONS UNDER THE LICENSE.
//=======================================================================================
#endregion

using System;

namespace ServiceBusExplorer.ServiceBus.Helpers
{
public class PurgeOperationCompletedEventArgs : EventArgs
{
public bool IsDeadLetterQueue { get; set; }
public string EntityPath { get; set; }
public long ElapsedMilliseconds { get; set; }
public long TotalMessagesPurged { get; set; }

public PurgeOperationCompletedEventArgs(string entityPath, long elapsedMilliseconds, long totalMessagesPurged, bool isDeadLetterQueue)
{
this.EntityPath = entityPath;
this.ElapsedMilliseconds = elapsedMilliseconds;
this.TotalMessagesPurged = totalMessagesPurged;
this.IsDeadLetterQueue = isDeadLetterQueue;
}
}
}
35 changes: 35 additions & 0 deletions src/ServiceBus/Helpers/PurgeOperationFailedEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#region Copyright
//=======================================================================================
// Microsoft Azure Customer Advisory Team
//
// This sample is supplemental to the technical guidance published on my personal
// blog at http://blogs.msdn.com/b/paolos/.
//
// Author: Paolo Salvatori
//=======================================================================================
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// LICENSED UNDER THE APACHE LICENSE, VERSION 2.0 (THE "LICENSE"); YOU MAY NOT USE THESE
// FILES EXCEPT IN COMPLIANCE WITH THE LICENSE. YOU MAY OBTAIN A COPY OF THE LICENSE AT
// http://www.apache.org/licenses/LICENSE-2.0
// UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE DISTRIBUTED UNDER THE
// LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, EITHER EXPRESS OR IMPLIED. SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING
// PERMISSIONS AND LIMITATIONS UNDER THE LICENSE.
//=======================================================================================
#endregion

using System;

namespace ServiceBusExplorer.ServiceBus.Helpers
{
public class PurgeOperationFailedEventArgs : EventArgs
{
public Exception Exception { get; set; }

public PurgeOperationFailedEventArgs(Exception exception)
{
this.Exception = exception;
}
}
}
33 changes: 33 additions & 0 deletions src/ServiceBus/Helpers/PurgeStrategies.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#region Copyright
//=======================================================================================
// Microsoft Azure Customer Advisory Team
//
// This sample is supplemental to the technical guidance published on my personal
// blog at http://blogs.msdn.com/b/paolos/.
//
// Author: Paolo Salvatori
//=======================================================================================
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// LICENSED UNDER THE APACHE LICENSE, VERSION 2.0 (THE "LICENSE"); YOU MAY NOT USE THESE
// FILES EXCEPT IN COMPLIANCE WITH THE LICENSE. YOU MAY OBTAIN A COPY OF THE LICENSE AT
// http://www.apache.org/licenses/LICENSE-2.0
// UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE DISTRIBUTED UNDER THE
// LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, EITHER EXPRESS OR IMPLIED. SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING
// PERMISSIONS AND LIMITATIONS UNDER THE LICENSE.
//=======================================================================================
#endregion

using System;

namespace ServiceBusExplorer.ServiceBus.Helpers
{
[Flags]
public enum PurgeStrategies
{
Messages = 1,
DeadletteredMessages = 2,
All = Messages | DeadletteredMessages
}
}
86 changes: 86 additions & 0 deletions src/ServiceBus/Helpers/QueueServiceBusPurger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#region Copyright
//=======================================================================================
// Microsoft Azure Customer Advisory Team
//
// This sample is supplemental to the technical guidance published on my personal
// blog at http://blogs.msdn.com/b/paolos/.
//
// Author: Paolo Salvatori
//=======================================================================================
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// LICENSED UNDER THE APACHE LICENSE, VERSION 2.0 (THE "LICENSE"); YOU MAY NOT USE THESE
// FILES EXCEPT IN COMPLIANCE WITH THE LICENSE. YOU MAY OBTAIN A COPY OF THE LICENSE AT
// http://www.apache.org/licenses/LICENSE-2.0
// UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE DISTRIBUTED UNDER THE
// LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, EITHER EXPRESS OR IMPLIED. SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING
// PERMISSIONS AND LIMITATIONS UNDER THE LICENSE.
//=======================================================================================
#endregion

using Azure.Messaging.ServiceBus;
using Azure.Messaging.ServiceBus.Administration;
using System.Threading.Tasks;

namespace ServiceBusExplorer.ServiceBus.Helpers
{
public class QueueServiceBusPurger : ServiceBusPurger<QueueProperties>
{
public QueueServiceBusPurger(ServiceBusHelper2 serviceBusHelper) : base(serviceBusHelper) { }

protected override ServiceBusReceiver CreateServiceBusReceiver(QueueProperties entity, ServiceBusClient client, bool purgeDeadLetterQueueInstead)
{
return client.CreateReceiver(
entity.Name,
new ServiceBusReceiverOptions
{
PrefetchCount = 50,
ReceiveMode = ServiceBusReceiveMode.ReceiveAndDelete,
SubQueue = purgeDeadLetterQueueInstead ? SubQueue.DeadLetter : SubQueue.None
});
}

protected async override Task<ServiceBusSessionReceiver> CreateServiceBusSessionReceiver(QueueProperties entity, ServiceBusClient client, bool purgeDeadLetterQueueInstead)
{
return await client.AcceptNextSessionAsync(
entity.Name,
new ServiceBusSessionReceiverOptions
{
PrefetchCount = 10,
ReceiveMode = ServiceBusReceiveMode.ReceiveAndDelete
})
.ConfigureAwait(false);
}

protected override bool EntityRequiresSession(QueueProperties entity)
{
return entity.RequiresSession;
}

protected override string GetEntityPath(QueueProperties entity)
{
return entity.Name;
}

protected async override Task<long> GetMessageCount(QueueProperties entity, bool deadLetterQueueData)
{
var client = new ServiceBusAdministrationClient(serviceBusHelper.ConnectionString);

if (deadLetterQueueData)
{
var runtimeInfoResponse = await client.GetQueueRuntimePropertiesAsync(entity.Name)
.ConfigureAwait(false);

return runtimeInfoResponse.Value.DeadLetterMessageCount;
}
else
{
var runtimeInfo = await client.GetQueueRuntimePropertiesAsync(entity.Name)
.ConfigureAwait(false);

return runtimeInfo.Value.ActiveMessageCount;
}
}
}
}
Loading

0 comments on commit 8fd1d40

Please sign in to comment.