diff --git a/src/Common/Common.csproj b/src/Common/Common.csproj index f7637910..85a496c1 100644 --- a/src/Common/Common.csproj +++ b/src/Common/Common.csproj @@ -16,6 +16,8 @@ + + diff --git a/src/Common/Helpers/AuthorizationRuleWrapper2.cs b/src/Common/Helpers/AuthorizationRuleWrapper2.cs new file mode 100644 index 00000000..dfc4da91 --- /dev/null +++ b/src/Common/Helpers/AuthorizationRuleWrapper2.cs @@ -0,0 +1,210 @@ +#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 + +#region Using Directives + +using System; +using System.Linq; +using Azure.Messaging.ServiceBus.Administration; + +#endregion + + +namespace ServiceBusExplorer.Helpers +{ + public class AuthorizationRuleWrapper2 + { + #region Private Fields + private bool manage; + private bool send; + private bool listen; + private string keyName; + private string primaryKey; + private string secondaryKey; + private string issuerName; + #endregion + + #region Public Constructor + public AuthorizationRuleWrapper2() + { + } + + public AuthorizationRuleWrapper2(AuthorizationRule rule) + { + KeyName = rule.KeyName; + if (rule is SharedAccessAuthorizationRule) + { + var sharedAccessAuthorizationRule = rule as SharedAccessAuthorizationRule; + PrimaryKey = sharedAccessAuthorizationRule.PrimaryKey; + SecondaryKey = sharedAccessAuthorizationRule.SecondaryKey; + } + Manage = rule.Rights.Contains(AccessRights.Manage); + Send = rule.Rights.Contains(AccessRights.Send); + Listen = rule.Rights.Contains(AccessRights.Listen); + IssuerName = rule.KeyName; + CreatedTime = rule.CreatedTime; + ModifiedTime = rule.ModifiedTime; + AuthorizationRule = rule; + } + #endregion + + #region Public Properties + public string KeyName + { + get + { + return keyName; + } + set + { + keyName = value; + if (AuthorizationRule != null) + { + AuthorizationRule.KeyName = value; + } + } + } + + public string PrimaryKey + { + get + { + return primaryKey; + } + set + { + primaryKey = value; + var rule = AuthorizationRule as SharedAccessAuthorizationRule; + if (rule != null) + { + rule.PrimaryKey = value; + } + } + } + + public string SecondaryKey + { + get + { + return secondaryKey; + } + set + { + secondaryKey = value; + var rule = AuthorizationRule as SharedAccessAuthorizationRule; + if (rule != null) + { + rule.SecondaryKey = value; + } + } + } + + public string IssuerName + { + get + { + return issuerName; + } + set + { + issuerName = value; + if (AuthorizationRule != null) + { + AuthorizationRule.KeyName = value; + } + } + } + + public DateTimeOffset CreatedTime { get; private set; } + public DateTimeOffset ModifiedTime { get; private set; } + public AuthorizationRule AuthorizationRule { get; } + + public bool Manage + { + get + { + return manage; + } + set + { + manage = value; + if (!value) + { + return; + } + Send = true; + Listen = true; + if (AuthorizationRule != null && + !AuthorizationRule.Rights.Contains(AccessRights.Manage)) + { + AuthorizationRule.Rights = new[] {AccessRights.Manage, AccessRights.Send, AccessRights.Listen}.ToList(); + } + } + } + + public bool Send + { + get + { + return send; + } + set + { + send = value; + if (!value && manage) + { + Manage = false; + } + if (AuthorizationRule == null || AuthorizationRule.Rights.Contains(AccessRights.Send)) + { + return; + } + var list = AuthorizationRule.Rights.ToList(); + list.Add(AccessRights.Send); + AuthorizationRule.Rights = list; + } + } + + public bool Listen + { + get + { + return listen; + } + set + { + listen = value; + if (!value && manage) + { + Manage = false; + } + if (AuthorizationRule == null || AuthorizationRule.Rights.Contains(AccessRights.Listen)) + { + return; + } + var list = AuthorizationRule.Rights.ToList(); + list.Add(AccessRights.Listen); + AuthorizationRule.Rights = list; + } + } + #endregion + } +} diff --git a/src/Common/Helpers/DeadLetterMessageHandler.cs b/src/Common/Helpers/DeadLetterMessageHandler.cs index a86cfd5e..f22e54b9 100644 --- a/src/Common/Helpers/DeadLetterMessageHandler.cs +++ b/src/Common/Helpers/DeadLetterMessageHandler.cs @@ -33,6 +33,8 @@ namespace ServiceBusExplorer.Helpers { + using Azure.Messaging.ServiceBus.Administration; + public class DeletedDlqMessagesResult { #region Public constructor @@ -52,8 +54,8 @@ public DeletedDlqMessagesResult(bool timedOut, List deletedSequenceNumbers public class DeadLetterMessageHandler { #region Private Fields - // Either queueDescription or subscriptionWrapper is used - but never both. - readonly QueueDescription sourceQueueDescription; + // Either queueProperties or subscriptionWrapper is used - but never both. + readonly QueueProperties sourceQueueProperties; readonly SubscriptionWrapper sourceSubscriptionWrapper; readonly int receiveTimeoutInSeconds; readonly ServiceBusHelper serviceBusHelper; @@ -62,10 +64,10 @@ public class DeadLetterMessageHandler #region Public Constructors public DeadLetterMessageHandler(WriteToLogDelegate writeToLog, ServiceBusHelper serviceBusHelper, - int receiveTimeoutInSeconds, QueueDescription queueDescription) + int receiveTimeoutInSeconds, QueueProperties queueProperties) : this(writeToLog, serviceBusHelper, receiveTimeoutInSeconds) { - sourceQueueDescription = queueDescription; + sourceQueueProperties = queueProperties; } public DeadLetterMessageHandler(WriteToLogDelegate writeToLog, ServiceBusHelper serviceBusHelper, @@ -335,9 +337,9 @@ public string GetFailureExplanation(DeletedDlqMessagesResult result, int targetM #region Private methods private double GetLockDurationInSeconds() { - if (sourceQueueDescription != null) + if (sourceQueueProperties != null) { - return sourceQueueDescription.LockDuration.TotalSeconds; + return sourceQueueProperties.LockDuration.TotalSeconds; } return sourceSubscriptionWrapper.SubscriptionDescription.LockDuration.TotalSeconds; @@ -348,9 +350,9 @@ private int GetMaxOperationTimeInSeconds() // Allocate three seconds for final operations; const int FinalActionsTime = 3; - if (sourceQueueDescription != null) + if (sourceQueueProperties != null) { - return (int)sourceQueueDescription.LockDuration.TotalSeconds - FinalActionsTime; + return (int)sourceQueueProperties.LockDuration.TotalSeconds - FinalActionsTime; } return (int)sourceSubscriptionWrapper.SubscriptionDescription.LockDuration.TotalSeconds @@ -359,9 +361,9 @@ private int GetMaxOperationTimeInSeconds() string GetDlqEntityPath() { - if (sourceQueueDescription != null) + if (sourceQueueProperties != null) { - return QueueClient.FormatDeadLetterPath(sourceQueueDescription.Path); + return QueueClient.FormatDeadLetterPath(sourceQueueProperties.Name); } return SubscriptionClient.FormatDeadLetterPath( diff --git a/src/Common/Helpers/IReceivedMessageInspector.cs b/src/Common/Helpers/IReceivedMessageInspector.cs new file mode 100644 index 00000000..bf60733f --- /dev/null +++ b/src/Common/Helpers/IReceivedMessageInspector.cs @@ -0,0 +1,31 @@ +#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 + +namespace ServiceBusExplorer.Helpers +{ + using Azure.Messaging.ServiceBus; + + public interface IReceivedMessageInspector + { + ServiceBusReceivedMessage BeforeSendMessage(ServiceBusReceivedMessage message); + ServiceBusReceivedMessage AfterReceiveMessage(ServiceBusReceivedMessage message); + } +} diff --git a/src/Common/Helpers/LogReceivedMessageInspector.cs b/src/Common/Helpers/LogReceivedMessageInspector.cs new file mode 100644 index 00000000..179f45b9 --- /dev/null +++ b/src/Common/Helpers/LogReceivedMessageInspector.cs @@ -0,0 +1,218 @@ +#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 + +#region Using Directives + +using System; +using System.Collections.Concurrent; +using System.Globalization; +using System.IO; +using System.Linq; +using System.ServiceModel.Channels; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using Microsoft.ServiceBus.Messaging; + +#endregion + +namespace ServiceBusExplorer.Helpers +{ + using Azure.Messaging.ServiceBus; + using Enums; + + public class LogReceivedMessageInspector : IReceivedMessageInspector, IDisposable + { + #region Private Constants + //*************************** + // Constants + //*************************** + private const string DateFormat = "<{0,2:00}:{1,2:00}:{2,2:00}> {3}"; + private const string MessageSuccessfullySent = "Message Sent. MessageId=[{0}] SessionId=[{1}] Label=[{2}] Size=[{3}]"; + private const string MessageSuccessfullyReceived = "Message Received. MessageId=[{0}] SessionId=[{1}] Label=[{2}] Size=[{3}]"; + private const string UnableToReadMessageBody = "Unable to read the message body."; + private const string NullValue = "NULL"; + private const string MessagePropertiesHeader = "Properties:"; + private const string MessagePayloadHeader = "Payload:"; + private const string MessageTextFormat = "{0}"; + private const string MessagePropertyFormat = " - Key=[{0}] Value=[{1}]"; + private const string LogFileNameFormat = "ReceivedMessage {0}.txt"; + private const int MaxBufferSize = 262144; // 256 KB + #endregion + + #region Private Instance Fields + private readonly Task writeTask = Task.Run( + () => + { + messageCollection = new BlockingCollection>(int.MaxValue); + writer = new StreamWriter(new FileStream(Path.Combine(Environment.CurrentDirectory, + string.Format(LogFileNameFormat, + DateTime.Now.ToString(CultureInfo.InvariantCulture).Replace('/', '-').Replace(':', '-'))), + FileMode.Append, + FileAccess.Write, + FileShare.ReadWrite)); + WriteToLog(); + }); + #endregion + + #region Private Static Fields + private static BlockingCollection> messageCollection; + private static StreamWriter writer; + private static readonly string line = new string('-', 100); + #endregion + + #region IReceivedMessageInspector Methods + public ServiceBusReceivedMessage BeforeSendMessage(ServiceBusReceivedMessage message) + { + return LogMessage(MessageDirection.Send, message); + } + + public ServiceBusReceivedMessage AfterReceiveMessage(ServiceBusReceivedMessage message) + { + return LogMessage(MessageDirection.Receive, message); + } + #endregion + + #region IDisposable Methods + public void Dispose() + { + messageCollection.CompleteAdding(); + writeTask.Wait(); + writer.Dispose(); + } + #endregion + + #region Private Static Methods + private static ServiceBusReceivedMessage LogMessage(MessageDirection direction, ServiceBusReceivedMessage message) + { + try + { + if (message != null) + { + messageCollection.TryAdd(new Tuple(direction, message)); + } + } + // ReSharper disable once EmptyGeneralCatchClause + catch (Exception) + { + } + return message; + } + + /// + /// Reads the content of the ReceivedMessage passed as argument. + /// + /// The ReceivedMessage to read. + /// The content of the ReceivedMessage. + private static string GetMessageText(ServiceBusReceivedMessage messageToRead) + { + string messageText; + + if (messageToRead?.Body == null) + { + return null; + } + + try + { + messageText = messageToRead.Body.ToString(); + } + catch (Exception) + { + messageText = UnableToReadMessageBody; + } + return messageText; + } + + private async static void WriteToLog() + { + try + { + foreach (var tuple in messageCollection.GetConsumingEnumerable()) + { + await Task.Delay(TimeSpan.FromMilliseconds(50)); + if (tuple != null && tuple.Item2 != null) + { + try + { + var direction = tuple.Item1; + var message = tuple.Item2; + var now = DateTime.Now; + var builder = new StringBuilder(); + builder.AppendLine(string.Format(DateFormat, + now.Hour, + now.Minute, + now.Second, + line)); + builder.AppendLine(string.Format(CultureInfo.CurrentCulture, + direction == MessageDirection.Send + ? MessageSuccessfullySent + : MessageSuccessfullyReceived, + string.IsNullOrWhiteSpace(message.MessageId) ? NullValue : message.MessageId, + string.IsNullOrWhiteSpace(message.SessionId) ? NullValue : message.SessionId, + /*string.IsNullOrWhiteSpace(message.Label) ? */NullValue/* : message.Label, + message.Size*/)); + builder.AppendLine(MessagePayloadHeader); + var messageText = GetMessageText(message); + builder.AppendLine(string.Format(MessageTextFormat, + messageText.Contains('\n') + ? messageText + : messageText.Substring(0, Math.Min(messageText.Length, 128)) + + (messageText.Length >= 128 ? "..." : ""))); + if (message.ApplicationProperties.Any()) + { + builder.AppendLine(MessagePropertiesHeader); + foreach (var p in message.ApplicationProperties) + { + builder.AppendLine(string.Format(MessagePropertyFormat, + p.Key, + p.Value)); + } + } + if (writer != null) + { + await writer.WriteAsync(builder.ToString()); + await writer.FlushAsync(); + } + else + { + break; + } + } + // ReSharper disable once EmptyGeneralCatchClause + catch + { + } + } + } + } + // ReSharper disable once EmptyGeneralCatchClause + catch + { + } + finally + { + messageCollection.Dispose(); + } + } + #endregion + } +} diff --git a/src/ServiceBus/Helpers/QueueServiceBusPurger.cs b/src/Common/Helpers/QueueServiceBusPurger.cs similarity index 100% rename from src/ServiceBus/Helpers/QueueServiceBusPurger.cs rename to src/Common/Helpers/QueueServiceBusPurger.cs diff --git a/src/Common/Helpers/ServiceBusHelper.cs b/src/Common/Helpers/ServiceBusHelper.cs index 62a8cee0..c0758809 100644 --- a/src/Common/Helpers/ServiceBusHelper.cs +++ b/src/Common/Helpers/ServiceBusHelper.cs @@ -53,7 +53,6 @@ namespace ServiceBusExplorer // ReSharper restore CheckNamespace { using System.IO.Compression; - using System.Web.UI.WebControls; using Abstractions; using ServiceBusConnectionStringBuilder = Microsoft.ServiceBus.ServiceBusConnectionStringBuilder; @@ -5337,12 +5336,12 @@ public string GetAddressRelativeToNamespace(string address) public ServiceBusHelper2 GetServiceBusHelper2() { - var serviceBusHelper2 = new ServiceBusHelper2(); - serviceBusHelper2.ConnectionString = ConnectionString; - serviceBusHelper2.TransportType = UseAmqpWebSockets + var ServiceBusHelper2 = new ServiceBusHelper2(writeToLog); + ServiceBusHelper2.ConnectionString = ConnectionString; + ServiceBusHelper2.TransportType = UseAmqpWebSockets ? Azure.Messaging.ServiceBus.ServiceBusTransportType.AmqpWebSockets : Azure.Messaging.ServiceBus.ServiceBusTransportType.AmqpTcp; - return serviceBusHelper2; + return ServiceBusHelper2; } public async Task GetQueueProperties(QueueDescription oldQueueDescription) diff --git a/src/Common/Helpers/ServiceBusHelper2.cs b/src/Common/Helpers/ServiceBusHelper2.cs new file mode 100644 index 00000000..85c5a9d7 --- /dev/null +++ b/src/Common/Helpers/ServiceBusHelper2.cs @@ -0,0 +1,1056 @@ +#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 + +#region Using Directives +using System.Threading.Tasks; +using Azure.Messaging.ServiceBus; +using Azure.Messaging.ServiceBus.Administration; + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using Azure.Identity; +using ServiceBusExplorer.Helpers; +#endregion + +// ReSharper disable CheckNamespace +namespace ServiceBusExplorer.ServiceBus.Helpers +// ReSharper restore CheckNamespace +{ + + using Utilities.Helpers; + using System.IO.Compression; + using System.Text; + using Abstractions; + using Enums; + + + public enum BodyType + { + Stream, + String, + Wcf, + ByteArray + } + + public class ServiceBusHelper2 + { + + #region Private Constants + //*************************** + // Constants + //*************************** + private const string DefaultScheme = "sb"; + private const string MessageNumber = "MessageNumber"; + private const string StringType = "String"; + private const string DeadLetterQueue = "$DeadLetterQueue"; + private const string NullValue = "NULL"; + private const string CloudServiceBusPostfix = ".servicebus.windows.net"; + private const string GermanyServiceBusPostfix = ".servicebus.cloudapi.de"; + private const string ChinaServiceBusPostfix = ".servicebus.chinacloudapi.cn"; + private const string TestServiceBusPostFix = ".servicebus.int7.windows-int.net"; + private const int MaxBufferSize = 262144; // 256 KB + + + //*************************** + // Messages + //*************************** + private const string ServiceBusConnectionStringCannotBeNull = "The connection string argument cannot be null."; + private const string ServiceBusUriArgumentCannotBeNull = "The uri argument cannot be null."; + private const string ServiceBusNamespaceArgumentCannotBeNull = "The nameSpace argument cannot be null."; + private const string ServiceBusIssuerNameArgumentCannotBeNull = "The issuerName argument cannot be null."; + private const string ServiceBusIssuerSecretArgumentCannotBeNull = "The issuerSecret argument cannot be null."; + private const string serviceBusAdministrationClientCannotBeNull = "The namespace manager argument cannot be null."; + private const string QueueDescriptionCannotBeNull = "The queue description argument cannot be null."; + private const string TopicDescriptionCannotBeNull = "The topic decsription argument cannot be null."; + private const string SubscriptionDescriptionCannotBeNull = "The subscription description argument cannot be null."; + private const string RuleDescriptionCannotBeNull = "The rule description argument cannot be null."; + private const string EventHubDescriptionCannotBeNull = "The event hub description argument cannot be null."; + private const string ConsumerGroupCannotBeNull = "The consumerGroup argument cannot be null or empty."; + private const string PartitionDescriptionCannotBeNull = "The partition description argument cannot be null."; + private const string ConsumerGroupDescriptionCannotBeNull = "The consumer group description argument cannot be null."; + private const string NotificationHubDescriptionCannotBeNull = "The notification hub description argument cannot be null."; + private const string RuleCannotBeNull = "The rule argument cannot be null."; + private const string PathCannotBeNull = "The path argument cannot be null or empty."; + private const string NewPathCannotBeNull = "The new path argument cannot be null or empty."; + private const string NameCannotBeNull = "The name argument cannot be null or empty."; + private const string DescriptionCannotBeNull = "The description argument cannot be null."; + private const string ServiceBusIsDisconnected = "The application is now disconnected from any service bus namespace."; + private const string ServiceBusIsConnected = "The application is now connected to the {0} service bus namespace."; + private const string QueueCreated = "The queue {0} has been successfully created."; + private const string QueueDeleted = "The queue {0} has been successfully deleted."; + private const string QueueRenamed = "The queue {0} has been successfully renamed to {1}."; + private const string QueueUpdated = "The queue {0} has been successfully updated."; + private const string TopicCreated = "The topic {0} has been successfully created."; + private const string TopicDeleted = "The topic {0} has been successfully deleted."; + private const string TopicRenamed = "The topic {0} has been successfully renamed to {1}."; + private const string TopicUpdated = "The topic {0} has been successfully updated."; + private const string SubscriptionCreated = "The {0} subscription for the {1} topic has been successfully created."; + private const string SubscriptionDeleted = "The {0} subscription for the {1} topic has been successfully deleted."; + private const string SubscriptionUpdated = "The {0} subscription for the {1} topic has been successfully updated."; + private const string RuleCreated = "The {0} rule for the {1} subscription has been successfully created."; + private const string RuleDeleted = "The {0} rule for the {1} subscription has been successfully deleted."; + private const string RelayCreated = "The relay {0} has been successfully created."; + private const string RelayDeleted = "The relay {0} has been successfully deleted."; + private const string RelayUpdated = "The relay {0} has been successfully updated."; + private const string EventHubCreated = "The event hub {0} has been successfully created."; + private const string EventHubDeleted = "The event hub {0} has been successfully deleted."; + private const string EventHubUpdated = "The event hub {0} has been successfully updated."; + private const string ConsumerGroupCreated = "The consumer group {0} has been successfully created."; + private const string ConsumerGroupDeleted = "The consumer group {0} has been successfully deleted."; + private const string ConsumerGroupUpdated = "The consumer group {0} has been successfully updated."; + private const string NotificationHubCreated = "The notification hub {0} has been successfully created."; + private const string NotificationHubDeleted = "The notification hub {0} has been successfully deleted."; + private const string NotificationHubUpdated = "The notification hub {0} has been successfully updated."; + private const string WarningHeader = "The following validations failed:"; + private const string WarningFormat = "\n\r - {0}"; + private const string PropertyConversionError = "{0} property conversion error: {1}"; + private const string PropertyValueCannotBeNull = "The value of the {0} property cannot be null."; + private const string MessageSuccessfullySent = "Sender[{0}]: Message sent. MessageId=[{1}] SessionId=[{2}] Label=[{3}] Size=[{4}]"; + private const string MessageSuccessfullyReceived = "Receiver[{0}]: Message received. MessageId=[{1}] SessionId=[{2}] Label=[{3}] Size=[{4}] DeliveryCount[{5}]"; + private const string MessagePeekedButNotConsumed = "Receiver[{0}]: Message peeked, but not consumed. MessageId=[{1}] SessionId=[{2}] Label=[{3}] Size=[{4}]"; + private const string MessageSuccessfullyReceivedNoTask = "Message {0}: MessageId=[{1}] SessionId=[{2}] Label=[{3}] Size=[{4}] DeliveryCount[{5}]"; + private const string EventDataSuccessfullySent = "Sender[{0}]: EventData sent. MessageNumber=[{1}] PartitionKey=[{2}]"; + private const string ReceiverStatisticsLineNoTask = "Messages {0}: Count=[{1}]"; + private const string SentMessagePropertiesHeader = "Properties:"; + private const string ReceivedMessagePropertiesHeader = "Properties:"; + private const string SentMessagePayloadHeader = "Payload:"; + private const string ReceivedMessagePayloadHeader = "Payload:"; + private const string MessageTextFormat = "{0}"; + 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 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}]"; + private const string SenderStatisticsLine2 = " - Average Send Time (ms)=[{0}] Minimum Send Time (ms)=[{1}] Maximum Send Time (ms)=[{2}] "; + private const string ReceiverStatisticsHeader = "Receiver[{0}]:"; + private const string ReceiverStatisticsLine1 = " - Message Count=[{0}] Messages Read/Sec=[{1:F1}] Total Elapsed Time (ms)=[{2}]"; + private const string ReceiverStatisticsWithCompleteLine1 = " - Message Count=[{0}] Messages Read/Sec=[{1:F1}] Total Receive Elapsed Time (ms)=[{2}] Total Complete Elapsed Time (ms)=[{3}]"; + private const string ReceiverStatisticsLine2 = " - Average Receive Time (ms)=[{0}] Minimum Receive Time (ms)=[{1}] Maximum Receive Time (ms)=[{2}] "; + private const string ReceiverStatisticsLine3 = " - Average Complete Time (ms)=[{0}] Minimum Complete Time (ms)=[{1}] Maximum Complete Time (ms)=[{2}] "; + private const string ExceptionOccurred = " - Exception occurred: {0}"; + private const string UnableToReadMessageBody = "Unable to read the message body."; + private const string EventHubClientCannotBeNull = "The EventHubClient parameter cannot be null."; + private const string EventHubSenderCannotBeNull = "The EventHubSender parameter cannot be null."; + private const string MessageSenderCannotBeNull = "The MessageSender parameter cannot be null."; + private const string MessageReceiverCannotBeNull = "The MessageReceiver parameter cannot be null."; + private const string BrokeredMessageCannotBeNull = "The BrokeredMessage parameter cannot be null."; + private const string EventDataCannotBeNull = "The EventData parameter cannot be null."; + private const string EventDataTemplateEnumerableCannotBeNull = "The eventDataTemplateEnumerable parameter cannot be null."; + private const string CancellationTokenSourceCannotBeNull = "The CancellationTokenSource parameter cannot be null."; + private const string MessageIsNotXmlOrJson = "The message is not in XML or JSON format."; + private const string MessageFactorySuccessfullyCreated = "MessagingFactory successfully created."; + private const string SleepingFor = "Sleeping for [{0}] milliseconds..."; + private const string Read = "read"; + private const string Peeked = "peeked"; + #endregion + + + #region Private Fields + private Type messageDeferProviderType = typeof(InMemoryMessageDeferProvider); + private ServiceBusAdministrationClient serviceBusAdministrationClient; + public ServiceBusClient serviceBusClient; + //private AzureNotificationHubs.serviceBusAdministrationClient notificationHubserviceBusAdministrationClient; + private bool traceEnabled; + private string scheme = DefaultScheme; + //private Microsoft.ServiceBus.TokenProvider tokenProvider; + //private AzureNotificationHubs.TokenProvider notificationHubTokenProvider; + private Uri namespaceUri; + private ServiceBusNamespaceType connectionStringType; + private Uri atomFeedUri; + private string ns; + private string servicePath; + private string connectionString; + //private List brokeredMessageList; + private readonly WriteToLogDelegate writeToLog; + private string currentSharedAccessKeyName; + private string currentSharedAccessKey; + private ServiceBusTransportType currentTransportType; + private ServiceBusNamespace2 serviceBusNamespaceInstance; + #endregion + + #region Private Static Fields + private static Encoding encodingType = Encoding.ASCII; + #endregion + + #region Public Constructors + + /// + /// Initializes a new instance of the ServiceBusHelper class. + /// + /// WriteToLog method. + public ServiceBusHelper2(WriteToLogDelegate writeToLog) + { + this.writeToLog = writeToLog; + traceEnabled = true; + } + + /// + /// Initializes a new instance of the ServiceBusHelper class. + /// + /// WriteToLog method. + /// A boolean value indicating whether tracing is enabled. + public ServiceBusHelper2(WriteToLogDelegate writeToLog, bool traceEnabled) + { + this.writeToLog = writeToLog; + this.traceEnabled = traceEnabled; + } + + /// + /// Initializes a new instance of the ServiceBusHelper class. + /// + /// WriteToLog method. + /// Base ServiceBusHelper. + public ServiceBusHelper2(WriteToLogDelegate writeToLog, ServiceBusHelper2 serviceBusHelper) + { + this.writeToLog = writeToLog; + AtomFeedUri = serviceBusHelper.AtomFeedUri; + MessageDeferProviderType = serviceBusHelper.MessageDeferProviderType; + ConnectionString = serviceBusHelper.ConnectionString; + //namespaceManager = serviceBusHelper.NamespaceManager; + //notificationHubNamespaceManager = serviceBusHelper.NotificationHubNamespaceManager; + //MessagingFactory = serviceBusHelper.MessagingFactory; + Namespace = serviceBusHelper.Namespace; + NamespaceUri = serviceBusHelper.NamespaceUri; + MessageDeferProviderType = serviceBusHelper.MessageDeferProviderType; + Scheme = serviceBusHelper.Scheme; + ServiceBusNamespaces = serviceBusHelper.ServiceBusNamespaces; + ReceivedMessageInspectors = new ReceivedMessageInspector(); + EventDataInspectors = serviceBusHelper.EventDataInspectors; + BrokeredMessageGenerators = serviceBusHelper.BrokeredMessageGenerators; + EventDataGenerators = serviceBusHelper.EventDataGenerators; + ServicePath = serviceBusHelper.ServicePath; + //TokenProvider = serviceBusHelper.TokenProvider; + //notificationHubTokenProvider = serviceBusHelper.notificationHubTokenProvider; + TraceEnabled = serviceBusHelper.TraceEnabled; + SharedAccessKey = serviceBusHelper.SharedAccessKey; + SharedAccessKeyName = serviceBusHelper.SharedAccessKeyName; + TransportType = serviceBusHelper.TransportType; + } + #endregion + + #region Public Instance Properties + + /// + /// Gets a boolean that indicates if the current namespace is a cloud namespace. + /// + public bool IsCloudNamespace + { + get + { + string uri; + return connectionStringType == ServiceBusNamespaceType.Cloud || + (namespaceUri != null && + !string.IsNullOrWhiteSpace(uri = namespaceUri.ToString()) && + (uri.Contains(CloudServiceBusPostfix) || + uri.Contains(TestServiceBusPostFix) || + uri.Contains(GermanyServiceBusPostfix) || + uri.Contains(ChinaServiceBusPostfix))); + } + } + + /// + /// Gets or sets the type of the message defer provider + /// + public Type MessageDeferProviderType + { + get + { + lock (this) + { + return messageDeferProviderType; + } + } + set + { + lock (this) + { + if (value.GetInterfaces().Contains(typeof(IMessageDeferProvider))) + { + messageDeferProviderType = value; + } + } + } + } + + /// + /// Gets or sets a boolean value indicating whether tracing is enabled. + /// + public bool TraceEnabled + { + get + { + lock (this) + { + return traceEnabled; + } + } + set + { + lock (this) + { + traceEnabled = value; + } + } + } + + /// + /// Gets or sets the scheme of the URI. + /// + public string Scheme + { + get + { + lock (this) + { + return scheme; + } + } + set + { + lock (this) + { + scheme = value; + } + } + } + + /// + /// Gets or sets the current namespace. + /// + public string Namespace + { + get + { + lock (this) + { + return ns; + } + } + set + { + lock (this) + { + ns = value; + } + } + } + + /// + /// Gets or sets the current service name. + /// + public string ServicePath + { + get + { + lock (this) + { + return servicePath ?? string.Empty; + } + } + set + { + lock (this) + { + servicePath = value; + if (!string.IsNullOrWhiteSpace(servicePath) && + servicePath[servicePath.Length - 1] != '/') + { + servicePath = servicePath + '/'; + } + } + } + } + + public string ConnectionStringWithoutEntityPath + { + get + { + var builder = ServiceBusConnectionStringProperties .Parse(connectionString); + + // Todo find a way to remove entity path + //builder.EntityPath = string.Empty; + + return builder.ToString(); + } + } + + /// + /// Gets or sets the connection string. + /// + public string ConnectionString + { + get + { + lock (this) + { + return connectionString; + } + } + set + { + lock (this) + { + connectionString = value; + } + } + } + + + /// + /// Gets or sets the shared access key name. + /// + public string SharedAccessKeyName + { + get + { + lock (this) + { + return currentSharedAccessKeyName; + } + } + set + { + lock (this) + { + currentSharedAccessKeyName = value; + } + } + } + + /// + /// Gets or sets the shared access key. + /// + public string SharedAccessKey + { + get + { + lock (this) + { + return currentSharedAccessKey; + } + } + set + { + lock (this) + { + currentSharedAccessKey = value; + } + } + } + + /// + /// Gets or sets the transport type. + /// + public ServiceBusTransportType TransportType + { + get + { + lock (this) + { + return currentTransportType; + } + } + set + { + lock (this) + { + currentTransportType = value; + } + } + } + + /// + /// Gets or sets the URI of the current service bus namespace. + /// + public Uri NamespaceUri + { + get + { + lock (this) + { + return namespaceUri; + } + } + set + { + lock (this) + { + namespaceUri = value; + } + } + } + + /// + /// Gets or sets the URI of the atom feed for the current namespace. + /// + public Uri AtomFeedUri + { + get + { + lock (this) + { + return atomFeedUri; + } + } + set + { + lock (this) + { + atomFeedUri = value; + } + } + } + + /// + /// Gets or sets the dictionary containing serviceBus accounts. + /// + public Dictionary ServiceBusNamespaces { get; set; } + + /// + /// Gets or sets the dictionary containing ReceivedMessage inspectors. + /// + public Dictionary ReceivedMessageInspectors { get; set; } + + /// + /// Gets or sets the dictionary containing EventData inspectors. + /// + public Dictionary EventDataInspectors { get; set; } + + /// + /// Gets or sets the dictionary containing BrokeredMessage generators. + /// + public Dictionary BrokeredMessageGenerators { get; set; } + + /// + /// Gets or sets the dictionary containing EventData generators. + /// + public Dictionary EventDataGenerators { get; set; } + + public bool ConnectionStringContainsEntityPath() + { + var connectionStringProperties = ServiceBusConnectionStringProperties.Parse(ConnectionString); + + if (connectionStringProperties?.EntityPath != null) + { + return true; + } + + return false; + } + + public async Task IsPremiumNamespace() + { + var administrationClient = new ServiceBusAdministrationClient(ConnectionString); + NamespaceProperties namespaceProperties = await administrationClient.GetNamespacePropertiesAsync().ConfigureAwait(false); + + return namespaceProperties.MessagingSku == MessagingSku.Premium; + } + + public async Task IsQueue(string name) + { + var administrationClient = new ServiceBusAdministrationClient(ConnectionString); + return await administrationClient.QueueExistsAsync(name).ConfigureAwait(false); + } + + public async Task IsTopic(string name) + { + var administrationClient = new ServiceBusAdministrationClient(ConnectionString); + return await administrationClient.TopicExistsAsync(name).ConfigureAwait(false); + } + + #endregion + + #region Public Static Properties + + /// + /// Gets or sets the connectivity mode when connecting to namespaces + /// + public static Microsoft.ServiceBus.ConnectivityMode ConnectivityMode + { + get + { + return Microsoft.ServiceBus.ServiceBusEnvironment.SystemConnectivity.Mode; + } + set + { + Microsoft.ServiceBus.ServiceBusEnvironment.SystemConnectivity.Mode = value; + } + } + + public static bool UseAmqpWebSockets { get; set; } + + /// + /// Gets or sets the encodingType of sent messages + /// + public static Encoding EncodingType + { + get + { + return encodingType; + } + set + { + encodingType = value; + } + } + + public ServiceBusClient ServiceBusClient + { + get + { + return serviceBusClient; + } + } + + #endregion + + public delegate void UpdateStatisticsDelegate(long messageNumber, long elapsedMilliseconds, DirectionType direction); + + #region Public Events + public delegate void EventHandler(ServiceBusHelperEventArgs args); +#pragma warning disable CS0067 // Event is never used + public event EventHandler OnDelete; + public event EventHandler OnCreate; +#pragma warning restore CS0067 // Event is never used + #endregion + + + #region Public Methods + + + /// + /// Connects the ServiceBusHelper object to service bus namespace contained in the ServiceBusNamespaces dictionary. + /// + /// The Service Bus namespace. + /// True if the operation succeeds, false otherwise. + public bool Connect(ServiceBusNamespace2 serviceBusNamespace) + { + this.serviceBusNamespaceInstance = serviceBusNamespace; + + if (string.IsNullOrWhiteSpace(serviceBusNamespace?.ConnectionString)) + { + throw new ArgumentException(ServiceBusConnectionStringCannotBeNull); + } + + if (!TestNamespaceHostIsContactable(serviceBusNamespace)) + { + throw new Exception($"Could not contact host in connection string: { serviceBusNamespace.ConnectionString }."); + } + + var func = (() => + { + connectionString = serviceBusNamespace.ConnectionString; + currentSharedAccessKey = serviceBusNamespace.SharedAccessKey; + currentSharedAccessKeyName = serviceBusNamespace.SharedAccessKeyName; + currentTransportType = serviceBusNamespace.TransportType; + + // The serviceBusAdministrationClient class can be used for managing entities, + // such as queues, topics, subscriptions, and rules, in your service namespace. + // You must provide service namespace address and access credentials in order + // to manage your service namespace. + if (!string.IsNullOrEmpty(serviceBusNamespace.SharedAccessKey) && !string.IsNullOrEmpty(serviceBusNamespace.SharedAccessKey)){ + serviceBusAdministrationClient = new ServiceBusAdministrationClient(serviceBusNamespace.ConnectionString); + serviceBusClient = new ServiceBusClient(serviceBusNamespace.ConnectionString); + } else + { + serviceBusAdministrationClient = new ServiceBusAdministrationClient(serviceBusNamespace.Namespace + "servicebus.windows.net", new DefaultAzureCredential()); + serviceBusClient = new ServiceBusClient(serviceBusNamespace.Namespace + "servicebus.windows.net", new DefaultAzureCredential()); + } + + //todo moet retry policy geset worden? + + + try + { + // todo notificationhub nodig hier? + } + catch (Exception) + { + // ignored + } + WriteToLogIf(traceEnabled, string.Format(CultureInfo.CurrentCulture, ServiceBusIsConnected, connectionString)); + //var namespaceProperties = serviceBusAdministrationClient.GetNamespacePropertiesAsync().Result; + //namespaceUri = new Uri(namespaceProperties.Value.Name); + connectionStringType = serviceBusNamespace.ConnectionStringType; + //ns = IsCloudNamespace ? namespaceUri.Host.Split('.')[0] : namespaceUri.Segments[namespaceUri.Segments.Length - 1]; + //atomFeedUri = new Uri($"{Uri.UriSchemeHttp}://{namespaceUri.Host}"); + + return true; + }); + return RetryHelper.RetryFunc(func, writeToLog); + } + + + // TODO rest van public methods + + #region queuecontrol + + public async Task GetQueueProperties(QueueProperties oldQueueDescription) + { + return (await this.GetQueueProperties(new List() { oldQueueDescription }).ConfigureAwait(false)).FirstOrDefault(); + } + + public async Task> GetQueueProperties(List oldQueueDescriptions) + { + var administrationClient = new ServiceBusAdministrationClient(connectionString); + var result = new List(); + + foreach(QueueProperties oldQueueDescription in oldQueueDescriptions) + { + result.Add(await administrationClient.GetQueueAsync(oldQueueDescription.Name).ConfigureAwait(false)); + } + + return result; + } + + /// + /// Retrieves an enumerable collection of all queues in the service bus namespace. + /// + /// OData filter. + /// + /// Returns an IEnumerable collection of all queues in the service namespace. + /// Returns an empty collection if no queue exists in this service namespace. + public async Task> GetQueuesAsync(string filter, int timeoutInSeconds) + { + if (serviceBusAdministrationClient != null) + { + if (string.IsNullOrEmpty(serviceBusNamespaceInstance.EntityPath)) + { + /* + var taskList = new List(); + */ + //Documentation states AND is the only logical clause allowed in the filter (And FYI a maximum of only 3 filter expressions allowed) + //https://docs.microsoft.com/en-us/dotnet/api/microsoft.servicebus.namespacemanager.getqueuesasync?view=azure-dotnet#Microsoft_ServiceBus_NamespaceManager_GetQueuesAsync_System_String_ + //Split on ' OR ' and combine queues returned + + var queuesListingResult = /*string.IsNullOrWhiteSpace(filter) ?*/ serviceBusAdministrationClient.GetQueuesRuntimePropertiesAsync() /*: serviceBusAdministrationClient.GetQueuesAsync(/*splitFilter#1#)*/; + + + // Todo client side filtering + IList queues = new List(); + + await foreach (var item in queuesListingResult) + { + queues.Add(item); + } + + return queues; + } + + return new List { + GetQueueUsingEntityPath(timeoutInSeconds) + }; + } + throw new ApplicationException(ServiceBusIsDisconnected); + } + + /// + /// Retrieves a queue in the service bus namespace that matches the entity path. + /// + private QueueRuntimeProperties GetQueueUsingEntityPath(int timeoutInSeconds) + { + var taskList = new List(); + var getQueueTask = serviceBusAdministrationClient.GetQueueRuntimePropertiesAsync(serviceBusNamespaceInstance.EntityPath); + taskList.Add(getQueueTask); + taskList.Add(Task.Delay(TimeSpan.FromSeconds(timeoutInSeconds))); + Task.WaitAny(taskList.ToArray()); + if (getQueueTask.IsCompleted) + { + try + { + return getQueueTask.Result; + } + catch (AggregateException ex) + { + throw ex.InnerExceptions.First(); + } + } + throw new TimeoutException(); + } + + /// + /// Retrieves the queue from the service namespace. + /// + /// Path of the queue relative to the service namespace base address. + /// A QueueDescription handle to the queue, or null if the queue does not exist in the service namespace. + public QueueProperties GetQueue(string path) + { + if (string.IsNullOrWhiteSpace(path)) + { + throw new ArgumentException(PathCannotBeNull); + } + if (serviceBusAdministrationClient != null) + { + return RetryHelper.RetryFunc(() => serviceBusAdministrationClient.GetQueueAsync(path).Result.Value, writeToLog); + } + throw new ApplicationException(ServiceBusIsDisconnected); + } + + /// . + /// Creates a new queue in the service namespace with the given name. + /// + /// Path of the queue relative to the service namespace base address. + /// Returns a newly-created QueueDescription object. + public QueueProperties CreateQueue(string path) + { + if (string.IsNullOrWhiteSpace(path)) + { + throw new ArgumentException(PathCannotBeNull); + } + if (serviceBusAdministrationClient != null) + { + var queue = RetryHelper.RetryFunc(() => serviceBusAdministrationClient.CreateQueueAsync(path).Result.Value, writeToLog); + WriteToLogIf(traceEnabled, string.Format(CultureInfo.CurrentCulture, QueueCreated, path)); + OnCreate?.Invoke(new ServiceBusHelperEventArgs(queue, EntityType.Queue)); + return queue; + } + throw new ApplicationException(ServiceBusIsDisconnected); + } + + /// + /// Creates a new queue in the service namespace with the given name. + /// + /// A QueueDescription object describing the attributes with which the new queue will be created. + /// Returns a newly-created QueueDescription object. + public QueueProperties CreateQueue(QueueProperties description) + { + if (description == null) + { + throw new ArgumentException(DescriptionCannotBeNull); + } + if (serviceBusAdministrationClient != null) + { + var queue = RetryHelper.RetryFunc(() => serviceBusAdministrationClient.CreateQueueAsync(description.Name).Result.Value, writeToLog); + WriteToLogIf(traceEnabled, string.Format(CultureInfo.CurrentCulture, QueueCreated, description.Name)); + OnCreate?.Invoke(new ServiceBusHelperEventArgs(queue, EntityType.Queue)); + return queue; + } + throw new ApplicationException(ServiceBusIsDisconnected); + } + + /// + /// Updates a queue in the service namespace with the given name. + /// + /// A QueueDescription object describing the attributes with which the new queue will be updated. + /// Returns an updated QueueDescription object. + public QueueProperties UpdateQueue(QueueProperties description) + { + if (description == null) + { + throw new ArgumentException(DescriptionCannotBeNull); + } + if (serviceBusAdministrationClient != null) + { + var queue = RetryHelper.RetryFunc(() => serviceBusAdministrationClient.UpdateQueueAsync(description).Result.Value, writeToLog); + WriteToLogIf(traceEnabled, string.Format(CultureInfo.CurrentCulture, QueueUpdated, description.Name)); + OnCreate?.Invoke(new ServiceBusHelperEventArgs(queue, EntityType.Queue)); + return queue; + } + throw new ApplicationException(ServiceBusIsDisconnected); + } + + /// + /// Deletes all the queues in the list. + /// A list of queues to delete. + /// + public async Task DeleteQueues(IEnumerable queues) + { + if (queues == null) + { + return; + } + + await Task.WhenAll(queues.Select(DeleteQueue)); + } + + /// + /// Deletes the queue described by the relative name of the service namespace base address. + /// + /// Path of the queue relative to the service namespace base address. + public async Task DeleteQueue(string path) + { + if (string.IsNullOrWhiteSpace(path)) + { + throw new ArgumentException(PathCannotBeNull); + } + if (serviceBusAdministrationClient != null) + { + await RetryHelper.RetryActionAsync(() => serviceBusAdministrationClient.DeleteQueueAsync(path), writeToLog); + WriteToLogIf(traceEnabled, string.Format(CultureInfo.CurrentCulture, QueueDeleted, path)); + OnDelete?.Invoke(new ServiceBusHelperEventArgs(path, EntityType.Queue)); + } + else + { + throw new ApplicationException(ServiceBusIsDisconnected); + } + } + + /// + /// Deletes the queue passed as a argument. + /// + /// The queue to delete. + public async Task DeleteQueue(QueueProperties queueDescription) + { + if (queueDescription == null) + { + throw new ArgumentException(QueueDescriptionCannotBeNull); + } + if (serviceBusAdministrationClient != null) + { + await RetryHelper.RetryActionAsync(() => serviceBusAdministrationClient.DeleteQueueAsync(queueDescription.Name), writeToLog); + WriteToLogIf(traceEnabled, string.Format(CultureInfo.CurrentCulture, QueueDeleted, queueDescription.Name)); + OnDelete?.Invoke(new ServiceBusHelperEventArgs(queueDescription, EntityType.Queue)); + } + else + { + throw new ApplicationException(ServiceBusIsDisconnected); + } + } + + /* + /// + /// Renames a queue inside a namespace. + /// + /// The path to an existing queue. + /// The new path to the renamed queue. + /// Returns a QueueDescription with the new name. + public QueueProperties RenameQueue(string path, string newPath) + { + if (string.IsNullOrWhiteSpace(path)) + { + throw new ArgumentException(PathCannotBeNull); + } + if (string.IsNullOrWhiteSpace(newPath)) + { + throw new ArgumentException(NewPathCannotBeNull); + } + if (serviceBusAdministrationClient != null) + { + var queueDescription = RetryHelper.RetryFunc(() => serviceBusAdministrationClient.RenameQueue(path, newPath), writeToLog); + WriteToLogIf(traceEnabled, string.Format(CultureInfo.CurrentCulture, QueueRenamed, path, newPath)); + OnDelete?.Invoke(new ServiceBusHelperEventArgs(new QueueProperties(path), EntityType.Queue)); + OnCreate?.Invoke(new ServiceBusHelperEventArgs(queueDescription, EntityType.Queue)); + return queueDescription; + } + throw new ApplicationException(ServiceBusIsDisconnected); + } + */ + + #endregion + + /*/// + /// Retrieves an enumerable collection of all message sessions for the queue passed as argument. + /// + /// The queue for which to search message sessions. + /// The time the session was last updated. + /// Returns an IEnumerable collection of message sessions. + public IEnumerable GetMessageSessions(string path, DateTime? dateTime) + { + if (string.IsNullOrWhiteSpace(path)) + { + throw new ArgumentException(PathCannotBeNull); + } + if (serviceBusAdministrationClient == null) + { + throw new ApplicationException(ServiceBusIsDisconnected); + + } + var queueClient = serviceBusClient.CreateSessionProcessor(path); + return RetryHelper.RetryFunc(() => dateTime != null ? queueClient.GetMessageSessions(dateTime.Value) : queueClient.GetMessageSessions(), writeToLog); + } + + /// + /// Retrieves an enumerable collection of all message sessions for the queue passed as argument. + /// + /// The queue for which to search message sessions. + /// The time the session was last updated. + /// Returns an IEnumerable collection of message sessions. + public IEnumerable GetMessageSessions(QueueDescription queue, DateTime? dateTime) + { + if (queue == null) + { + throw new ArgumentException(QueueDescriptionCannotBeNull); + } + if (messagingFactory == null) + { + throw new ApplicationException(ServiceBusIsDisconnected); + + } + var queueClient = messagingFactory.CreateQueueClient(queue.Path); + return RetryHelper.RetryFunc(() => dateTime != null ? queueClient.GetMessageSessions(dateTime.Value) : queueClient.GetMessageSessions(), writeToLog); + } + */ + + + + + #endregion + + private void WriteToLog(string message) + { + if (writeToLog != null && + !string.IsNullOrWhiteSpace(message)) + { + writeToLog(message); + } + } + + private void WriteToLogIf(bool condition, string message, bool async = false) + { + if (condition && + writeToLog != null && + !string.IsNullOrWhiteSpace(message)) + { + writeToLog(message, async); + } + } + + private static Encoding GetEncoding() + { + // Todo can possibly go + return encodingType; + } + + private static bool TestNamespaceHostIsContactable(ServiceBusNamespace2 serviceBusNamespace) + { + if (!Uri.TryCreate(serviceBusNamespace.Uri, UriKind.Absolute, out var namespaceUri)) + { + return false; + } + + try + { + System.Net.Dns.GetHostEntry(namespaceUri.Host); + } + catch + { + return false; + } + + return true; + } + } +} diff --git a/src/Common/Helpers/ServiceBusNamespace.cs b/src/Common/Helpers/ServiceBusNamespace.cs index c560a699..e959250b 100644 --- a/src/Common/Helpers/ServiceBusNamespace.cs +++ b/src/Common/Helpers/ServiceBusNamespace.cs @@ -141,7 +141,7 @@ public ServiceBusNamespace(ServiceBusNamespaceType connectionStringType, { ConnectionStringType = connectionStringType; Uri = string.IsNullOrWhiteSpace(uri) ? - ServiceBusEnvironment.CreateServiceUri("sb", ns, servicePath).ToString() : + ("sb", ns, servicePath).ToString() : uri; ConnectionString = connectionString; diff --git a/src/Common/Helpers/ServiceBusNamespace2.cs b/src/Common/Helpers/ServiceBusNamespace2.cs new file mode 100644 index 00000000..4cf2270b --- /dev/null +++ b/src/Common/Helpers/ServiceBusNamespace2.cs @@ -0,0 +1,588 @@ +#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 + +#region Using Directives + +using System; +using System.Text.RegularExpressions; +using Azure.Messaging.ServiceBus; +using System.Globalization; +using System.Linq; +using System.Collections.Generic; +using ServiceBusExplorer.Utilities.Helpers; + +#endregion + +namespace ServiceBusExplorer.Helpers +{ + using Microsoft.ServiceBus; + + public enum ServiceBusNamespaceType2 + { + Custom, + Cloud, + OnPremises + } + + /// + /// This class represents a service bus namespace address and authentication credentials + /// + public class ServiceBusNamespace2 + { + #region Private Constants + //*************************** + // Constants for accessing configuration files + //*************************** + const string ServiceBusNamespaces = "serviceBusNamespaces"; + + //*************************** + // Messages + //*************************** + const string ServiceBusNamespacesNotConfigured = "Service bus accounts have not been properly configured in the configuration file."; + const string ServiceBusNamespaceIsNullOrEmpty = "The connection string for service bus entry {0} is null or empty."; + const string ServiceBusNamespaceIsWrong = "The connection string for service bus namespace {0} is in the wrong format."; + const string ServiceBusNamespaceEndpointIsNullOrEmpty = "The endpoint for the service bus namespace {0} is null or empty."; + const string ServiceBusNamespaceEndpointPrefixedWithSb = "The endpoint for the service bus namespace {0} is being automatically prefixed with \"sb://\"."; + const string ServiceBusNamespaceStsEndpointIsNullOrEmpty = "The sts endpoint for the service bus namespace {0} is null or empty."; + const string ServiceBusNamespaceRuntimePortIsNullOrEmpty = "The runtime port for the service bus namespace {0} is null or empty."; + const string ServiceBusNamespaceManagementPortIsNullOrEmpty = "The management port for the service bus namespace {0} is null or empty."; + const string ServiceBusNamespaceEndpointUriIsInvalid = "The endpoint URI for the service bus namespace {0} is invalid."; + const string ServiceBusNamespaceSharedAccessKeyNameIsInvalid = "The SharedAccessKeyName for the service bus namespace {0} is invalid."; + const string ServiceBusNamespaceSharedAccessKeyIsInvalid = "The SharedAccessKey for the service bus namespace {0} is invalid."; + + //*************************** + // Parameters + //*************************** + const string ConnectionStringEndpoint = "endpoint"; + const string ConnectionStringSharedAccessKeyName = "sharedaccesskeyname"; + const string ConnectionStringSharedAccessKey = "sharedaccesskey"; + const string ConnectionStringStsEndpoint = "stsendpoint"; + const string ConnectionStringRuntimePort = "runtimeport"; + const string ConnectionStringManagementPort = "managementport"; + const string ConnectionStringWindowsUsername = "windowsusername"; + const string ConnectionStringWindowsDomain = "windowsdomain"; + const string ConnectionStringWindowsPassword = "windowspassword"; + const string ConnectionStringTransportType = "transporttype"; + const string ConnectionStringEntityPath = "entitypath"; + + #endregion + + #region Public Constants + //*************************** + // Formats + //*************************** + public const string SasConnectionStringFormat = "Endpoint={0};SharedAccessKeyName={1};SharedAccessKey={2};TransportType={3}"; + public const string SasConnectionStringEntityPathFormat = "Endpoint={0};SharedAccessKeyName={1};SharedAccessKey={2};TransportType={3};EntityPath={4}"; + #endregion + + #region Public Constructors + /// + /// Initializes a new instance of the ServiceBusHelper class. + /// + public ServiceBusNamespace2() + { + ConnectionStringType = ServiceBusNamespaceType.Cloud; + ConnectionString = default(string); + Uri = default(string); + Namespace = default(string); + ServicePath = default(string); + StsEndpoint = default(string); + RuntimePort = default(string); + ManagementPort = default(string); + WindowsDomain = default(string); + WindowsUserName = default(string); + WindowsPassword = default(string); + } + + /// + /// Initializes a new instance of the ServiceBusNamespace class. + /// + /// The service bus namespace connection string type. + /// The service bus namespace connection string. + /// The full address of the service bus namespace. + /// The service bus namespace. + /// The issuer name of the shared secret credentials. + /// The issuer secret of the shared secret credentials. + /// The service path that follows the host name section of the URI. + /// The sts endpoint of the service bus namespace. + /// The transport type to use to access the namespace. + /// True is is SAS connection string, false otherwise. + /// Entity path connection string scoped to. Otherwise a default. + public ServiceBusNamespace2(ServiceBusNamespaceType connectionStringType, + string connectionString, + string uri, + string ns, + string servicePath, + string name, + string key, + string stsEndpoint, + ServiceBusTransportType transportType, + bool isSas = false, + string entityPath = "", + bool isUserCreated = false) + { + ConnectionStringType = connectionStringType; + if (string.IsNullOrWhiteSpace(uri)) + { + if (isSas) + { + ServiceBusConnectionStringBuilder.CreateUsingSharedSecret(new Uri(ConnectionString), name, key); + } + // todo expand + } + else + { + Uri = uri; + } + + ConnectionString = connectionString; + Namespace = ns; + + if (isSas) + { + SharedAccessKeyName = name; + SharedAccessKey = key; + } + else + { + ServicePath = servicePath; + } + + TransportType = transportType; + StsEndpoint = stsEndpoint; + RuntimePort = default(string); + ManagementPort = default(string); + WindowsDomain = default(string); + WindowsUserName = default(string); + WindowsPassword = default(string); + EntityPath = entityPath; + UserCreated = isUserCreated; + } + + /// + /// Initializes a new instance of the ServiceBusNamespace class for an on-premises namespace. + /// + /// The service bus namespace connection string. + /// The endpoint of the service bus namespace. + /// The sts endpoint of the service bus namespace. + /// The runtime port. + /// The management port. + /// The Windows domain or machine name. + /// The Windows user name. + /// The Windows user password. + /// The service bus namespace. + /// The transport type to use to access the namespace. + public ServiceBusNamespace2(string connectionString, + string endpoint, + string stsEndpoint, + string runtimePort, + string managementPort, + string windowsDomain, + string windowsUsername, + string windowsPassword, + string ns, + ServiceBusTransportType transportType, + bool isUserCreated = false) + { + ConnectionStringType = ServiceBusNamespaceType.OnPremises; + ConnectionString = connectionString; + Uri = endpoint; + var uri = new Uri(endpoint); + + + if (string.IsNullOrWhiteSpace(endpoint)) + { + Uri = ServiceBusEnvironment.CreateServiceUri(uri.Scheme, ns, null).ToString(); + } + + Namespace = ns; + TransportType = ServiceBusTransportType.AmqpTcp; + StsEndpoint = stsEndpoint; + RuntimePort = runtimePort; + ManagementPort = managementPort; + WindowsDomain = windowsDomain; + WindowsUserName = windowsUsername; + WindowsPassword = windowsPassword; + TransportType = transportType; + UserCreated = isUserCreated; + } + #endregion + + #region Public methods + public static ServiceBusNamespace2 GetServiceBusNamespace(string key, string connectionString, + WriteToLogDelegate staticWriteToLog) + { + + if (string.IsNullOrWhiteSpace(connectionString)) + { + staticWriteToLog(string.Format(CultureInfo.CurrentCulture, ServiceBusNamespaceIsNullOrEmpty, key)); + return null; + } + + var isUserCreated = !(key == "CustomConnectionString" || key == "SASConnectionString"); + var toLower = connectionString.ToLower(); + var parameters = connectionString.Split(';').ToDictionary(s => s.Substring(0, s.IndexOf('=')).ToLower(), s => s.Substring(s.IndexOf('=') + 1)); + + if (toLower.Contains(ConnectionStringEndpoint) && + toLower.Contains(ConnectionStringSharedAccessKeyName) && + toLower.Contains(ConnectionStringSharedAccessKey)) + { + return GetServiceBusNamespaceUsingSAS(key, connectionString, staticWriteToLog, + isUserCreated, parameters); + } + + if (toLower.Contains(ConnectionStringRuntimePort) || + toLower.Contains(ConnectionStringManagementPort) || + toLower.Contains(ConnectionStringWindowsUsername) || + toLower.Contains(ConnectionStringWindowsDomain) || + toLower.Contains(ConnectionStringWindowsPassword)) + { + return GetServiceBusNamespaceUsingWindows(key, connectionString, staticWriteToLog, + isUserCreated, toLower, parameters); + } + + return null; + } + + public static Dictionary GetMessagingNamespaces + (TwoFilesConfiguration configuration, WriteToLogDelegate writeToLog) + { + var hashtable = configuration.GetHashtableFromSection(ServiceBusNamespaces); + + if (hashtable == null || hashtable.Count == 0) + { + writeToLog(ServiceBusNamespacesNotConfigured); + } + + var serviceBusNamespaces = new Dictionary(); + + if (hashtable == null) + { + return serviceBusNamespaces; + } + + var e = hashtable.GetEnumerator(); + + while (e.MoveNext()) + { + if (!(e.Key is string) || !(e.Value is string)) + { + continue; + } + + var serviceBusNamespace = ServiceBusNamespace2.GetServiceBusNamespace((string)e.Key, (string)e.Value, writeToLog); + + if (serviceBusNamespace != null) + { + serviceBusNamespaces.Add((string)e.Key, serviceBusNamespace); + } + } + + var microsoftServiceBusConnectionString = + configuration.GetStringValue(ConfigurationParameters.MicrosoftServiceBusConnectionString); + + if (!string.IsNullOrWhiteSpace(microsoftServiceBusConnectionString)) + { + var serviceBusNamespace = ServiceBusNamespace2.GetServiceBusNamespace(ConfigurationParameters.MicrosoftServiceBusConnectionString, microsoftServiceBusConnectionString, writeToLog); + + if (serviceBusNamespace != null) + { + serviceBusNamespaces. + Add(ConfigurationParameters.MicrosoftServiceBusConnectionString, serviceBusNamespace); + } + } + + return serviceBusNamespaces; + } + + public static void SaveConnectionString(TwoFilesConfiguration configuration, + string key, string value, WriteToLogDelegate staticWriteToLog) + { + configuration.AddEntryToDictionarySection(ServiceBusNamespaces, key, value); + } + #endregion + + #region Public Properties + + /// + /// Gets or sets the service bus namespace type. + /// + public ServiceBusNamespaceType ConnectionStringType { get; set; } + + /// + /// Get or set if this is a connection string added by the user + /// + public bool UserCreated { get; set; } + + /// + /// Gets or sets the service bus namespace connection string. + /// + public string ConnectionString { get; set; } + + /// + /// Gets or sets the service bus namespace connection string without transport type. + /// + public string ConnectionStringWithoutTransportType + { + get + { + var regex = new Regex(@";TransportType=\w*;?"); + var connectionString = regex.Replace(ConnectionString, string.Empty); + return connectionString; + } + } + + /// + /// Gets or sets the full address of the service bus namespace. + /// + public string Uri { get; set; } + + /// + /// Gets or sets the service bus namespace. + /// + public string Namespace { get; set; } + + /// + /// Gets or sets the service path that follows the host name section of the URI. + /// + public string ServicePath { get; set; } + + /// + /// Gets or sets the transport type to use to access the namespace. + /// + public ServiceBusTransportType TransportType { get; set; } + + /// + /// Gets or sets the URL of the sts endpoint. + /// + public string StsEndpoint { get; set; } + + /// + /// Gets or sets the runtime port. + /// + public string RuntimePort { get; set; } + + /// + /// Gets or sets the management port. + /// + public string ManagementPort { get; set; } + + /// + /// Gets or sets the windows domain. + /// + public string WindowsDomain { get; set; } + + /// + /// Gets or sets the Windows user name. + /// + public string WindowsUserName { get; set; } + + /// + /// Gets or sets the Windows user password. + /// + public string WindowsPassword { get; set; } + + /// + /// Gets or sets the SharedAccessKeyName. + /// + public string SharedAccessKeyName { get; set; } + + /// + /// Gets or sets the SharedAccessKey. + /// + public string SharedAccessKey { get; set; } + + /// + /// Gets or sets the EntityPath + /// + public string EntityPath { get; set; } + #endregion + + #region Private Methods + + static ServiceBusNamespace2 GetServiceBusNamespaceUsingWindows(string key, string connectionString, + WriteToLogDelegate staticWriteToLog, bool isUserCreated, string toLower, + Dictionary parameters) + { + if (!toLower.Contains(ConnectionStringEndpoint) || + !toLower.Contains(ConnectionStringStsEndpoint) || + !toLower.Contains(ConnectionStringRuntimePort) || + !toLower.Contains(ConnectionStringManagementPort)) + { + return null; + } + + var endpoint = parameters.ContainsKey(ConnectionStringEndpoint) ? + parameters[ConnectionStringEndpoint] : + null; + + if (string.IsNullOrWhiteSpace(endpoint)) + { + staticWriteToLog(string.Format(CultureInfo.CurrentCulture, + ServiceBusNamespaceEndpointIsNullOrEmpty, key)); + return null; + } + + string ns = GetNamespaceNameFromEndpoint(endpoint, staticWriteToLog, key); + + var stsEndpoint = parameters.ContainsKey(ConnectionStringStsEndpoint) ? + parameters[ConnectionStringStsEndpoint] : + null; + + if (string.IsNullOrWhiteSpace(stsEndpoint)) + { + staticWriteToLog(string.Format(CultureInfo.CurrentCulture, + ServiceBusNamespaceStsEndpointIsNullOrEmpty, key)); + return null; + } + + var runtimePort = parameters.ContainsKey(ConnectionStringRuntimePort) ? + parameters[ConnectionStringRuntimePort] : + null; + + if (string.IsNullOrWhiteSpace(runtimePort)) + { + staticWriteToLog(string.Format(CultureInfo.CurrentCulture, + ServiceBusNamespaceRuntimePortIsNullOrEmpty, key)); + return null; + } + + var managementPort = parameters.ContainsKey(ConnectionStringManagementPort) ? + parameters[ConnectionStringManagementPort] : + null; + + if (string.IsNullOrWhiteSpace(managementPort)) + { + staticWriteToLog(string.Format(CultureInfo.CurrentCulture, ServiceBusNamespaceManagementPortIsNullOrEmpty, key)); + return null; + } + + var windowsDomain = parameters.ContainsKey(ConnectionStringWindowsDomain) ? + parameters[ConnectionStringWindowsDomain] : + null; + + var windowsUsername = parameters.ContainsKey(ConnectionStringWindowsUsername) ? + parameters[ConnectionStringWindowsUsername] : + null; + + var windowsPassword = parameters.ContainsKey(ConnectionStringWindowsPassword) ? + parameters[ConnectionStringWindowsPassword] : + null; + + var transportType = ServiceBusTransportType.AmqpTcp; + + if (parameters.ContainsKey(ConnectionStringTransportType)) + { + Enum.TryParse(parameters[ConnectionStringTransportType], true, out transportType); + } + + return new ServiceBusNamespace2(connectionString, endpoint, stsEndpoint, runtimePort, managementPort, windowsDomain, windowsUsername, windowsPassword, ns, transportType, isUserCreated); + } + + static ServiceBusNamespace2 GetServiceBusNamespaceUsingSAS(string key, string connectionString, + WriteToLogDelegate staticWriteToLog, bool isUserCreated, Dictionary parameters) + { + if (parameters.Count < 3) + { + staticWriteToLog(string.Format(CultureInfo.CurrentCulture, ServiceBusNamespaceIsWrong, key)); + return null; + } + + var endpoint = parameters.ContainsKey(ConnectionStringEndpoint) ? + parameters[ConnectionStringEndpoint] : + null; + + if (string.IsNullOrWhiteSpace(endpoint)) + { + staticWriteToLog(string.Format(CultureInfo.CurrentCulture, + ServiceBusNamespaceEndpointIsNullOrEmpty, key)); + return null; + } + + if (!endpoint.Contains("://")) + { + staticWriteToLog(string.Format(CultureInfo.CurrentCulture, + ServiceBusNamespaceEndpointPrefixedWithSb, endpoint)); + endpoint = "sb://" + endpoint; + } + + var stsEndpoint = parameters.ContainsKey(ConnectionStringStsEndpoint) ? + parameters[ConnectionStringStsEndpoint] : + null; + + string ns = GetNamespaceNameFromEndpoint(endpoint, staticWriteToLog, key); + + if (!parameters.ContainsKey(ConnectionStringSharedAccessKeyName) || + string.IsNullOrWhiteSpace(parameters[ConnectionStringSharedAccessKeyName])) + { + staticWriteToLog(string.Format(CultureInfo.CurrentCulture, ServiceBusNamespaceSharedAccessKeyNameIsInvalid, key)); + } + + var sharedAccessKeyName = parameters[ConnectionStringSharedAccessKeyName]; + + if (!parameters.ContainsKey(ConnectionStringSharedAccessKey) || string.IsNullOrWhiteSpace(parameters[ConnectionStringSharedAccessKey])) + { + staticWriteToLog(string.Format(CultureInfo.CurrentCulture, + ServiceBusNamespaceSharedAccessKeyIsInvalid, key)); + } + + var sharedAccessKey = parameters[ConnectionStringSharedAccessKey]; + var transportType = ServiceBusTransportType.AmqpTcp; + + if (parameters.ContainsKey(ConnectionStringTransportType)) + { + Enum.TryParse(parameters[ConnectionStringTransportType], true, out transportType); + } + + string entityPath = string.Empty; + + if (parameters.ContainsKey(ConnectionStringEntityPath)) + { + entityPath = parameters[ConnectionStringEntityPath]; + } + + return new ServiceBusNamespace2(ServiceBusNamespaceType.Cloud, connectionString, endpoint, ns, null, + sharedAccessKeyName, sharedAccessKey, stsEndpoint, transportType, true, + entityPath, isUserCreated); + } + + static string GetNamespaceNameFromEndpoint(string endpoint, WriteToLogDelegate staticWriteToLog, + string key) + { + Uri uri; + + try + { + uri = new Uri(endpoint); + } + catch (Exception) + { + staticWriteToLog(string.Format(CultureInfo.CurrentCulture, + ServiceBusNamespaceEndpointUriIsInvalid, key)); + return null; + } + + return uri.Host.Split('.')[0]; + } + + #endregion + } +} diff --git a/src/ServiceBus/Helpers/ServiceBusPurger.cs b/src/Common/Helpers/ServiceBusPurger.cs similarity index 100% rename from src/ServiceBus/Helpers/ServiceBusPurger.cs rename to src/Common/Helpers/ServiceBusPurger.cs diff --git a/src/ServiceBus/Helpers/TopicSubscriptionServiceBusPurger.cs b/src/Common/Helpers/TopicSubscriptionServiceBusPurger.cs similarity index 100% rename from src/ServiceBus/Helpers/TopicSubscriptionServiceBusPurger.cs rename to src/Common/Helpers/TopicSubscriptionServiceBusPurger.cs diff --git a/src/ServiceBus/Helpers/ServiceBusHelper2.cs b/src/ServiceBus/Helpers/ServiceBusHelper2.cs deleted file mode 100644 index 468fafd0..00000000 --- a/src/ServiceBus/Helpers/ServiceBusHelper2.cs +++ /dev/null @@ -1,67 +0,0 @@ -#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.Threading.Tasks; -using Azure.Messaging.ServiceBus; -using Azure.Messaging.ServiceBus.Administration; - -// ReSharper disable CheckNamespace -namespace ServiceBusExplorer.ServiceBus.Helpers -// ReSharper restore CheckNamespace -{ - public class ServiceBusHelper2 - { - public string ConnectionString { get; set; } - public ServiceBusTransportType TransportType { get; set; } - - public bool ConnectionStringContainsEntityPath() - { - var connectionStringProperties = ServiceBusConnectionStringProperties.Parse(ConnectionString); - - if (connectionStringProperties?.EntityPath != null) - { - return true; - } - - return false; - } - - public async Task IsPremiumNamespace() - { - var administrationClient = new ServiceBusAdministrationClient(ConnectionString); - NamespaceProperties namespaceProperties = await administrationClient.GetNamespacePropertiesAsync().ConfigureAwait(false); - - return namespaceProperties.MessagingSku == MessagingSku.Premium; - } - - public async Task IsQueue(string name) - { - var administrationClient = new ServiceBusAdministrationClient(ConnectionString); - return await administrationClient.QueueExistsAsync(name).ConfigureAwait(false); - } - - public async Task IsTopic(string name) - { - var administrationClient = new ServiceBusAdministrationClient(ConnectionString); - return await administrationClient.TopicExistsAsync(name).ConfigureAwait(false); - } - } -} diff --git a/src/ServiceBusExplorer/Controls/HandleQueueControl.cs b/src/ServiceBusExplorer/Controls/HandleQueueControl.cs index 48c644fe..c645bc8f 100644 --- a/src/ServiceBusExplorer/Controls/HandleQueueControl.cs +++ b/src/ServiceBusExplorer/Controls/HandleQueueControl.cs @@ -24,7 +24,7 @@ #region Using Directives #nullable enable -using Microsoft.ServiceBus.Messaging; +using Azure.Messaging.ServiceBus.Administration; using ServiceBusExplorer.Forms; using ServiceBusExplorer.Helpers; @@ -50,6 +50,13 @@ namespace ServiceBusExplorer.Controls { + using Azure.Messaging.ServiceBus; + using Azure.Messaging.ServiceBus.Administration; + using Microsoft.ServiceBus.Messaging; + using AccessRights = Microsoft.ServiceBus.Messaging.AccessRights; + using EntityStatus = Microsoft.ServiceBus.Messaging.EntityStatus; + using SharedAccessAuthorizationRule = Microsoft.ServiceBus.Messaging.SharedAccessAuthorizationRule; + public partial class HandleQueueControl : UserControl { #region Private Constants @@ -217,8 +224,8 @@ public partial class HandleQueueControl : UserControl private const string TxtExtension = "txt"; private const string JsonFilter = "JSON Files|*.json|Text Documents|*.txt"; private const string AllFilesFilter = "Text Documents|*.txt|JSON Files|*.json|XML Files|*.xml|All Files (*.*)|*.*"; - private const string MessageFileFormat = "BrokeredMessage_{0}_{1}.json"; - private const string MessageFileFormatAutoRecognize = "BrokeredMessage_{0}_{1}.txt"; + private const string MessageFileFormat = "ServiceBusMessage_{0}_{1}.json"; + private const string MessageFileFormatAutoRecognize = "ServiceBusMessage_{0}_{1}.txt"; //*************************** // Pages @@ -233,15 +240,16 @@ public partial class HandleQueueControl : UserControl #region Private Fields - private QueueDescription queueDescription = default!; + private QueueProperties queueProperties = default!; private readonly ServiceBusHelper serviceBusHelper = default!; + private readonly ServiceBusHelper2 serviceBusHelper2 = default!; private readonly WriteToLogDelegate writeToLog = default!; private readonly string path = default!; private readonly List hiddenPages = new List(); private readonly bool premiumNamespace; - private BrokeredMessage brokeredMessage = default!; - private BrokeredMessage deadletterMessage = default!; - private BrokeredMessage transferDeadletterMessage = default!; + private ServiceBusMessage ServiceBusMessage = default!; + private ServiceBusMessage deadletterMessage = default!; + private ServiceBusMessage transferDeadletterMessage = default!; private int currentMessageRowIndex = default!; private int currentDeadletterMessageRowIndex = default!; private int currentTransferDeadletterMessageRowIndex = default!; @@ -252,9 +260,9 @@ public partial class HandleQueueControl : UserControl private DateTime? messagesFilterToDate = default!; private DateTime? deadletterFilterFromDate = default!; private DateTime? deadletterFilterToDate = default!; - private SortableBindingList messageBindingList = default!; - private SortableBindingList deadletterBindingList = default!; - private SortableBindingList transferDeadletterBindingList = default!; + private SortableBindingList messageBindingList = default!; + private SortableBindingList deadletterBindingList = default!; + private SortableBindingList transferDeadletterBindingList = default!; private SortableBindingList sessionBindingList = default!; private bool buttonsMoved; private readonly bool duplicateQueue; @@ -292,12 +300,13 @@ public partial class HandleQueueControl : UserControl #region Public Constructors public HandleQueueControl(WriteToLogDelegate writeToLog, ServiceBusHelper serviceBusHelper, - QueueDescription queueDescription, string path, bool duplicateQueue) + QueueProperties queueProperties, string path, bool duplicateQueue) { this.writeToLog = writeToLog; this.serviceBusHelper = serviceBusHelper; + this.serviceBusHelper2 = serviceBusHelper.GetServiceBusHelper2(); this.path = path; - this.queueDescription = queueDescription; + this.queueProperties = queueProperties; var serviceBusHelper2 = serviceBusHelper.GetServiceBusHelper2(); if (!serviceBusHelper2.ConnectionStringContainsEntityPath()) @@ -326,7 +335,7 @@ public void GetMessages() { using ( var receiveModeForm = new ReceiveModeForm(RetrieveMessagesFromQueue, MainForm.SingletonMainForm.TopCount, - serviceBusHelper.BrokeredMessageInspectors.Keys, queueDescription.RequiresSession)) + serviceBusHelper.BrokeredMessageInspectors.Keys, queueProperties.RequiresSession)) { if (receiveModeForm.ShowDialog() == DialogResult.OK) { @@ -339,7 +348,7 @@ public void GetMessages() ? Activator.CreateInstance(serviceBusHelper.BrokeredMessageInspectors[receiveModeForm.Inspector]) as IBrokeredMessageInspector : null; - if (queueDescription.EnablePartitioning) + if (queueProperties.EnablePartitioning) { ReadMessagesOneAtTheTime(receiveModeForm.Peek, receiveModeForm.All, receiveModeForm.Count, messageInspector, receiveModeForm.FromSequenceNumber, receiveModeForm.FromSession); @@ -354,7 +363,7 @@ as IBrokeredMessageInspector public void PurgeMessages(int numberOfMessages) { - if (queueDescription.EnablePartitioning) + if (queueProperties.EnablePartitioning) { ReadMessagesOneAtTheTime(false, true, numberOfMessages, null); } @@ -366,18 +375,18 @@ public void PurgeMessages(int numberOfMessages) public async Task PurgeMessagesAsync() { - await this.DoPurge(PurgeStrategies.Messages, $"Would you like to purge the {queueDescription.Path} queue?"); + await this.DoPurge(PurgeStrategies.Messages, $"Would you like to purge the {queueProperties.Name} queue?"); } public async Task PurgeDeadletterQueueMessagesAsync() { - await this.DoPurge(PurgeStrategies.DeadletteredMessages, $"Would you like to purge the dead-letter queue of the {queueDescription.Path} queue?"); + await this.DoPurge(PurgeStrategies.DeadletteredMessages, $"Would you like to purge the dead-letter queue of the {queueProperties.Name} queue?"); } public async Task PurgeAllMessagesAsync() { - await this.DoPurge(PurgeStrategies.All, $"Would you like to purge all (messages and dead-lettered messages) from the {queueDescription.Path} queue?"); + await this.DoPurge(PurgeStrategies.All, $"Would you like to purge all (messages and dead-lettered messages) from the {queueProperties.Name} queue?"); } private async Task DoPurge(PurgeStrategies purgeStrategy, string deleteConfirmation) @@ -392,7 +401,7 @@ private async Task DoPurge(PurgeStrategies purgeStrategy, string deleteConfirmat QueueServiceBusPurger purger = new QueueServiceBusPurger(this.serviceBusHelper.GetServiceBusHelper2()); purger.PurgeFailed += (o, e) => this.HandleException(e.Exception); purger.PurgeCompleted += (o, e) => writeToLog($"[{e.TotalMessagesPurged}] messages have been purged from the{(e.IsDeadLetterQueue ? " dead-letter queue of the" : "")} [{e.EntityPath}] queue in [{e.ElapsedMilliseconds / 1000}] seconds."); - await purger.Purge(purgeStrategy, await this.serviceBusHelper.GetQueueProperties(queueDescription)); + await purger.Purge(purgeStrategy, await this.serviceBusHelper2.GetQueueProperties(queueProperties)); await MainForm.SingletonMainForm.RefreshSelectedEntity(); Application.UseWaitCursor = false; @@ -400,59 +409,59 @@ private async Task DoPurge(PurgeStrategies purgeStrategy, string deleteConfirmat public void GetDeadletterMessages() { - using (var receiveModeForm = new ReceiveModeForm(RetrieveMessagesFromDeadletterQueue, MainForm.SingletonMainForm.TopCount, serviceBusHelper.BrokeredMessageInspectors.Keys)) + using (var ReceiveModeForm = new ReceiveModeForm(RetrieveMessagesFromDeadletterQueue, MainForm.SingletonMainForm.TopCount, serviceBusHelper.BrokeredMessageInspectors.Keys)) { - if (receiveModeForm.ShowDialog() != DialogResult.OK) + if (ReceiveModeForm.ShowDialog() != DialogResult.OK) { return; } txtDeadletterText.Text = string.Empty; deadletterCustomPropertyGrid.SelectedObject = null; deadletterPropertyGrid.SelectedObject = null; - var messageInspector = !string.IsNullOrEmpty(receiveModeForm.Inspector) && serviceBusHelper.BrokeredMessageInspectors.ContainsKey(receiveModeForm.Inspector) - ? Activator.CreateInstance(serviceBusHelper.BrokeredMessageInspectors[receiveModeForm.Inspector]) as IBrokeredMessageInspector + var messageInspector = !string.IsNullOrEmpty(ReceiveModeForm.Inspector) && serviceBusHelper.BrokeredMessageInspectors.ContainsKey(ReceiveModeForm.Inspector) + ? Activator.CreateInstance(serviceBusHelper.BrokeredMessageInspectors[ReceiveModeForm.Inspector]) as IBrokeredMessageInspector : null; - if (queueDescription.EnablePartitioning) + if (queueProperties.EnablePartitioning) { - ReadDeadletterMessagesOneAtTheTime(receiveModeForm.Peek, receiveModeForm.All, receiveModeForm.Count, messageInspector, receiveModeForm.FromSequenceNumber); + ReadDeadletterMessagesOneAtTheTime(ReceiveModeForm.Peek, ReceiveModeForm.All, ReceiveModeForm.Count, messageInspector, ReceiveModeForm.FromSequenceNumber); } else { - GetDeadletterMessages(receiveModeForm.Peek, receiveModeForm.All, receiveModeForm.Count, messageInspector, receiveModeForm.FromSequenceNumber); + GetDeadletterMessages(ReceiveModeForm.Peek, ReceiveModeForm.All, ReceiveModeForm.Count, messageInspector, ReceiveModeForm.FromSequenceNumber); } } } public void GetTransferDeadletterMessages() { - using (var receiveModeForm = new ReceiveModeForm(RetrieveMessagesFromTransferDeadletterQueue, MainForm.SingletonMainForm.TopCount, serviceBusHelper.BrokeredMessageInspectors.Keys)) + using (var ReceiveModeForm = new ReceiveModeForm(RetrieveMessagesFromTransferDeadletterQueue, MainForm.SingletonMainForm.TopCount, serviceBusHelper.BrokeredMessageInspectors.Keys)) { - if (receiveModeForm.ShowDialog() != DialogResult.OK) + if (ReceiveModeForm.ShowDialog() != DialogResult.OK) { return; } txtTransferDeadletterText.Text = string.Empty; transferDeadletterCustomPropertyGrid.SelectedObject = null; transferDeadletterPropertyGrid.SelectedObject = null; - var messageInspector = !string.IsNullOrEmpty(receiveModeForm.Inspector) && serviceBusHelper.BrokeredMessageInspectors.ContainsKey(receiveModeForm.Inspector) - ? Activator.CreateInstance(serviceBusHelper.BrokeredMessageInspectors[receiveModeForm.Inspector]) as IBrokeredMessageInspector + var messageInspector = !string.IsNullOrEmpty(ReceiveModeForm.Inspector) && serviceBusHelper.BrokeredMessageInspectors.ContainsKey(ReceiveModeForm.Inspector) + ? Activator.CreateInstance(serviceBusHelper.BrokeredMessageInspectors[ReceiveModeForm.Inspector]) as IBrokeredMessageInspector : null; - if (queueDescription.EnablePartitioning) + if (queueProperties.EnablePartitioning) { - ReadTransferDeadletterMessagesOneAtTheTime(receiveModeForm.Peek, receiveModeForm.All, receiveModeForm.Count, messageInspector, receiveModeForm.FromSequenceNumber); + ReadTransferDeadletterMessagesOneAtTheTime(ReceiveModeForm.Peek, ReceiveModeForm.All, ReceiveModeForm.Count, messageInspector, ReceiveModeForm.FromSequenceNumber); } else { - GetTransferDeadletterMessages(receiveModeForm.Peek, receiveModeForm.All, receiveModeForm.Count, messageInspector, receiveModeForm.FromSequenceNumber); + GetTransferDeadletterMessages(ReceiveModeForm.Peek, ReceiveModeForm.All, ReceiveModeForm.Count, messageInspector, ReceiveModeForm.FromSequenceNumber); } } } - public void RefreshData(QueueDescription queue) + public void RefreshData(QueueProperties queue) { try { - queueDescription = queue; + queueProperties = queue; InitializeData(); } catch (Exception ex) @@ -470,8 +479,8 @@ public void GetMessageSessions() tabPageSessions.SuspendDrawing(); tabPageSessions.SuspendLayout(); - var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queueDescription.Path, - ReceiveMode.PeekLock); + ReceiverOptions options = new ReceiverOptions(); + var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queueProperties.Name, ReceiveMode.PeekLock); var sessionEnumerable = queueClient.GetMessageSessions(); if (sessionEnumerable == null) { @@ -490,7 +499,7 @@ public void GetMessageSessions() AllowNew = false, AllowRemove = false }; - writeToLog(string.Format(SessionsGotFromTheQueue, sessionBindingList.Count, queueDescription.Path)); + writeToLog(string.Format(SessionsGotFromTheQueue, sessionBindingList.Count, queueProperties.Name)); sessionsBindingSource.DataSource = sessionBindingList; sessionsDataGridView.DataSource = sessionsBindingSource; @@ -679,7 +688,7 @@ private void InitializeControls(bool initialCall) } - if (queueDescription != null) + if (queueProperties != null) { if (duplicateQueue) { @@ -1049,8 +1058,9 @@ private void ConfigureDuplicateUserInterface() // special handling for max size if partitioning is enabled trackBarMaxQueueSize.Maximum = serviceBusHelper.IsCloudNamespace ? 5 : 11; - trackBarMaxQueueSize.Value = queueDescription.EnablePartitioning ? queueDescription.MaxSizeInGigabytes() / 16 - : queueDescription.MaxSizeInGigabytes(); + trackBarMaxQueueSize.Value = (int)(queueProperties.EnablePartitioning + ? queueProperties.MaxSizeInMegabytes / 16 + : queueProperties.MaxSizeInMegabytes); ConfigureCreateUserInterface(); } @@ -1073,7 +1083,7 @@ private void ConfigureCreateUserInterface() btnTransferDeadletterQueue.Visible = false; // Create BindingList for Authorization Rules - var bindingList = new BindingList(new List()) + var bindingList = new BindingList(new List()) { AllowEdit = true, AllowNew = true, @@ -1096,14 +1106,14 @@ private void bindingList_ListChanged(object sender, ListChangedEventArgs e) { if (e.ListChangedType == ListChangedType.ItemDeleted) { - if (queueDescription != null && - queueDescription.Authorization.Count > 0 && - queueDescription.Authorization.Count > e.NewIndex) + if (queueProperties != null && + queueProperties.AuthorizationRules.Count > 0 && + queueProperties.AuthorizationRules.Count > e.NewIndex) { - var rule = queueDescription.Authorization.ElementAt(e.NewIndex); + var rule = queueProperties.AuthorizationRules.ElementAt(e.NewIndex); if (rule != null) { - queueDescription.Authorization.Remove(rule); + queueProperties.AuthorizationRules.Remove(rule); } } } @@ -1118,7 +1128,7 @@ private void InitializeData() btnRefresh.Visible = true; btnChangeStatus.Visible = true; btnMessages.Visible = true; - btnSessions.Visible = queueDescription.RequiresSession; + btnSessions.Visible = queueProperties.RequiresSession; if (btnMessages.Visible && !btnSessions.Visible && !buttonsMoved) { @@ -1129,11 +1139,11 @@ private void InitializeData() btnDeadletter.Visible = true; // Authorization Rules - BindingList bindingList; - if (queueDescription.Authorization.Count > 0) + BindingList bindingList; + if (queueProperties.AuthorizationRules.Count > 0) { - var enumerable = queueDescription.Authorization.Select(r => new AuthorizationRuleWrapper(r)); - bindingList = new BindingList(enumerable.ToList()) + var enumerable = queueProperties.AuthorizationRules.Select(r => new AuthorizationRuleWrapper2(r)); + bindingList = new BindingList(enumerable.ToList()) { AllowEdit = true, AllowNew = true, @@ -1143,7 +1153,7 @@ private void InitializeData() } else { - bindingList = new BindingList(new List()) + bindingList = new BindingList(new List()) { AllowEdit = true, AllowNew = true, @@ -1151,7 +1161,7 @@ private void InitializeData() }; } bindingList.ListChanged += bindingList_ListChanged; - authorizationRulesBindingSource.DataSource = new BindingList(bindingList); + authorizationRulesBindingSource.DataSource = new BindingList(bindingList); authorizationRulesDataGridView.DataSource = authorizationRulesBindingSource; // Initialize property grid @@ -1159,40 +1169,40 @@ private void InitializeData() propertyList.AddRange(new[] { - new[] {Status, queueDescription.Status.ToString()}, - new[] {IsReadOnly, queueDescription.IsReadOnly.ToString()}, - new[] {SizeInBytes, queueDescription.SizeInBytes.ToString("N0")}, - new[] {CreatedAt, queueDescription.CreatedAt.ToString(CultureInfo.CurrentCulture)}, - new[] {AccessedAt, queueDescription.AccessedAt.ToString(CultureInfo.CurrentCulture)}, - new[] {UpdatedAt, queueDescription.UpdatedAt.ToString(CultureInfo.CurrentCulture)}, + new[] {Status, queueProperties.Status.ToString()}, + /*new[] {IsReadOnly, queueProperties.IsReadOnly.ToString()}, + new[] {SizeInBytes, queueProperties.SizeInBytes.ToString("N0")}, + new[] {CreatedAt, queueProperties.CreatedAt.ToString(CultureInfo.CurrentCulture)}, + new[] {AccessedAt, queueProperties.AccessedAt.ToString(CultureInfo.CurrentCulture)}, + new[] {UpdatedAt, queueProperties.UpdatedAt.ToString(CultureInfo.CurrentCulture)}, new[] { ActiveMessageCount, - queueDescription.MessageCountDetails.ActiveMessageCount.ToString("N0", CultureInfo.CurrentCulture) + queueProperties.MessageCountDetails.ActiveMessageCount.ToString("N0", CultureInfo.CurrentCulture) }, new[] { DeadLetterCount, - queueDescription.MessageCountDetails.DeadLetterMessageCount.ToString("N0", + queueProperties.MessageCountDetails.DeadLetterMessageCount.ToString("N0", CultureInfo.CurrentCulture) }, new[] { ScheduledMessageCount, - queueDescription.MessageCountDetails.ScheduledMessageCount.ToString("N0", CultureInfo.CurrentCulture) + queueProperties.MessageCountDetails.ScheduledMessageCount.ToString("N0", CultureInfo.CurrentCulture) }, new[] { TransferMessageCount, - queueDescription.MessageCountDetails.TransferMessageCount.ToString("N0", CultureInfo.CurrentCulture) + queueProperties.MessageCountDetails.TransferMessageCount.ToString("N0", CultureInfo.CurrentCulture) }, new[] { TransferDeadLetterMessageCount, - queueDescription.MessageCountDetails.TransferDeadLetterMessageCount.ToString("N0", + queueProperties.MessageCountDetails.TransferDeadLetterMessageCount.ToString("N0", CultureInfo.CurrentCulture) }, - new[] {MessageCount, queueDescription.MessageCount.ToString("N0", CultureInfo.CurrentCulture)} + new[] {MessageCount, queueProperties.MessageCount.ToString("N0", CultureInfo.CurrentCulture)}*/ }); propertyListView.Items.Clear(); @@ -1202,112 +1212,117 @@ private void InitializeData() } // Path - if (!string.IsNullOrWhiteSpace(queueDescription.Path)) + if (!string.IsNullOrWhiteSpace(queueProperties.Name)) { - txtPath.Text = queueDescription.Path; + txtPath.Text = queueProperties.Name; } // UserMetadata - if (!string.IsNullOrWhiteSpace(queueDescription.UserMetadata)) + if (!string.IsNullOrWhiteSpace(queueProperties.UserMetadata)) { - txtUserMetadata.Text = queueDescription.UserMetadata; + txtUserMetadata.Text = queueProperties.UserMetadata; } // ForwardTo - if (!string.IsNullOrWhiteSpace(queueDescription.ForwardTo)) + if (!string.IsNullOrWhiteSpace(queueProperties.ForwardTo)) { - txtForwardTo.Text = serviceBusHelper.GetAddressRelativeToNamespace(queueDescription.ForwardTo); + txtForwardTo.Text = serviceBusHelper.GetAddressRelativeToNamespace(queueProperties.ForwardTo); } // ForwardDeadLetteredMessagesTo - if (!string.IsNullOrWhiteSpace(queueDescription.ForwardDeadLetteredMessagesTo)) + if (!string.IsNullOrWhiteSpace(queueProperties.ForwardDeadLetteredMessagesTo)) { - txtForwardDeadLetteredMessagesTo.Text = serviceBusHelper.GetAddressRelativeToNamespace(queueDescription.ForwardDeadLetteredMessagesTo); + txtForwardDeadLetteredMessagesTo.Text = serviceBusHelper.GetAddressRelativeToNamespace(queueProperties.ForwardDeadLetteredMessagesTo); } // MaxQueueSizeInBytes - trackBarMaxQueueSize.Value = serviceBusHelper.IsCloudNamespace - ? queueDescription.MaxSizeInGigabytes() - : queueDescription.MaxSizeInMegabytes == SeviceBusForWindowsServerMaxQueueSize - ? 11 : queueDescription.MaxSizeInGigabytes(); + trackBarMaxQueueSize.Value = (int)(serviceBusHelper.IsCloudNamespace + ? queueProperties.MaxSizeInMegabytes + : queueProperties.MaxSizeInMegabytes == SeviceBusForWindowsServerMaxQueueSize + ? 11 : queueProperties.MaxSizeInMegabytes); // Update maximum and value if Maximum size is more than 5 Gigs (either premium or partitioned) - if (queueDescription.MaxSizeInGigabytes() > 5) + if (queueProperties.MaxSizeInMegabytes > 5) { - trackBarMaxQueueSize.Maximum = queueDescription.MaxSizeInGigabytes(); - trackBarMaxQueueSize.Value = queueDescription.MaxSizeInGigabytes(); + trackBarMaxQueueSize.Maximum = (int)queueProperties.MaxSizeInMegabytes; + trackBarMaxQueueSize.Value = (int)queueProperties.MaxSizeInMegabytes; } // MaxDeliveryCount - txtMaxDeliveryCount.Text = queueDescription.MaxDeliveryCount.ToString(CultureInfo.InvariantCulture); + txtMaxDeliveryCount.Text = queueProperties.MaxDeliveryCount.ToString(CultureInfo.InvariantCulture); // DefaultMessageTimeToLive - tsDefaultMessageTimeToLive.TimeSpanValue = queueDescription.DefaultMessageTimeToLive; + tsDefaultMessageTimeToLive.TimeSpanValue = queueProperties.DefaultMessageTimeToLive; // DuplicateDetectionHistoryTimeWindow - tsDuplicateDetectionHistoryTimeWindow.TimeSpanValue = queueDescription.DuplicateDetectionHistoryTimeWindow; + tsDuplicateDetectionHistoryTimeWindow.TimeSpanValue = queueProperties.DuplicateDetectionHistoryTimeWindow; // LockDuration - tsLockDuration.TimeSpanValue = queueDescription.LockDuration; + tsLockDuration.TimeSpanValue = queueProperties.LockDuration; // AutoDeleteOnIdle - tsAutoDeleteOnIdle.TimeSpanValue = queueDescription.AutoDeleteOnIdle; + tsAutoDeleteOnIdle.TimeSpanValue = queueProperties.AutoDeleteOnIdle; // EnableBatchedOperations checkedListBox.SetItemChecked(EnableBatchedOperationsItemText, - queueDescription.EnableBatchedOperations); + queueProperties.EnableBatchedOperations); // EnableDeadLetteringOnMessageExpiration checkedListBox.SetItemChecked(EnableDeadLetteringOnMessageExpirationItemText, - queueDescription.EnableDeadLetteringOnMessageExpiration); + queueProperties.DeadLetteringOnMessageExpiration); if (serviceBusHelper.IsCloudNamespace && !this.premiumNamespace) { // EnablePartitioning - checkedListBox.SetItemChecked(EnablePartitioningItemText, queueDescription.EnablePartitioning); + checkedListBox.SetItemChecked(EnablePartitioningItemText, queueProperties.EnablePartitioning); // EnableExpress - checkedListBox.SetItemChecked(EnableExpressItemText, queueDescription.EnableExpress); + checkedListBox.SetItemChecked(EnableExpressItemText, /*queueProperties.EnableExpress*/true); } // RequiresDuplicateDetection checkedListBox.SetItemChecked(RequiresDuplicateDetectionItemText, - queueDescription.RequiresDuplicateDetection); + queueProperties.RequiresDuplicateDetection); // RequiresSession checkedListBox.SetItemChecked(RequiresSessionItemText, - queueDescription.RequiresSession); + queueProperties.RequiresSession); // SupportOrdering checkedListBox.SetItemChecked(SupportOrderingItemText, - queueDescription.SupportOrdering); + /*queueProperties.SupportOrdering*/true); // IsAnonymousAccessible if (!serviceBusHelper.IsCloudNamespace) { checkedListBox.SetItemChecked(IsAnonymousAccessibleItemText, - queueDescription.IsAnonymousAccessible); + /*queueProperties.IsAnonymousAccessible*/true); } } - private MessageReceiver BuildMessageReceiver(ReceiveMode receiveMode, string? fromSession = null) + private ServiceBusReceiver BuildMessageReceiver(ServiceBusReceiveMode serviceBusReceiveMode, string? fromSession = null) { - if (fromSession == null && !queueDescription.RequiresSession) + var receiverOptions = new ServiceBusReceiverOptions() + { + ReceiveMode = serviceBusReceiveMode + }; + if (fromSession == null && !queueProperties.RequiresSession) { - return serviceBusHelper.MessagingFactory.CreateMessageReceiver(queueDescription.Path, receiveMode); + return serviceBusHelper2.serviceBusClient.CreateReceiver(queueProperties.Name, receiverOptions); } - var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queueDescription.Path, receiveMode); + var queueClient = serviceBusHelper2.serviceBusClient.CreateReceiver(queueProperties.Name, receiverOptions); var sessionAcceptTimeout = TimeSpan.FromSeconds(MainForm.SingletonMainForm.ReceiveTimeout); if (fromSession != null) { - return queueClient.AcceptMessageSession(fromSession, sessionAcceptTimeout); + return serviceBusHelper2.serviceBusClient.AcceptSessionAsync(queueProperties.Name, fromSession/*, sessionAcceptTimeout*/).Result; } - return queueClient.AcceptMessageSession(sessionAcceptTimeout); + // todo session accept timeout + return serviceBusHelper2.serviceBusClient.AcceptNextSessionAsync(queueProperties.Name).Result; } - private void GetMessages(bool peek, bool all, int count, IBrokeredMessageInspector? messageInspector, long? fromSequenceNumber = null, string? fromSession = null) + private async Task GetMessages(bool peek, bool all, int count, IBrokeredMessageInspector? messageInspector, long? fromSequenceNumber = null, string? fromSession = null) { try { @@ -1317,45 +1332,45 @@ private void GetMessages(bool peek, bool all, int count, IBrokeredMessageInspect tabPageMessages.SuspendLayout(); Cursor.Current = Cursors.WaitCursor; - var brokeredMessages = new List(); + var ServiceBusMessages = new List(); if (peek) { var totalRetrieved = 0; - var receiver = BuildMessageReceiver(ReceiveMode.PeekLock, fromSession); + var receiver = BuildMessageReceiver(ServiceBusReceiveMode.PeekLock, fromSession); while (totalRetrieved < count) { - IEnumerable messageEnumerable; + IReadOnlyList messageEnumerable; if (totalRetrieved == 0 && fromSequenceNumber.HasValue) { - messageEnumerable = receiver.PeekBatch(fromSequenceNumber.Value, count); + messageEnumerable = await receiver.PeekMessagesAsync(count, fromSequenceNumber.Value); } else { - messageEnumerable = receiver.PeekBatch(count); + messageEnumerable = await receiver.PeekMessagesAsync(count); } if (messageEnumerable == null) { break; } - var messageArray = messageEnumerable as BrokeredMessage[] ?? messageEnumerable.ToArray(); + var messageArray = messageEnumerable as ServiceBusReceivedMessage[] ?? messageEnumerable.ToArray(); var partialList = messageInspector != null ? messageArray.Select(b => messageInspector.AfterReceiveMessage(b)).ToList() - : new List(messageArray); - brokeredMessages.AddRange(partialList); + : new List(messageArray); + ServiceBusMessages.AddRange(partialList); totalRetrieved += partialList.Count; if (partialList.Count == 0) { break; } } - writeToLog(string.Format(MessagesPeekedFromTheQueue, brokeredMessages.Count, queueDescription.Path)); + writeToLog(string.Format(MessagesPeekedFromTheQueue, ServiceBusMessages.Count, queueProperties.Name)); } else { - var messageReceiver = BuildMessageReceiver(ReceiveMode.ReceiveAndDelete, fromSession); + var messageReceiver = BuildMessageReceiver(ServiceBusReceiveMode.ReceiveAndDelete, fromSession); var totalRetrieved = 0; int retrieved; @@ -1365,20 +1380,20 @@ private void GetMessages(bool peek, bool all, int count, IBrokeredMessageInspect ? MainForm.SingletonMainForm.TopCount : count - totalRetrieved, TimeSpan.FromSeconds(MainForm.SingletonMainForm.ReceiveTimeout)); - var enumerable = messages as BrokeredMessage[] ?? messages.ToArray(); + var enumerable = messages as ServiceBusMessage[] ?? messages.ToArray(); retrieved = enumerable.Length; if (retrieved == 0) { continue; } totalRetrieved += retrieved; - brokeredMessages.AddRange(messageInspector != null + ServiceBusMessages.AddRange(messageInspector != null ? enumerable.Select(b => messageInspector.AfterReceiveMessage(b)) : enumerable); } while (retrieved > 0 && (all || count > totalRetrieved)); - writeToLog(string.Format(MessagesReceivedFromTheQueue, brokeredMessages.Count, queueDescription.Path)); + writeToLog(string.Format(MessagesReceivedFromTheQueue, ServiceBusMessages.Count, queueProperties.Name)); } - messageBindingList = new SortableBindingList(brokeredMessages) + messageBindingList = new SortableBindingList(ServiceBusMessages) { AllowEdit = false, AllowNew = false, @@ -1411,7 +1426,7 @@ private void GetMessages(bool peek, bool all, int count, IBrokeredMessageInspect { writeToLog(string.Format(NoMessageReceivedFromTheQueue, MainForm.SingletonMainForm.ReceiveTimeout, - queueDescription.Path)); + queueProperties.Name)); } catch (NotSupportedException) { @@ -1435,14 +1450,14 @@ private void ReadMessagesOneAtTheTime(bool peek, bool all, int count, IBrokeredM { try { - var brokeredMessages = new List(); + var ServiceBusMessages = new List(); if (peek) { - var messageReceiver = BuildMessageReceiver(ReceiveMode.PeekLock, fromSession); + var messageReceiver = BuildMessageReceiver(ServiceBusReceiveMode.PeekLock, fromSession); for (var i = 0; i < count; i++) { - BrokeredMessage message; + ServiceBusMessage message; if (i == 0 && fromSequenceNumber.HasValue) { @@ -1459,14 +1474,14 @@ private void ReadMessagesOneAtTheTime(bool peek, bool all, int count, IBrokeredM { message = messageInspector.AfterReceiveMessage(message); } - brokeredMessages.Add(message); + ServiceBusMessages.Add(message); } } - writeToLog(string.Format(MessagesPeekedFromTheQueue, brokeredMessages.Count, queueDescription.Path)); + writeToLog(string.Format(MessagesPeekedFromTheQueue, ServiceBusMessages.Count, queueProperties.Name)); } else { - var messageReceiver = BuildMessageReceiver(ReceiveMode.ReceiveAndDelete, fromSession); + var messageReceiver = BuildMessageReceiver(ServiceBusReceiveMode.ReceiveAndDelete, fromSession); var totalRetrieved = 0; int retrieved; @@ -1482,14 +1497,14 @@ private void ReadMessagesOneAtTheTime(bool peek, bool all, int count, IBrokeredM totalRetrieved += retrieved; if (message != null) { - brokeredMessages.Add(messageInspector != null + ServiceBusMessages.Add(messageInspector != null ? messageInspector.AfterReceiveMessage(message) : message); } } while (retrieved > 0 && (all || count > totalRetrieved)); - writeToLog(string.Format(MessagesReceivedFromTheQueue, brokeredMessages.Count, queueDescription.Path)); + writeToLog(string.Format(MessagesReceivedFromTheQueue, ServiceBusMessages.Count, queueProperties.Name)); } - messageBindingList = new SortableBindingList(brokeredMessages) + messageBindingList = new SortableBindingList(ServiceBusMessages) { AllowEdit = false, AllowNew = false, @@ -1520,7 +1535,7 @@ private void ReadMessagesOneAtTheTime(bool peek, bool all, int count, IBrokeredM { writeToLog(string.Format(NoMessageReceivedFromTheQueue, MainForm.SingletonMainForm.ReceiveTimeout, - queueDescription.Path)); + queueProperties.Name)); } catch (Exception e) { @@ -1538,17 +1553,17 @@ private void GetDeadletterMessages(bool peek, bool all, int count, IBrokeredMess tabPageDeadletter.SuspendLayout(); Cursor.Current = Cursors.WaitCursor; - var brokeredMessages = new List(); + var ServiceBusMessages = new List(); - var queuePath = QueueClient.FormatDeadLetterPath(queueDescription.Path); + var queuePath = QueueClient.FormatDeadLetterPath(queueProperties.Name); if (peek) { - var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queuePath, ReceiveMode.PeekLock); + var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queuePath, ServiceBusReceiveMode.PeekLock); var totalRetrieved = 0; var retrieved = 0; do { - IEnumerable messages; + IEnumerable messages; if (retrieved == 0 && fromSequenceNumber.HasValue) { @@ -1563,22 +1578,22 @@ private void GetDeadletterMessages(bool peek, bool all, int count, IBrokeredMess : count - totalRetrieved); } - var enumerable = messages as BrokeredMessage[] ?? messages.ToArray(); + var enumerable = messages as ServiceBusMessage[] ?? messages.ToArray(); retrieved = enumerable.Length; if (retrieved == 0) { continue; } totalRetrieved += retrieved; - brokeredMessages.AddRange(messageInspector != null + ServiceBusMessages.AddRange(messageInspector != null ? enumerable.Select(b => messageInspector.AfterReceiveMessage(b)) : enumerable); } while (retrieved > 0 && (all || count > totalRetrieved)); - writeToLog(string.Format(MessagesPeekedFromTheDeadletterQueue, brokeredMessages.Count, queueDescription.Path)); + writeToLog(string.Format(MessagesPeekedFromTheDeadletterQueue, ServiceBusMessages.Count, queueProperties.Name)); } else { - var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queuePath, ReceiveMode.ReceiveAndDelete); + var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queuePath, ServiceBusReceiveMode.ReceiveAndDelete); var totalRetrieved = 0; int retrieved; do @@ -1587,34 +1602,34 @@ private void GetDeadletterMessages(bool peek, bool all, int count, IBrokeredMess ? MainForm.SingletonMainForm.TopCount : count - totalRetrieved, TimeSpan.FromSeconds(MainForm.SingletonMainForm.ReceiveTimeout)); - var enumerable = messages as BrokeredMessage[] ?? messages.ToArray(); + var enumerable = messages as ServiceBusMessage[] ?? messages.ToArray(); retrieved = enumerable.Length; if (retrieved == 0) { continue; } totalRetrieved += retrieved; - brokeredMessages.AddRange(messageInspector != null + ServiceBusMessages.AddRange(messageInspector != null ? enumerable.Select(b => messageInspector.AfterReceiveMessage(b)) : enumerable); } while (retrieved > 0 && (all || count > totalRetrieved)); - //if (!queueDescription.EnablePartitioning) + //if (!queueProperties.EnablePartitioning) //{ - // queueClient.CompleteBatch(brokeredMessages.Select(bm => bm.LockToken)); + // queueClient.CompleteBatch(ServiceBusMessages.Select(bm => bm.LockToken)); //} //else //{ - // foreach (var partitionKey in brokeredMessages.Select(bm => bm.PartitionKey).Distinct()) + // foreach (var partitionKey in ServiceBusMessages.Select(bm => bm.PartitionKey).Distinct()) // { // var key = partitionKey; // queueClient.CompleteBatch( - // brokeredMessages.Where(bm => bm.PartitionKey == key).Select(bm => bm.LockToken)); + // ServiceBusMessages.Where(bm => bm.PartitionKey == key).Select(bm => bm.LockToken)); // } //} - writeToLog(string.Format(MessagesReceivedFromTheDeadletterQueue, brokeredMessages.Count, queueDescription.Path)); + writeToLog(string.Format(MessagesReceivedFromTheDeadletterQueue, ServiceBusMessages.Count, queueProperties.Name)); } - deadletterBindingList = new SortableBindingList(brokeredMessages) + deadletterBindingList = new SortableBindingList(ServiceBusMessages) { AllowEdit = false, AllowNew = false, @@ -1645,7 +1660,7 @@ private void GetDeadletterMessages(bool peek, bool all, int count, IBrokeredMess } catch (TimeoutException) { - writeToLog(string.Format(NoMessageReceivedFromTheDeadletterQueue, MainForm.SingletonMainForm.ReceiveTimeout, queueDescription.Path)); + writeToLog(string.Format(NoMessageReceivedFromTheDeadletterQueue, MainForm.SingletonMainForm.ReceiveTimeout, queueProperties.Name)); } catch (NotSupportedException) { @@ -1675,17 +1690,17 @@ private void GetTransferDeadletterMessages(bool peek, bool all, int count, IBrok tabPageTransferDeadletter.SuspendLayout(); Cursor.Current = Cursors.WaitCursor; - var brokeredMessages = new List(); + var ServiceBusMessages = new List(); - var queuePath = QueueClient.FormatTransferDeadLetterPath(queueDescription.Path); + var queuePath = QueueClient.FormatTransferDeadLetterPath(queueProperties.Name); if (peek) { - var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queuePath, ReceiveMode.PeekLock); + var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queuePath, ServiceBusReceiveMode.PeekLock); var totalRetrieved = 0; var retrieved = 0; do { - IEnumerable messages; + IEnumerable messages; if (retrieved == 0 && fromSequenceNumber.HasValue) { @@ -1700,22 +1715,22 @@ private void GetTransferDeadletterMessages(bool peek, bool all, int count, IBrok : count - totalRetrieved); } - var enumerable = messages as BrokeredMessage[] ?? messages.ToArray(); + var enumerable = messages as ServiceBusMessage[] ?? messages.ToArray(); retrieved = enumerable.Length; if (retrieved == 0) { continue; } totalRetrieved += retrieved; - brokeredMessages.AddRange(messageInspector != null + ServiceBusMessages.AddRange(messageInspector != null ? enumerable.Select(b => messageInspector.AfterReceiveMessage(b)) : enumerable); } while (retrieved > 0 && (all || count > totalRetrieved)); - writeToLog(string.Format(MessagesPeekedFromTheTransferDeadletterQueue, brokeredMessages.Count, queueDescription.Path)); + writeToLog(string.Format(MessagesPeekedFromTheTransferDeadletterQueue, ServiceBusMessages.Count, queueProperties.Name)); } else { - var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queuePath, ReceiveMode.ReceiveAndDelete); + var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queuePath, ServiceBusReceiveMode.ReceiveAndDelete); var totalRetrieved = 0; int retrieved; do @@ -1724,34 +1739,34 @@ private void GetTransferDeadletterMessages(bool peek, bool all, int count, IBrok ? MainForm.SingletonMainForm.TopCount : count - totalRetrieved, TimeSpan.FromSeconds(MainForm.SingletonMainForm.ReceiveTimeout)); - var enumerable = messages as BrokeredMessage[] ?? messages.ToArray(); + var enumerable = messages as ServiceBusMessage[] ?? messages.ToArray(); retrieved = enumerable.Length; if (retrieved == 0) { continue; } totalRetrieved += retrieved; - brokeredMessages.AddRange(messageInspector != null + ServiceBusMessages.AddRange(messageInspector != null ? enumerable.Select(b => messageInspector.AfterReceiveMessage(b)) : enumerable); } while (retrieved > 0 && (all || count > totalRetrieved)); - //if (!queueDescription.EnablePartitioning) + //if (!queueProperties.EnablePartitioning) //{ - // queueClient.CompleteBatch(brokeredMessages.Select(bm => bm.LockToken)); + // queueClient.CompleteBatch(ServiceBusMessages.Select(bm => bm.LockToken)); //} //else //{ - // foreach (var partitionKey in brokeredMessages.Select(bm => bm.PartitionKey).Distinct()) + // foreach (var partitionKey in ServiceBusMessages.Select(bm => bm.PartitionKey).Distinct()) // { // var key = partitionKey; // queueClient.CompleteBatch( - // brokeredMessages.Where(bm => bm.PartitionKey == key).Select(bm => bm.LockToken)); + // ServiceBusMessages.Where(bm => bm.PartitionKey == key).Select(bm => bm.LockToken)); // } //} - writeToLog(string.Format(MessagesReceivedFromTheTransferDeadletterQueue, brokeredMessages.Count, queueDescription.Path)); + writeToLog(string.Format(MessagesReceivedFromTheTransferDeadletterQueue, ServiceBusMessages.Count, queueProperties.Name)); } - transferDeadletterBindingList = new SortableBindingList(brokeredMessages) + transferDeadletterBindingList = new SortableBindingList(ServiceBusMessages) { AllowEdit = false, AllowNew = false, @@ -1782,7 +1797,7 @@ private void GetTransferDeadletterMessages(bool peek, bool all, int count, IBrok } catch (TimeoutException) { - writeToLog(string.Format(NoMessageReceivedFromTheTransferDeadletterQueue, MainForm.SingletonMainForm.ReceiveTimeout, queueDescription.Path)); + writeToLog(string.Format(NoMessageReceivedFromTheTransferDeadletterQueue, MainForm.SingletonMainForm.ReceiveTimeout, queueProperties.Name)); } catch (NotSupportedException) { @@ -1806,15 +1821,15 @@ private void ReadDeadletterMessagesOneAtTheTime(bool peek, bool all, int count, { try { - var brokeredMessages = new List(); - var queuePath = QueueClient.FormatDeadLetterPath(queueDescription.Path); + var ServiceBusMessages = new List(); + var queuePath = QueueClient.FormatDeadLetterPath(queueProperties.Name); if (peek) { - var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queuePath, ReceiveMode.PeekLock); + var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queuePath, ServiceBusReceiveMode.PeekLock); for (var i = 0; i < count; i++) { - BrokeredMessage message; + ServiceBusMessage message; if (i == 0 && fromSequenceNumber.HasValue) { @@ -1833,13 +1848,13 @@ private void ReadDeadletterMessagesOneAtTheTime(bool peek, bool all, int count, { message = messageInspector.AfterReceiveMessage(message); } - brokeredMessages.Add(message); + ServiceBusMessages.Add(message); } - writeToLog(string.Format(MessagesPeekedFromTheDeadletterQueue, brokeredMessages.Count, queueDescription.Path)); + writeToLog(string.Format(MessagesPeekedFromTheDeadletterQueue, ServiceBusMessages.Count, queueProperties.Name)); } else { - var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queuePath, ReceiveMode.ReceiveAndDelete); + var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queuePath, ServiceBusReceiveMode.ReceiveAndDelete); var totalRetrieved = 0; int retrieved; do @@ -1853,14 +1868,14 @@ private void ReadDeadletterMessagesOneAtTheTime(bool peek, bool all, int count, totalRetrieved += retrieved; if (message != null) { - brokeredMessages.Add(messageInspector != null + ServiceBusMessages.Add(messageInspector != null ? messageInspector.AfterReceiveMessage(message) : message); } } while (retrieved > 0 && (all || count > totalRetrieved)); - writeToLog(string.Format(MessagesPeekedFromTheDeadletterQueue, brokeredMessages.Count, queueDescription.Path)); + writeToLog(string.Format(MessagesPeekedFromTheDeadletterQueue, ServiceBusMessages.Count, queueProperties.Name)); } - deadletterBindingList = new SortableBindingList(brokeredMessages) + deadletterBindingList = new SortableBindingList(ServiceBusMessages) { AllowEdit = false, AllowNew = false, @@ -1890,7 +1905,7 @@ private void ReadDeadletterMessagesOneAtTheTime(bool peek, bool all, int count, } catch (TimeoutException) { - writeToLog(string.Format(NoMessageReceivedFromTheDeadletterQueue, MainForm.SingletonMainForm.ReceiveTimeout, queueDescription.Path)); + writeToLog(string.Format(NoMessageReceivedFromTheDeadletterQueue, MainForm.SingletonMainForm.ReceiveTimeout, queueProperties.Name)); } catch (Exception e) { @@ -1902,15 +1917,15 @@ private void ReadTransferDeadletterMessagesOneAtTheTime(bool peek, bool all, int { try { - var brokeredMessages = new List(); - var queuePath = QueueClient.FormatTransferDeadLetterPath(queueDescription.Path); + var ServiceBusMessages = new List(); + var queuePath = QueueClient.FormatTransferDeadLetterPath(queueProperties.Name); if (peek) { - var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queuePath, ReceiveMode.PeekLock); + var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queuePath, ServiceBusReceiveMode.PeekLock); for (var i = 0; i < count; i++) { - BrokeredMessage message; + ServiceBusMessage message; if (i == 0 && fromSequenceNumber.HasValue) { @@ -1929,13 +1944,13 @@ private void ReadTransferDeadletterMessagesOneAtTheTime(bool peek, bool all, int { message = messageInspector.AfterReceiveMessage(message); } - brokeredMessages.Add(message); + ServiceBusMessages.Add(message); } - writeToLog(string.Format(MessagesPeekedFromTheTransferDeadletterQueue, brokeredMessages.Count, queueDescription.Path)); + writeToLog(string.Format(MessagesPeekedFromTheTransferDeadletterQueue, ServiceBusMessages.Count, queueProperties.Name)); } else { - var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queuePath, ReceiveMode.ReceiveAndDelete); + var queueClient = serviceBusHelper.MessagingFactory.CreateQueueClient(queuePath, ServiceBusReceiveMode.ReceiveAndDelete); var totalRetrieved = 0; int retrieved; do @@ -1949,14 +1964,14 @@ private void ReadTransferDeadletterMessagesOneAtTheTime(bool peek, bool all, int totalRetrieved += retrieved; if (message != null) { - brokeredMessages.Add(messageInspector != null + ServiceBusMessages.Add(messageInspector != null ? messageInspector.AfterReceiveMessage(message) : message); } } while (retrieved > 0 && (all || count > totalRetrieved)); - writeToLog(string.Format(MessagesPeekedFromTheTransferDeadletterQueue, brokeredMessages.Count, queueDescription.Path)); + writeToLog(string.Format(MessagesPeekedFromTheTransferDeadletterQueue, ServiceBusMessages.Count, queueProperties.Name)); } - transferDeadletterBindingList = new SortableBindingList(brokeredMessages) + transferDeadletterBindingList = new SortableBindingList(ServiceBusMessages) { AllowEdit = false, AllowNew = false, @@ -1984,7 +1999,7 @@ private void ReadTransferDeadletterMessagesOneAtTheTime(bool peek, bool all, int } catch (TimeoutException) { - writeToLog(string.Format(NoMessageReceivedFromTheTransferDeadletterQueue, MainForm.SingletonMainForm.ReceiveTimeout, queueDescription.Path)); + writeToLog(string.Format(NoMessageReceivedFromTheTransferDeadletterQueue, MainForm.SingletonMainForm.ReceiveTimeout, queueProperties.Name)); } catch (Exception e) { @@ -2002,7 +2017,7 @@ private async void btnCreateDelete_Click(object sender, EventArgs e) } if (btnCreateDelete.Text == DeleteText) { - using (var deleteForm = new DeleteForm(queueDescription.Path, QueueEntity.ToLower())) + using (var deleteForm = new DeleteForm(queueProperties.Name, QueueEntity.ToLower())) { var configuration = TwoFilesConfiguration.Create(TwoFilesConfiguration.GetCurrentConfigFileUse(), writeToLog); @@ -2012,12 +2027,12 @@ private async void btnCreateDelete_Click(object sender, EventArgs e) if (!disableAccidentalDeletionPrevention) { - deleteForm.ShowAccidentalDeletionPreventionCheck(configuration, $"Delete {queueDescription.Path} {QueueEntity.ToLower()}"); + deleteForm.ShowAccidentalDeletionPreventionCheck(configuration, $"Delete {queueProperties.Name} {QueueEntity.ToLower()}"); } if (deleteForm.ShowDialog() == DialogResult.OK) { - await serviceBusHelper.DeleteQueue(queueDescription); + await serviceBusHelper.DeleteQueue(queueProperties); } } } @@ -2046,7 +2061,7 @@ private async void btnCreateDelete_Click(object sender, EventArgs e) return; } - var description = new QueueDescription(txtPath.Text) + var description = new QueueProperties(txtPath.Text) { UserMetadata = txtUserMetadata.Text, ForwardTo = txtForwardTo.Text, @@ -2174,7 +2189,7 @@ private async void btnCreateDelete_Click(object sender, EventArgs e) { if (string.IsNullOrWhiteSpace(rule.SecondaryKey)) { - description.Authorization.Add(new SharedAccessAuthorizationRule(rule.KeyName, + description.AuthorizationRules.Add(new SharedAccessAuthorizationRule(rule.KeyName, rule.PrimaryKey ?? SharedAccessAuthorizationRule.GenerateRandomKey(), rightList)); } @@ -2197,7 +2212,7 @@ private async void btnCreateDelete_Click(object sender, EventArgs e) } - queueDescription = serviceBusHelper.CreateQueue(description); + queueProperties = serviceBusHelper.CreateQueue(description); InitializeControls(initialCall: false); } } @@ -2222,25 +2237,26 @@ private void HandleException(Exception? ex) private void checkedListBox_ItemCheck(object sender, ItemCheckEventArgs e) { - if (queueDescription == null) + if (queueProperties == null) { return; } if (e.Index == checkedListBox.Items.IndexOf(EnablePartitioningItemText)) { - e.NewValue = queueDescription.EnablePartitioning ? CheckState.Checked : CheckState.Unchecked; + e.NewValue = queueProperties.EnablePartitioning ? CheckState.Checked : CheckState.Unchecked; } if (e.Index == checkedListBox.Items.IndexOf(RequiresSessionItemText)) { - e.NewValue = queueDescription.RequiresSession ? CheckState.Checked : CheckState.Unchecked; + e.NewValue = queueProperties.RequiresSession ? CheckState.Checked : CheckState.Unchecked; } if (e.Index == checkedListBox.Items.IndexOf(RequiresDuplicateDetectionItemText)) { - e.NewValue = queueDescription.RequiresDuplicateDetection ? CheckState.Checked : CheckState.Unchecked; + e.NewValue = queueProperties.RequiresDuplicateDetection ? CheckState.Checked : CheckState.Unchecked; } if (e.Index == checkedListBox.Items.IndexOf(IsAnonymousAccessibleItemText)) { - e.NewValue = queueDescription.IsAnonymousAccessible ? CheckState.Checked : CheckState.Unchecked; + // todo missing public get + e.NewValue = /*queueProperties.IsAnonymousAccessible*/false ? CheckState.Checked : CheckState.Unchecked; } } @@ -2270,9 +2286,9 @@ private void btnCancelUpdate_Click(object sender, EventArgs e) return; } - queueDescription.UserMetadata = txtUserMetadata.Text; - queueDescription.ForwardTo = string.IsNullOrWhiteSpace(txtForwardTo.Text) ? null : txtForwardTo.Text; - queueDescription.ForwardDeadLetteredMessagesTo = + queueProperties.UserMetadata = txtUserMetadata.Text; + queueProperties.ForwardTo = string.IsNullOrWhiteSpace(txtForwardTo.Text) ? null : txtForwardTo.Text; + queueProperties.ForwardDeadLetteredMessagesTo = string.IsNullOrWhiteSpace(txtForwardDeadLetteredMessagesTo.Text) ? null : txtForwardDeadLetteredMessagesTo.Text; @@ -2281,7 +2297,7 @@ private void btnCancelUpdate_Click(object sender, EventArgs e) { if (int.TryParse(txtMaxDeliveryCount.Text, out var value)) { - queueDescription.MaxDeliveryCount = value; + queueProperties.MaxDeliveryCount = value; } else { @@ -2294,7 +2310,7 @@ private void btnCancelUpdate_Click(object sender, EventArgs e) { if (tsDefaultMessageTimeToLive.TimeSpanValue.HasValue) { - queueDescription.DefaultMessageTimeToLive = tsDefaultMessageTimeToLive.TimeSpanValue.Value; + queueProperties.DefaultMessageTimeToLive = tsDefaultMessageTimeToLive.TimeSpanValue.Value; } else { @@ -2307,7 +2323,7 @@ private void btnCancelUpdate_Click(object sender, EventArgs e) { if (tsDuplicateDetectionHistoryTimeWindow.TimeSpanValue.HasValue) { - queueDescription.DuplicateDetectionHistoryTimeWindow = tsDuplicateDetectionHistoryTimeWindow.TimeSpanValue.Value; + queueProperties.DuplicateDetectionHistoryTimeWindow = tsDuplicateDetectionHistoryTimeWindow.TimeSpanValue.Value; } else { @@ -2320,7 +2336,7 @@ private void btnCancelUpdate_Click(object sender, EventArgs e) { if (tsAutoDeleteOnIdle.TimeSpanValue.HasValue) { - queueDescription.AutoDeleteOnIdle = tsAutoDeleteOnIdle.TimeSpanValue.Value; + queueProperties.AutoDeleteOnIdle = tsAutoDeleteOnIdle.TimeSpanValue.Value; } else { @@ -2333,7 +2349,7 @@ private void btnCancelUpdate_Click(object sender, EventArgs e) { if (tsLockDuration.TimeSpanValue.HasValue) { - queueDescription.LockDuration = tsLockDuration.TimeSpanValue.Value; + queueProperties.LockDuration = tsLockDuration.TimeSpanValue.Value; } else { @@ -2342,14 +2358,14 @@ private void btnCancelUpdate_Click(object sender, EventArgs e) } } - queueDescription.EnableBatchedOperations = + queueProperties.EnableBatchedOperations = checkedListBox.GetItemChecked(EnableBatchedOperationsItemText); - queueDescription.EnableExpress = checkedListBox.GetItemChecked(EnableExpressItemText, defaultValue: false); - queueDescription.EnableDeadLetteringOnMessageExpiration = + queueProperties.EnableExpress = checkedListBox.GetItemChecked(EnableExpressItemText, defaultValue: false); + queueProperties.EnableDeadLetteringOnMessageExpiration = checkedListBox.GetItemChecked(EnableDeadLetteringOnMessageExpirationItemText); - queueDescription.SupportOrdering = checkedListBox.GetItemChecked(SupportOrderingItemText); + queueProperties.SupportOrdering = checkedListBox.GetItemChecked(SupportOrderingItemText); - queueDescription.IsAnonymousAccessible = + queueProperties.IsAnonymousAccessible = checkedListBox.GetItemChecked(IsAnonymousAccessibleItemText, defaultValue: false); var bindingList = @@ -2390,18 +2406,18 @@ private void btnCancelUpdate_Click(object sender, EventArgs e) if (string.IsNullOrWhiteSpace(rule.PrimaryKey) && string.IsNullOrWhiteSpace(rule.SecondaryKey)) { - queueDescription.Authorization.Add(new SharedAccessAuthorizationRule(rule.KeyName, + queueProperties.AuthorizationRules.Add(new SharedAccessAuthorizationRule(rule.KeyName, rightList)); } else if (string.IsNullOrWhiteSpace(rule.SecondaryKey)) { - queueDescription.Authorization.Add(new SharedAccessAuthorizationRule(rule.KeyName, + queueProperties.AuthorizationRules.Add(new SharedAccessAuthorizationRule(rule.KeyName, rule.PrimaryKey ?? SharedAccessAuthorizationRule.GenerateRandomKey(), rightList)); } else { - queueDescription.Authorization.Add(new SharedAccessAuthorizationRule(rule.KeyName, + queueProperties.AuthorizationRules.Add(new SharedAccessAuthorizationRule(rule.KeyName, rule.PrimaryKey ?? SharedAccessAuthorizationRule.GenerateRandomKey(), rule.SecondaryKey ?? SharedAccessAuthorizationRule.GenerateRandomKey(), rightList)); @@ -2409,7 +2425,7 @@ private void btnCancelUpdate_Click(object sender, EventArgs e) } else { - queueDescription.Authorization.Add(new AllowRule(rule.IssuerName, + queueProperties.AuthorizationRules.Add(new AllowRule(rule.IssuerName, rule.ClaimType, rule.ClaimValue, rightList)); @@ -2417,18 +2433,18 @@ private void btnCancelUpdate_Click(object sender, EventArgs e) } } - queueDescription.Status = EntityStatus.Disabled; - serviceBusHelper.UpdateQueue(queueDescription); + queueProperties.Status = EntityStatus.Disabled; + serviceBusHelper.UpdateQueue(queueProperties); } catch (Exception ex) { HandleException(ex); - queueDescription = serviceBusHelper.GetQueue(queueDescription.Path); + queueProperties = serviceBusHelper.GetQueue(queueProperties.Name); } finally { - queueDescription.Status = EntityStatus.Active; - queueDescription = serviceBusHelper.NamespaceManager.UpdateQueue(queueDescription); + queueProperties.Status = EntityStatus.Active; + queueProperties = serviceBusHelper2.UpdateQueue(queueProperties); InitializeData(); } } @@ -2508,20 +2524,20 @@ private SelectEntityForm creteSelectEntityFormForPath(string path) { if (!string.IsNullOrWhiteSpace(path)) { - QueueDescription queueDescriptionSource = default!; + QueueProperties queuePropertiesSource = default!; try { - queueDescriptionSource = serviceBusHelper.GetQueue(path); + queuePropertiesSource = serviceBusHelper2.GetQueue(path); } catch (Exception) { // we might have found a topic, and the sdk will throw with an indistinguishable MessagingException error. } - if (queueDescriptionSource != null) + if (queuePropertiesSource != null) { - return new SelectEntityForm(SelectEntityDialogTitle, SelectEntityGrouperTitle, SelectEntityLabelText, queueDescriptionSource); + return new SelectEntityForm(SelectEntityDialogTitle, SelectEntityGrouperTitle, SelectEntityLabelText, queuePropertiesSource); } - TopicDescription topicDescriptionSource = default!; + TopicProperties topicDescriptionSource = default!; try { topicDescriptionSource = serviceBusHelper.GetTopic(path); @@ -2876,22 +2892,22 @@ private void messagesDataGridView_RowEnter(object sender, DataGridViewCellEventA { try { - var bindingList = messagesBindingSource.DataSource as BindingList; + var bindingList = messagesBindingSource.DataSource as BindingList; currentMessageRowIndex = e.RowIndex; if (bindingList == null) { return; } - if (brokeredMessage == bindingList[e.RowIndex]) + if (ServiceBusMessage == bindingList[e.RowIndex]) { return; } - brokeredMessage = bindingList[e.RowIndex]; + ServiceBusMessage = bindingList[e.RowIndex]; - LanguageDetector.SetFormattedMessage(serviceBusHelper, brokeredMessage, txtMessageText); + LanguageDetector.SetFormattedMessage(serviceBusHelper, ServiceBusMessage, txtMessageText); - messageCustomPropertyGrid.SelectedObject = new DictionaryPropertyGridAdapter(brokeredMessage.Properties); - messagePropertyGrid.SelectedObject = brokeredMessage; + messageCustomPropertyGrid.SelectedObject = new DictionaryPropertyGridAdapter(ServiceBusMessage.Properties); + messagePropertyGrid.SelectedObject = ServiceBusMessage; } // ReSharper disable once EmptyGeneralCatchClause catch (Exception) @@ -3009,7 +3025,7 @@ private void btnTransferDlq_Click(object sender, EventArgs e) private void deadletterDataGridView_RowEnter(object sender, DataGridViewCellEventArgs e) { - var bindingList = deadletterBindingSource.DataSource as BindingList; + var bindingList = deadletterBindingSource.DataSource as BindingList; currentDeadletterMessageRowIndex = e.RowIndex; if (bindingList == null) { @@ -3029,7 +3045,7 @@ private void deadletterDataGridView_RowEnter(object sender, DataGridViewCellEven private void transferDeadletterDataGridView_RowEnter(object sender, DataGridViewCellEventArgs e) { - var bindingList = transferDeadletterBindingSource.DataSource as BindingList; + var bindingList = transferDeadletterBindingSource.DataSource as BindingList; currentTransferDeadletterMessageRowIndex = e.RowIndex; if (bindingList == null) { @@ -3166,12 +3182,12 @@ private void messagesDataGridView_CellDoubleClick(object sender, DataGridViewCel { return; } - var bindingList = messagesBindingSource.DataSource as BindingList; + var bindingList = messagesBindingSource.DataSource as BindingList; if (bindingList == null) { return; } - using (var messageForm = new MessageForm(queueDescription, bindingList[e.RowIndex], serviceBusHelper, writeToLog)) + using (var messageForm = new MessageForm(queueProperties, bindingList[e.RowIndex], serviceBusHelper, writeToLog)) { messageForm.ShowDialog(); } @@ -3183,12 +3199,12 @@ private void deadletterDataGridView_CellDoubleClick(object sender, DataGridViewC { return; } - var bindingList = deadletterBindingSource.DataSource as BindingList; + var bindingList = deadletterBindingSource.DataSource as BindingList; if (bindingList == null) { return; } - using (var messageForm = new MessageForm(queueDescription, bindingList[e.RowIndex], serviceBusHelper, writeToLog)) + using (var messageForm = new MessageForm(queueProperties, bindingList[e.RowIndex], serviceBusHelper, writeToLog)) { messageForm.ShowDialog(); @@ -3213,12 +3229,12 @@ private void transferDeadletterDataGridView_CellDoubleClick(object sender, DataG { return; } - var bindingList = transferDeadletterBindingSource.DataSource as BindingList; + var bindingList = transferDeadletterBindingSource.DataSource as BindingList; if (bindingList == null) { return; } - using (var messageForm = new MessageForm(queueDescription, bindingList[e.RowIndex], serviceBusHelper, writeToLog)) + using (var messageForm = new MessageForm(queueProperties, bindingList[e.RowIndex], serviceBusHelper, writeToLog)) { messageForm.ShowDialog(); } @@ -3362,8 +3378,8 @@ private void ResubmitSelectedMessages() return; } - using (var form = new MessageForm(queueDescription, messagesDataGridView.SelectedRows.Cast() - .Select(r => (BrokeredMessage)r.DataBoundItem), serviceBusHelper, writeToLog)) + using (var form = new MessageForm(queueProperties, messagesDataGridView.SelectedRows.Cast() + .Select(r => (ServiceBusMessage)r.DataBoundItem), serviceBusHelper, writeToLog)) { form.ShowDialog(); } @@ -3387,19 +3403,19 @@ async void deleteSelectedMessagesToolStripMenuItem_Click(object sender, EventArg } var messages = deadletterDataGridView.SelectedRows.Cast() - .Select(r => r.DataBoundItem as BrokeredMessage); + .Select(r => r.DataBoundItem as ServiceBusMessage); string confirmationText; if (messages.Count() == 1) { confirmationText = "Are you sure you want to delete the selected message from the " + - $"dead-letter subqueue for the {queueDescription.Path} queue?"; + $"dead-letter subqueue for the {queueProperties.Name} queue?"; } else { confirmationText = $"Are you sure you want to delete {messages.Count()} messages from the " + - $"dead-letter subqueue for {queueDescription.Path} queue?"; + $"dead-letter subqueue for {queueProperties.Name} queue?"; } using (var deleteForm = new DeleteForm(confirmationText)) @@ -3412,7 +3428,7 @@ async void deleteSelectedMessagesToolStripMenuItem_Click(object sender, EventArg var sequenceNumbersToDelete = messages.Select(s => s?.SequenceNumber).ToList(); var deadLetterMessageHandler = new DeadLetterMessageHandler(writeToLog, serviceBusHelper, - MainForm.SingletonMainForm.ReceiveTimeout, queueDescription); + MainForm.SingletonMainForm.ReceiveTimeout, queueProperties); try { @@ -3512,8 +3528,8 @@ async Task ResubmitSelectedDeadletterMessages() return; } - using (var form = new MessageForm(queueDescription, deadletterDataGridView.SelectedRows.Cast() - .Select(r => (BrokeredMessage)r.DataBoundItem), serviceBusHelper, writeToLog)) + using (var form = new MessageForm(queueProperties, deadletterDataGridView.SelectedRows.Cast() + .Select(r => (ServiceBusMessage)r.DataBoundItem), serviceBusHelper, writeToLog)) { form.ShowDialog(); if (form.RemovedSequenceNumbers != null && form.RemovedSequenceNumbers.Any()) @@ -3548,8 +3564,8 @@ private void resubmitSelectedTransferDeadletterMessagesInBatchModeToolStripMenuI { return; } - using (var form = new MessageForm(queueDescription, transferDeadletterDataGridView.SelectedRows.Cast() - .Select(r => (BrokeredMessage)r.DataBoundItem), serviceBusHelper, writeToLog)) + using (var form = new MessageForm(queueProperties, transferDeadletterDataGridView.SelectedRows.Cast() + .Select(r => (ServiceBusMessage)r.DataBoundItem), serviceBusHelper, writeToLog)) { form.ShowDialog(); } @@ -3624,7 +3640,7 @@ private void pictFindMessagesByDate_Click(object sender, EventArgs e) } } - private static bool IsWithinDateTimeRange(BrokeredMessage message, DateTime? fromDateTime, DateTime? toDateTime) + private static bool IsWithinDateTimeRange(ServiceBusMessage message, DateTime? fromDateTime, DateTime? toDateTime) { if (message.EnqueuedTimeUtc < (fromDateTime ?? DateTime.MinValue)) { @@ -3639,7 +3655,7 @@ private static bool IsWithinDateTimeRange(BrokeredMessage message, DateTime? fro private void FilterMessages() { - var bindingList = new SortableBindingList(); + var bindingList = new SortableBindingList(); try { if (messagesFilterFromDate == null && messagesFilterToDate == null && string.IsNullOrWhiteSpace(messagesFilterExpression)) @@ -3676,7 +3692,7 @@ private void FilterMessages() filteredList = filteredList.Where(msg => IsWithinDateTimeRange(msg, messagesFilterFromDate, messagesFilterToDate)).ToList(); } - bindingList = new SortableBindingList(filteredList) + bindingList = new SortableBindingList(filteredList) { AllowEdit = false, AllowNew = false, @@ -3699,7 +3715,7 @@ private void FilterMessages() { if (messagesDataGridView.Rows.Count > 0) { - brokeredMessage = default!; + ServiceBusMessage = default!; messagesDataGridView_RowEnter(this, new DataGridViewCellEventArgs(0, 0)); } } @@ -3708,7 +3724,7 @@ private void FilterMessages() private void FilterDeadletters() { - var bindingList = new SortableBindingList(); + var bindingList = new SortableBindingList(); try { if (deadletterFilterFromDate == null && deadletterFilterToDate == null && string.IsNullOrWhiteSpace(deadletterFilterExpression)) @@ -3745,7 +3761,7 @@ private void FilterDeadletters() filteredList = filteredList.Where(msg => IsWithinDateTimeRange(msg, deadletterFilterFromDate, deadletterFilterToDate)).ToList(); } - bindingList = new SortableBindingList(filteredList) + bindingList = new SortableBindingList(filteredList) { AllowEdit = false, AllowNew = false, @@ -3950,7 +3966,7 @@ private void saveSelectedMessageToolStripMenuItem_Click(object sender, EventArgs { return; } - var bindingList = messagesBindingSource.DataSource as BindingList; + var bindingList = messagesBindingSource.DataSource as BindingList; if (bindingList == null) { return; @@ -3993,7 +4009,7 @@ void saveSelectedMessageBodyAsFileToolStripMenuItem_Click(object sender, EventAr return; } - var bindingList = messagesBindingSource.DataSource as BindingList; + var bindingList = messagesBindingSource.DataSource as BindingList; if (bindingList == null) { return; @@ -4042,9 +4058,9 @@ private void saveSelectedMessagesToolStripMenuItem_Click(object sender, EventArg } var messages = messagesDataGridView.SelectedRows.Cast() - .Select(r => r.DataBoundItem as BrokeredMessage); - IEnumerable brokeredMessages = messages as BrokeredMessage?[] ?? messages.ToArray(); - if (!brokeredMessages.Any()) + .Select(r => r.DataBoundItem as ServiceBusMessage); + IEnumerable ServiceBusMessages = messages as ServiceBusMessage?[] ?? messages.ToArray(); + if (!ServiceBusMessages.Any()) { return; } @@ -4064,9 +4080,9 @@ private void saveSelectedMessagesToolStripMenuItem_Click(object sender, EventArg } using (var writer = new StreamWriter(saveFileDialog.FileName)) { - var bodies = brokeredMessages.Select(bm => serviceBusHelper.GetMessageText(bm, + var bodies = ServiceBusMessages.Select(bm => serviceBusHelper.GetMessageText(bm, MainForm.SingletonMainForm.UseAscii, out _)); - writer.Write(MessageSerializationHelper.Serialize(brokeredMessages, bodies, doNotSerializeBody: true)); + writer.Write(MessageSerializationHelper.Serialize(ServiceBusMessages, bodies, doNotSerializeBody: true)); } } catch (Exception ex) @@ -4086,9 +4102,9 @@ void saveSelectedMessagesBodyAsFileToolStripMenuItem_Click(object sender, EventA var messages = messagesDataGridView.SelectedRows.Cast() - .Select(r => r.DataBoundItem as BrokeredMessage); - IEnumerable brokeredMessages = messages as BrokeredMessage[] ?? messages.ToArray(); - if (!brokeredMessages.Any()) + .Select(r => r.DataBoundItem as ServiceBusMessage); + IEnumerable ServiceBusMessages = messages as ServiceBusMessage[] ?? messages.ToArray(); + if (!ServiceBusMessages.Any()) { return; } @@ -4104,7 +4120,7 @@ void saveSelectedMessagesBodyAsFileToolStripMenuItem_Click(object sender, EventA return; } - var bodies = brokeredMessages.Select(bm => serviceBusHelper.GetMessageText(bm, + var bodies = ServiceBusMessages.Select(bm => serviceBusHelper.GetMessageText(bm, MainForm.SingletonMainForm.UseAscii, out _)); var count = 0; foreach (var body in bodies) @@ -4140,7 +4156,7 @@ private void saveSelectedDeadletteredMessageToolStripMenuItem_Click(object sende { return; } - var bindingList = deadletterBindingSource.DataSource as BindingList; + var bindingList = deadletterBindingSource.DataSource as BindingList; if (bindingList == null) { return; @@ -4183,7 +4199,7 @@ void saveSelectedDeadletteredMessageBodyAsFileToolStripMenuItem_Click(object sen return; } - var bindingList = deadletterBindingSource.DataSource as BindingList; + var bindingList = deadletterBindingSource.DataSource as BindingList; if (bindingList == null) { return; @@ -4230,9 +4246,9 @@ private void saveSelectedDeadletteredMessagesToolStripMenuItem_Click(object send return; } var messages = deadletterDataGridView.SelectedRows.Cast() - .Select(r => r.DataBoundItem as BrokeredMessage); - IEnumerable brokeredMessages = messages as BrokeredMessage[] ?? messages.ToArray(); - if (!brokeredMessages.Any()) + .Select(r => r.DataBoundItem as ServiceBusMessage); + IEnumerable ServiceBusMessages = messages as ServiceBusMessage[] ?? messages.ToArray(); + if (!ServiceBusMessages.Any()) { return; } @@ -4252,9 +4268,9 @@ private void saveSelectedDeadletteredMessagesToolStripMenuItem_Click(object send } using (var writer = new StreamWriter(saveFileDialog.FileName)) { - var bodies = brokeredMessages.Select(bm => serviceBusHelper.GetMessageText(bm, + var bodies = ServiceBusMessages.Select(bm => serviceBusHelper.GetMessageText(bm, MainForm.SingletonMainForm.UseAscii, out _)); - writer.Write(MessageSerializationHelper.Serialize(brokeredMessages, bodies, doNotSerializeBody: true)); + writer.Write(MessageSerializationHelper.Serialize(ServiceBusMessages, bodies, doNotSerializeBody: true)); } } catch (Exception ex) @@ -4273,9 +4289,9 @@ void saveSelectedDeadletteredMessagesBodyAsFileToolStripMenuItem_Click(object se } var messages = deadletterDataGridView.SelectedRows.Cast() - .Select(r => r.DataBoundItem as BrokeredMessage); - IEnumerable brokeredMessages = messages as BrokeredMessage[] ?? messages.ToArray(); - if (!brokeredMessages.Any()) + .Select(r => r.DataBoundItem as ServiceBusMessage); + IEnumerable ServiceBusMessages = messages as ServiceBusMessage[] ?? messages.ToArray(); + if (!ServiceBusMessages.Any()) { return; } @@ -4291,7 +4307,7 @@ void saveSelectedDeadletteredMessagesBodyAsFileToolStripMenuItem_Click(object se return; } - var bodies = brokeredMessages.Select(bm => serviceBusHelper.GetMessageText(bm, + var bodies = ServiceBusMessages.Select(bm => serviceBusHelper.GetMessageText(bm, MainForm.SingletonMainForm.UseAscii, out _)); var count = 0; foreach (var body in bodies) @@ -4327,7 +4343,7 @@ private void saveSelectedTransferDeadletteredMessageToolStripMenuItem_Click(obje { return; } - var bindingList = transferDeadletterBindingSource.DataSource as BindingList; + var bindingList = transferDeadletterBindingSource.DataSource as BindingList; if (bindingList == null) { return; @@ -4371,7 +4387,7 @@ void saveSelectedTransferDeadletteredMessageBodyAsFileToolStripMenuItem_Click(ob return; } - var bindingList = transferDeadletterBindingSource.DataSource as BindingList; + var bindingList = transferDeadletterBindingSource.DataSource as BindingList; if (bindingList == null) { return; @@ -4418,9 +4434,9 @@ private void saveSelectedTransferDeadletteredMessagesToolStripMenuItem_Click(obj return; } var messages = transferDeadletterDataGridView.SelectedRows.Cast() - .Select(r => r.DataBoundItem as BrokeredMessage); - IEnumerable brokeredMessages = messages as BrokeredMessage[] ?? messages.ToArray(); - if (!brokeredMessages.Any()) + .Select(r => r.DataBoundItem as ServiceBusMessage); + IEnumerable ServiceBusMessages = messages as ServiceBusMessage[] ?? messages.ToArray(); + if (!ServiceBusMessages.Any()) { return; } @@ -4440,9 +4456,9 @@ private void saveSelectedTransferDeadletteredMessagesToolStripMenuItem_Click(obj } using (var writer = new StreamWriter(saveFileDialog.FileName)) { - var bodies = brokeredMessages.Select(bm => serviceBusHelper.GetMessageText(bm, + var bodies = ServiceBusMessages.Select(bm => serviceBusHelper.GetMessageText(bm, MainForm.SingletonMainForm.UseAscii, out _)); - writer.Write(MessageSerializationHelper.Serialize(brokeredMessages, bodies, doNotSerializeBody: true)); + writer.Write(MessageSerializationHelper.Serialize(ServiceBusMessages, bodies, doNotSerializeBody: true)); } } catch (Exception ex) @@ -4461,9 +4477,9 @@ void saveSelectedTransferDeadletteredMessagesBodyAsFileToolStripMenuItem_Click(o } var messages = transferDeadletterDataGridView.SelectedRows.Cast() - .Select(r => r.DataBoundItem as BrokeredMessage); - IEnumerable brokeredMessages = messages as BrokeredMessage[] ?? messages.ToArray(); - if (!brokeredMessages.Any()) + .Select(r => r.DataBoundItem as ServiceBusMessage); + IEnumerable ServiceBusMessages = messages as ServiceBusMessage[] ?? messages.ToArray(); + if (!ServiceBusMessages.Any()) { return; } @@ -4479,7 +4495,7 @@ void saveSelectedTransferDeadletteredMessagesBodyAsFileToolStripMenuItem_Click(o return; } - var bodies = brokeredMessages.Select(bm => serviceBusHelper.GetMessageText(bm, + var bodies = ServiceBusMessages.Select(bm => serviceBusHelper.GetMessageText(bm, MainForm.SingletonMainForm.UseAscii, out _)); var count = 0; foreach (var body in bodies) @@ -4539,7 +4555,7 @@ void RemoveDeadletterDataGridRows(IEnumerable sequenceNumbersToRemove) foreach (DataGridViewRow row in deadletterDataGridView.Rows) { - var message = (BrokeredMessage)row.DataBoundItem; + var message = (ServiceBusMessage)row.DataBoundItem; if (sequenceNumbersToRemove.Contains(message.SequenceNumber)) { diff --git a/src/ServiceBusExplorer/Forms/MainForm.cs b/src/ServiceBusExplorer/Forms/MainForm.cs index 2c2d3e83..c80935c1 100644 --- a/src/ServiceBusExplorer/Forms/MainForm.cs +++ b/src/ServiceBusExplorer/Forms/MainForm.cs @@ -20,6 +20,7 @@ #endregion #region Using Directives +using Azure.Messaging.ServiceBus.Administration; using Microsoft.Azure.NotificationHubs; using Microsoft.ServiceBus.Messaging; using ServiceBusExplorer.Controls; @@ -204,6 +205,7 @@ public partial class MainForm : Form #region Private Instance Fields private readonly ServiceBusHelper serviceBusHelper; + private readonly ServiceBusHelper2 serviceBusHelper2; private TreeNode rootNode; private TreeNode currentNode; private readonly FieldInfo eventClickFieldInfo; @@ -265,8 +267,11 @@ public MainForm(string logMessage) Trace.Listeners.Add(new LogTraceListener(MainForm.StaticWriteToLog)); mainSingletonMainForm = this; serviceBusHelper = new ServiceBusHelper(WriteToLog); + serviceBusHelper2 = serviceBusHelper.GetServiceBusHelper2(); serviceBusHelper.OnCreate += serviceBusHelper_OnCreate; serviceBusHelper.OnDelete += serviceBusHelper_OnDelete; + serviceBusHelper2.OnCreate += serviceBusHelper_OnCreate; + serviceBusHelper2.OnDelete += serviceBusHelper_OnDelete; serviceBusTreeView.TreeViewNodeSorter = new TreeViewHelper(); eventClickFieldInfo = typeof(ToolStripItem).GetField(EventClick, BindingFlags.NonPublic | BindingFlags.Static); eventsPropertyInfo = typeof(Component).GetProperty(EventsProperty, BindingFlags.NonPublic | BindingFlags.Instance); @@ -313,9 +318,9 @@ private void UpdateSavedConnectionsMenu() Keys.Control | Keys.D5 }; - foreach (var namespaceKey in serviceBusHelper.ServiceBusNamespaces.Keys.OrderBy(k => k)) + foreach (var namespaceKey in serviceBusHelper2.ServiceBusNamespaces.Keys.OrderBy(k => k)) { - if (serviceBusHelper.ServiceBusNamespaces[namespaceKey].UserCreated) + if (serviceBusHelper2.ServiceBusNamespaces[namespaceKey].UserCreated) { var shortcutKey = allowedShortCutKeys.Count > 0 ? allowedShortCutKeys.First() : Keys.None; if (allowedShortCutKeys.Count > 0) allowedShortCutKeys.RemoveAt(0); @@ -340,6 +345,8 @@ private void UpdateSavedConnectionsMenu() private async void SavedConnectionToolStripMenuItem_Click(object sender, EventArgs e) { + var serviceBusNamespace2 = serviceBusHelper2.ServiceBusNamespaces[(sender as ToolStripMenuItem).Tag.ToString()]; + serviceBusHelper2.Connect(serviceBusNamespace2); var serviceBusNamespace = serviceBusHelper.ServiceBusNamespaces[(sender as ToolStripMenuItem).Tag.ToString()]; serviceBusHelper.Connect(serviceBusNamespace); SetTitle(serviceBusNamespace.Namespace); @@ -1097,15 +1104,15 @@ void serviceBusHelper_OnCreate(ServiceBusHelperEventArgs args) { subscriptionsNode = topicNode.Nodes.Add(SubscriptionEntities, SubscriptionEntities, - wrapper.SubscriptionDescription.Status == EntityStatus.Active ? SubscriptionListIconIndex : GreySubscriptionIconIndex, - wrapper.SubscriptionDescription.Status == EntityStatus.Active ? SubscriptionListIconIndex : GreySubscriptionIconIndex); + wrapper.SubscriptionDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? SubscriptionListIconIndex : GreySubscriptionIconIndex, + wrapper.SubscriptionDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? SubscriptionListIconIndex : GreySubscriptionIconIndex); subscriptionsNode.ContextMenuStrip = subscriptionsContextMenuStrip; subscriptionsNode.Tag = new SubscriptionWrapper(null, wrapper.TopicDescription, FilterExpressionHelper.SubscriptionFilterExpression); } var subscriptionNode = subscriptionsNode.Nodes.Add(wrapper.SubscriptionDescription.Name, GetNameAndMessageCountText(wrapper.SubscriptionDescription.Name, wrapper.SubscriptionDescription.MessageCountDetails), - wrapper.SubscriptionDescription.Status == EntityStatus.Active ? SubscriptionIconIndex : GreySubscriptionIconIndex, - wrapper.SubscriptionDescription.Status == EntityStatus.Active ? SubscriptionIconIndex : GreySubscriptionIconIndex); + wrapper.SubscriptionDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? SubscriptionIconIndex : GreySubscriptionIconIndex, + wrapper.SubscriptionDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? SubscriptionIconIndex : GreySubscriptionIconIndex); subscriptionNode.ContextMenuStrip = subscriptionContextMenuStrip; subscriptionNode.Tag = new SubscriptionWrapper(wrapper.SubscriptionDescription, wrapper.TopicDescription); subscriptionsNode.Expand(); @@ -1384,10 +1391,13 @@ private async void connectToolStripMenuItem_Click(object sender, EventArgs e) SelectedEntities = connectForm.SelectedEntities; ServiceBusHelper.ConnectivityMode = connectForm.ConnectivityMode; ServiceBusHelper.UseAmqpWebSockets = connectForm.UseAmqpWebSockets; + var serviceBusNamespace2 = ServiceBusNamespace2.GetServiceBusNamespace(connectForm.Key ?? "Manual", + connectForm.ConnectionString, StaticWriteToLog); var serviceBusNamespace = ServiceBusNamespace.GetServiceBusNamespace(connectForm.Key ?? "Manual", connectForm.ConnectionString, StaticWriteToLog); + serviceBusHelper2.Connect(serviceBusNamespace2); serviceBusHelper.Connect(serviceBusNamespace); - SetTitle(serviceBusNamespace.Namespace); + SetTitle(serviceBusNamespace2.Namespace); foreach (var userControl in panelMain.Controls.OfType()) { @@ -1669,7 +1679,7 @@ private void renameEntity_Click(object sender, EventArgs e) { return; } - serviceBusHelper.RenameQueue(queueDescription.Path, parameterForm.ParameterValues[0]); + serviceBusHelper2.RenameQueue(queueDescription.Path, parameterForm.ParameterValues[0]); return; } } @@ -1758,8 +1768,8 @@ private void RefreshIndividualTopic(TreeNode selectedNode) { var subscriptionNode = subscriptionsNode.Nodes.Add(subscriptionDescription.Name, GetNameAndMessageCountText(subscriptionDescription.Name, subscriptionDescription.MessageCountDetails), - subscriptionDescription.Status == EntityStatus.Active ? SubscriptionIconIndex : GreySubscriptionIconIndex, - subscriptionDescription.Status == EntityStatus.Active ? SubscriptionIconIndex : GreySubscriptionIconIndex); + subscriptionDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? SubscriptionIconIndex : GreySubscriptionIconIndex, + subscriptionDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? SubscriptionIconIndex : GreySubscriptionIconIndex); subscriptionNode.ContextMenuStrip = subscriptionContextMenuStrip; subscriptionNode.Tag = new SubscriptionWrapper(subscriptionDescription, topicDescription); if (topicDescription != null) @@ -2150,7 +2160,7 @@ private async void deleteEntity_Click(object sender, EventArgs e) if (deleteForm.ShowDialog() == DialogResult.OK) { - await serviceBusHelper.DeleteQueue(queueDescription); + await serviceBusHelper2.DeleteQueue(queueDescription); } } return; @@ -2394,12 +2404,12 @@ private void changeStatusQueueMenuItem_DropDownOpening(object sender, EventArgs if (tag != null) { // Put a check against the item that reflects the current status of the queue - var queueDescription = serviceBusHelper.GetQueue(tag.Path); + var queueDescription = serviceBusHelper2.GetQueue(tag.Path); var status = queueDescription.Status; foreach (var dropDownItem in changeStatusQueueMenuItem.DropDownItems) { var dropDownMenuItem = dropDownItem as ToolStripMenuItem; - dropDownMenuItem.Checked = (EntityStatus)dropDownMenuItem.Tag == status; + dropDownMenuItem.Checked = (Microsoft.ServiceBus.Messaging.EntityStatus)dropDownMenuItem.Tag == status; } } else @@ -2423,13 +2433,13 @@ private async void changeStatusQueue_Click(object sender, ToolStripItemClickedEv { if (serviceBusTreeView.SelectedNode.Tag is QueueDescription queueDescription) { - var desiredStatus = (EntityStatus)e.ClickedItem.Tag; + var desiredStatus = (Microsoft.ServiceBus.Messaging.EntityStatus)e.ClickedItem.Tag; using (var changeStatusForm = new ChangeStatusForm(queueDescription.Path, QueueEntity.ToLower(), desiredStatus)) { if (changeStatusForm.ShowDialog() == DialogResult.OK) { - queueDescription.Status = (EntityStatus)e.ClickedItem.Tag; - serviceBusHelper.NamespaceManager.UpdateQueue(queueDescription); + queueDescription.Status = (Microsoft.ServiceBus.Messaging.EntityStatus)e.ClickedItem.Tag; + serviceBusHelper2.UpdateQueue(queueDescription); await RefreshSelectedEntity(); } } @@ -2475,9 +2485,9 @@ private async void changeStatusEntity_Click(object sender, EventArgs e) // Topic Node if (serviceBusTreeView.SelectedNode.Tag is TopicDescription topicDescription) { - var desiredStatus = topicDescription.Status == EntityStatus.Active - ? EntityStatus.Disabled - : EntityStatus.Active; + var desiredStatus = topicDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active + ? Microsoft.ServiceBus.Messaging.EntityStatus.Disabled + : Microsoft.ServiceBus.Messaging.EntityStatus.Active; using (var changeStatusForm = new ChangeStatusForm(topicDescription.Path, TopicEntity.ToLower(), desiredStatus)) { if (changeStatusForm.ShowDialog() == DialogResult.OK) @@ -2485,7 +2495,7 @@ private async void changeStatusEntity_Click(object sender, EventArgs e) topicDescription.Status = desiredStatus; await serviceBusHelper.NamespaceManager.UpdateTopicAsync(topicDescription); await RefreshSelectedEntity(); - changeStatusTopicMenuItem.Text = topicDescription.Status == EntityStatus.Active + changeStatusTopicMenuItem.Text = topicDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? DisableTopic : EnableTopic; var item = actionsToolStripMenuItem.DropDownItems[ChangeStatusTopicMenuItem]; @@ -2504,9 +2514,9 @@ private async void changeStatusEntity_Click(object sender, EventArgs e) if (subscriptionWrapper.TopicDescription != null && subscriptionWrapper.SubscriptionDescription != null) { - var desiredStatus = subscriptionWrapper.SubscriptionDescription.Status = subscriptionWrapper.SubscriptionDescription.Status == EntityStatus.Active - ? EntityStatus.Disabled - : EntityStatus.Active; + var desiredStatus = subscriptionWrapper.SubscriptionDescription.Status = subscriptionWrapper.SubscriptionDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active + ? Microsoft.ServiceBus.Messaging.EntityStatus.Disabled + : Microsoft.ServiceBus.Messaging.EntityStatus.Active; using (var changeStatusForm = new ChangeStatusForm(subscriptionWrapper.SubscriptionDescription.Name, SubscriptionEntity.ToLower(), desiredStatus)) { if (changeStatusForm.ShowDialog() == DialogResult.OK) @@ -2514,7 +2524,7 @@ private async void changeStatusEntity_Click(object sender, EventArgs e) subscriptionWrapper.SubscriptionDescription.Status = desiredStatus; await serviceBusHelper.NamespaceManager.UpdateSubscriptionAsync(subscriptionWrapper.SubscriptionDescription); await RefreshSelectedEntity(); - changeStatusSubscriptionMenuItem.Text = subscriptionWrapper.SubscriptionDescription.Status == EntityStatus.Active + changeStatusSubscriptionMenuItem.Text = subscriptionWrapper.SubscriptionDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? DisableSubscription : EnableSubscription; var item = actionsToolStripMenuItem.DropDownItems[ChangeStatusSubscriptionMenuItem]; @@ -2530,9 +2540,9 @@ private async void changeStatusEntity_Click(object sender, EventArgs e) // Event Hub if (serviceBusTreeView.SelectedNode.Tag is EventHubDescription eventHubDescription) { - var desiredStatus = eventHubDescription.Status = eventHubDescription.Status == EntityStatus.Active - ? EntityStatus.Disabled - : EntityStatus.Active; + var desiredStatus = eventHubDescription.Status = eventHubDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active + ? Microsoft.ServiceBus.Messaging.EntityStatus.Disabled + : Microsoft.ServiceBus.Messaging.EntityStatus.Active; using (var changeStatusForm = new ChangeStatusForm(eventHubDescription.Path, EventHubEntity.ToLower(), desiredStatus)) { if (changeStatusForm.ShowDialog() == DialogResult.OK) @@ -2540,7 +2550,7 @@ private async void changeStatusEntity_Click(object sender, EventArgs e) eventHubDescription.Status = desiredStatus; await serviceBusHelper.NamespaceManager.UpdateEventHubAsync(eventHubDescription); await RefreshSelectedEntity(); - changeStatusEventHubMenuItem.Text = eventHubDescription.Status == EntityStatus.Active + changeStatusEventHubMenuItem.Text = eventHubDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? DisableEventHub : EnableEventHub; var item = actionsToolStripMenuItem.DropDownItems[ChangeStatusEventHubMenuItem]; @@ -2824,7 +2834,7 @@ public async Task RefreshSelectedEntity() var tag = serviceBusTreeView.SelectedNode.Tag as QueueDescription; if (tag != null) { - var queueDescription = serviceBusHelper.GetQueue(tag.Path); + var queueDescription = serviceBusHelper2.GetQueue(tag.Path); RefreshQueueNode(serviceBusTreeView.SelectedNode, queueDescription); // Update the right view @@ -2951,7 +2961,7 @@ public async Task RefreshSelectedEntity() if (serviceBusTreeView.SelectedNode.Tag is EventHubDescription) { var eventHubDescription = serviceBusHelper.GetEventHub(((EventHubDescription)serviceBusTreeView.SelectedNode.Tag).Path); - if (eventHubDescription.Status == EntityStatus.Active) + if (eventHubDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active) { serviceBusTreeView.SelectedNode.ImageIndex = EventHubIconIndex; serviceBusTreeView.SelectedNode.SelectedImageIndex = EventHubIconIndex; @@ -3042,8 +3052,8 @@ public async Task RefreshSelectedEntity() { var subscriptionNode = subscriptionsNode.Nodes.Add(subscription.Name, GetNameAndMessageCountText(subscription.Name, subscription.MessageCountDetails), - subscription.Status == EntityStatus.Active ? SubscriptionIconIndex : GreySubscriptionIconIndex, - subscription.Status == EntityStatus.Active ? SubscriptionIconIndex : GreySubscriptionIconIndex); + subscription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? SubscriptionIconIndex : GreySubscriptionIconIndex, + subscription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? SubscriptionIconIndex : GreySubscriptionIconIndex); subscriptionNode.ContextMenuStrip = subscriptionContextMenuStrip; subscriptionNode.Tag = new SubscriptionWrapper(subscription, wrapper.TopicDescription); WriteToLog(string.Format(CultureInfo.CurrentCulture, SubscriptionRetrievedFormat, subscription.Name, wrapper.TopicDescription.Path), false); @@ -3097,7 +3107,7 @@ public async Task RefreshSelectedEntity() { var subscriptionDescription = serviceBusHelper.GetSubscription(subWrapper.SubscriptionDescription.TopicPath, subWrapper.SubscriptionDescription.Name); subWrapper = new SubscriptionWrapper(subscriptionDescription, subWrapper.TopicDescription); - if (subscriptionDescription.Status == EntityStatus.Active) + if (subscriptionDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active) { serviceBusTreeView.SelectedNode.ImageIndex = SubscriptionIconIndex; serviceBusTreeView.SelectedNode.SelectedImageIndex = SubscriptionIconIndex; @@ -3432,7 +3442,7 @@ private void HandleNodeMouseClick(TreeNode node) // Topic Node if (node.Tag is TopicDescription topicDescription) { - changeStatusTopicMenuItem.Text = topicDescription.Status == EntityStatus.Active ? DisableTopic : EnableTopic; + changeStatusTopicMenuItem.Text = topicDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? DisableTopic : EnableTopic; var list = CloneItems(topicContextMenuStrip.Items); AddImportAndSeparatorMenuItems(list); actionsToolStripMenuItem.DropDownItems.AddRange(list.ToArray()); @@ -3459,7 +3469,7 @@ private void HandleNodeMouseClick(TreeNode node) // EventHub Node if (node.Tag is EventHubDescription eventHubDescription) { - changeStatusEventHubMenuItem.Text = eventHubDescription.Status == EntityStatus.Active ? DisableEventHub : EnableEventHub; + changeStatusEventHubMenuItem.Text = eventHubDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? DisableEventHub : EnableEventHub; var list = CloneItems(eventHubContextMenuStrip.Items); AddImportAndSeparatorMenuItems(list); actionsToolStripMenuItem.DropDownItems.AddRange(list.ToArray()); @@ -3509,7 +3519,7 @@ private void HandleNodeMouseClick(TreeNode node) // Subscription Node if (node.Tag is SubscriptionWrapper subscriptionWrapper) { - changeStatusSubscriptionMenuItem.Text = subscriptionWrapper.SubscriptionDescription.Status == EntityStatus.Active ? DisableSubscription : EnableSubscription; + changeStatusSubscriptionMenuItem.Text = subscriptionWrapper.SubscriptionDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? DisableSubscription : EnableSubscription; getSubscriptionMessageSessionsMenuItem.Visible = subscriptionWrapper.SubscriptionDescription.RequiresSession; getSubscriptionMessageSessionsSeparator.Visible = subscriptionWrapper.SubscriptionDescription.RequiresSession; subReceiveMessagesMenuItem.Visible = string.IsNullOrWhiteSpace(subscriptionWrapper.SubscriptionDescription.ForwardTo); @@ -3549,6 +3559,8 @@ private void GetServiceBusNamespacesFromConfiguration() try { var configuration = TwoFilesConfiguration.Create(configFileUse, WriteToLog); + serviceBusHelper2.ServiceBusNamespaces = + ServiceBusNamespace2.GetMessagingNamespaces(configuration, WriteToLog); serviceBusHelper.ServiceBusNamespaces = ServiceBusNamespace.GetMessagingNamespaces(configuration, WriteToLog); } @@ -3971,7 +3983,7 @@ private void ReadEventHubPartitionCheckpointFile() private void RefreshQueueNode(TreeNode node, QueueDescription queueDescription) { - if (queueDescription.Status == EntityStatus.Active) + if (queueDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active) { node.ImageIndex = QueueIconIndex; node.SelectedImageIndex = QueueIconIndex; @@ -3988,7 +4000,7 @@ private void RefreshQueueNode(TreeNode node, QueueDescription queueDescription) private void RefreshTopicNode(TreeNode node, TopicDescription topicDescription) { - if (topicDescription.Status == EntityStatus.Active) + if (topicDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active) { node.ImageIndex = TopicIconIndex; node.SelectedImageIndex = TopicIconIndex; @@ -4202,7 +4214,7 @@ private async Task ShowEntities(EntityType entityType) try { - if (serviceBusHelper != null && serviceBusHelper.NamespaceUri != null) + if (serviceBusHelper != null && serviceBusHelper2 != null) { Cursor.Current = Cursors.WaitCursor; serviceBusTreeView.SuspendDrawing(); @@ -4217,7 +4229,7 @@ private async Task ShowEntities(EntityType entityType) if (entityType == EntityType.All) { serviceBusTreeView.Nodes.Clear(); - rootNode = serviceBusTreeView.Nodes.Add(serviceBusHelper.NamespaceUri.AbsoluteUri, serviceBusHelper.NamespaceUri.AbsoluteUri, AzureIconIndex, AzureIconIndex); + rootNode = serviceBusTreeView.Nodes.Add("tobefilled" /*serviceBusHelper.NamespaceUri.AbsoluteUri*/, "tobefilled" /*serviceBusHelper2..NamespaceUri.AbsoluteUri*/, AzureIconIndex, AzureIconIndex); rootNode.ContextMenuStrip = rootContextMenuStrip; if (SelectedEntities.Contains(Constants.QueueEntities)) { @@ -4231,7 +4243,7 @@ private async Task ShowEntities(EntityType entityType) } // NOTE: Relays are not actually supported by Service Bus for Windows Server - if (serviceBusHelper.IsCloudNamespace) + if (serviceBusHelper2.IsCloudNamespace) { if (SelectedEntities.Contains(Constants.EventHubEntities)) { @@ -4251,7 +4263,7 @@ private async Task ShowEntities(EntityType entityType) } } updating = true; - if (serviceBusHelper.IsCloudNamespace) + if (serviceBusHelper2.IsCloudNamespace) { if (SelectedEntities.Contains(Constants.EventHubEntities) && (entityType == EntityType.All || @@ -4346,6 +4358,7 @@ private async Task ShowEntities(EntityType entityType) { try { + //todo getrelays var relayServices = serviceBusHelper.GetRelays(MainForm.SingletonMainForm.ServerTimeout); relayServiceListNode.Text = Constants.RelayEntities; @@ -4387,7 +4400,7 @@ private async Task ShowEntities(EntityType entityType) { try { - var queues = serviceBusHelper.GetQueues(FilterExpressionHelper.QueueFilterExpression, + var queues = await serviceBusHelper2.GetQueuesAsync(FilterExpressionHelper.QueueFilterExpression, MainForm.SingletonMainForm.ServerTimeout); queueListNode.Text = string.IsNullOrWhiteSpace(FilterExpressionHelper.QueueFilterExpression) ? Constants.QueueEntities @@ -4398,11 +4411,11 @@ private async Task ShowEntities(EntityType entityType) { foreach (var queue in queues) { - if (string.IsNullOrWhiteSpace(queue.Path)) + if (string.IsNullOrWhiteSpace(queue.Name)) { continue; } - CreateNode(queue.Path, queue, queueListNode, true); + CreateNode(queue.Name, queue, queueListNode, true); } } if (entityType == EntityType.Queue) @@ -4428,6 +4441,7 @@ private async Task ShowEntities(EntityType entityType) { try { + //todo get topics var topics = serviceBusHelper.GetTopics(FilterExpressionHelper.TopicFilterExpression, MainForm.SingletonMainForm.ServerTimeout); topicListNode.Text = string.IsNullOrWhiteSpace(FilterExpressionHelper.TopicFilterExpression) @@ -4557,10 +4571,10 @@ private void LazyLoadNode(TreeNode entityNode) { var subscriptionNode = subscriptionsNode.Nodes.Add(subscription.Name, GetNameAndMessageCountText(subscription.Name, subscription.MessageCountDetails), - subscription.Status == EntityStatus.Active + subscription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? SubscriptionIconIndex : GreySubscriptionIconIndex, - subscription.Status == EntityStatus.Active + subscription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? SubscriptionIconIndex : GreySubscriptionIconIndex); subscriptionNode.ContextMenuStrip = subscriptionContextMenuStrip; @@ -5625,7 +5639,7 @@ private TreeNode CreateNode(string path, UrlSegmentIconIndex, UrlSegmentIconIndex); var entityType = EntityType.Queue; - if (tag is QueueDescription) + if (tag is QueueRuntimeProperties) { entityNode.ContextMenuStrip = queueFolderContextMenuStrip; } @@ -5644,20 +5658,21 @@ private TreeNode CreateNode(string path, } else { - if (tag is QueueDescription) + if (tag is QueueRuntimeProperties) { - var queueDescription = tag as QueueDescription; + var queueProperties = tag as QueueRuntimeProperties; entityNode = entityNode.Nodes.Add(segments[i], - GetNameAndMessageCountText(segments[i], queueDescription.MessageCountDetails), - queueDescription.Status == EntityStatus.Active ? QueueIconIndex : GreyQueueIconIndex, - queueDescription.Status == EntityStatus.Active ? QueueIconIndex : GreyQueueIconIndex); + GetNameAndMessageCountText(segments[i], queueProperties), + QueueIconIndex, QueueIconIndex + /*queueProperties.Status == Azure.Messaging.ServiceBus.Administration.EntityStatus.Active ? QueueIconIndex : GreyQueueIconIndex, + queueProperties.Status == Azure.Messaging.ServiceBus.Administration.EntityStatus.Active ? QueueIconIndex : GreyQueueIconIndex*/); entityNode.ContextMenuStrip = queueContextMenuStrip; entityNode.Tag = tag; ApplyColor(entityNode, true); if (log) { - WriteToLog(string.Format(CultureInfo.CurrentCulture, QueueRetrievedFormat, queueDescription.Path), false); + WriteToLog(string.Format(CultureInfo.CurrentCulture, QueueRetrievedFormat, queueProperties.Name), false); } return entityNode; } @@ -5666,8 +5681,8 @@ private TreeNode CreateNode(string path, var topicDescription = tag as TopicDescription; entityNode = entityNode.Nodes.Add(segments[i], segments[i], - topicDescription.Status == EntityStatus.Active ? TopicIconIndex : GreyTopicIconIndex, - topicDescription.Status == EntityStatus.Active ? TopicIconIndex : GreyTopicIconIndex); + topicDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? TopicIconIndex : GreyTopicIconIndex, + topicDescription.Status == Microsoft.ServiceBus.Messaging.EntityStatus.Active ? TopicIconIndex : GreyTopicIconIndex); entityNode.ContextMenuStrip = topicContextMenuStrip; entityNode.Tag = tag; ApplyColor(entityNode, true); @@ -5736,6 +5751,21 @@ private TreeNode CreateNode(string path, return null; } + private string GetNameAndMessageCountText(string name, QueueRuntimeProperties details) + { + MessageCountDetails messageCountDetails = new MessageCountDetails(details.ActiveMessageCount, details.DeadLetterMessageCount, details.ScheduledMessageCount, details.TransferMessageCount, details.TransferDeadLetterMessageCount); + var sb = new StringBuilder(); + sb.Append(name); + if (showMessageCount && SelectedMessageCounts.Any()) + { + sb.Append(" ("); + var counts = SelectedMessageCounts.Select(smc => messageCountRetriever[smc](messageCountDetails)); + sb.Append(string.Join(", ", counts)); + sb.Append(")"); + } + return sb.ToString(); + } + private string GetNameAndMessageCountText(string name, MessageCountDetails details) { var sb = new StringBuilder(); @@ -6485,6 +6515,8 @@ private async void MainForm_Shown(object sender, EventArgs e) var ns = item.Value; if (ns != null) { + var serviceBusNamespace2 = ServiceBusNamespace2.GetServiceBusNamespace(item.Key, ns.ConnectionString, StaticWriteToLog); + serviceBusHelper2.Connect(serviceBusNamespace2); var serviceBusNamespace = ServiceBusNamespace.GetServiceBusNamespace(item.Key, ns.ConnectionString, StaticWriteToLog); serviceBusHelper.Connect(serviceBusNamespace); SetTitle(serviceBusNamespace.Namespace); @@ -6493,6 +6525,8 @@ private async void MainForm_Shown(object sender, EventArgs e) if (string.Compare(argumentName, "/c", StringComparison.InvariantCultureIgnoreCase) == 0 || string.Compare(argumentName, "-c", StringComparison.InvariantCultureIgnoreCase) == 0) { + var serviceBusNamespace2 = ServiceBusNamespace2.GetServiceBusNamespace("Manual", argumentValue, StaticWriteToLog); + serviceBusHelper2.Connect(serviceBusNamespace2); var serviceBusNamespace = ServiceBusNamespace.GetServiceBusNamespace("Manual", argumentValue, StaticWriteToLog); serviceBusHelper.Connect(serviceBusNamespace); SetTitle(serviceBusNamespace.Namespace); diff --git a/src/ServiceBusExplorer/Forms/MessageForm.cs b/src/ServiceBusExplorer/Forms/MessageForm.cs index 0a7ff931..703b9da3 100644 --- a/src/ServiceBusExplorer/Forms/MessageForm.cs +++ b/src/ServiceBusExplorer/Forms/MessageForm.cs @@ -41,6 +41,8 @@ namespace ServiceBusExplorer.Forms { + using Azure.Messaging.ServiceBus.Administration; + public partial class MessageForm : Form { #region Private Constants @@ -87,7 +89,7 @@ public partial class MessageForm : Form readonly ServiceBusHelper serviceBusHelper; readonly WriteToLogDelegate writeToLog; readonly BindingSource bindingSource = new BindingSource(); - readonly QueueDescription queueDescription; // Might be null + readonly QueueProperties queueProperties; // Might be null readonly SubscriptionWrapper subscriptionWrapper; // Might be null #endregion @@ -209,11 +211,11 @@ public MessageForm(BrokeredMessage brokeredMessage, ServiceBusHelper serviceBusH } } - public MessageForm(QueueDescription queueDescription, BrokeredMessage brokeredMessage, + public MessageForm(QueueProperties queueProperties, BrokeredMessage brokeredMessage, ServiceBusHelper serviceBusHelper, WriteToLogDelegate writeToLog) : this(brokeredMessage, serviceBusHelper, writeToLog) { - this.queueDescription = queueDescription; + this.queueProperties = queueProperties; } public MessageForm(SubscriptionWrapper subscriptionWrapper, BrokeredMessage brokeredMessage, @@ -260,11 +262,11 @@ public MessageForm(IEnumerable brokeredMessages, ServiceBusHelp } } - public MessageForm(QueueDescription queueDescription, IEnumerable brokeredMessages, + public MessageForm(QueueProperties queueProperties, IEnumerable brokeredMessages, ServiceBusHelper serviceBusHelper, WriteToLogDelegate writeToLog) : this(brokeredMessages, serviceBusHelper, writeToLog) { - this.queueDescription = queueDescription; + this.queueProperties = queueProperties; } public MessageForm(SubscriptionWrapper subscriptionWrapper, IEnumerable brokeredMessages, @@ -305,7 +307,7 @@ private void MessageForm_Load(object sender, EventArgs e) txtMessageText.Focus(); txtMessageText.SelectionLength = 0; - if (queueDescription != null || subscriptionWrapper != null) + if (queueProperties != null || subscriptionWrapper != null) { chkRemove.Visible = true; } @@ -507,11 +509,11 @@ private async void btnSubmit_Click(object sender, EventArgs e) messageSender.Path, stopwatch.ElapsedMilliseconds)); } - if (null != queueDescription) + if (null != queueProperties) { - if (!messageSender.Path.Equals(queueDescription.Path, StringComparison.InvariantCultureIgnoreCase)) + if (!messageSender.Path.Equals(queueProperties.Name, StringComparison.InvariantCultureIgnoreCase)) { - await MainForm.SingletonMainForm.RefreshServiceBusEntityNode(queueDescription.Path); + await MainForm.SingletonMainForm.RefreshServiceBusEntityNode(queueProperties.Name); } } else if (null != subscriptionWrapper?.SubscriptionDescription?.TopicPath) @@ -563,16 +565,16 @@ private async void btnSubmit_Click(object sender, EventArgs e) DeadLetterMessageHandler CreateDeadLetterMessageHandler() { - if (queueDescription != null) + if (queueProperties != null) { if (subscriptionWrapper != null) { throw new ArgumentException( - "At least one of the arguments queueDescription and subscriptionWrapper must be null."); + "At least one of the arguments queueProperties and subscriptionWrapper must be null."); } return new DeadLetterMessageHandler(writeToLog, serviceBusHelper, - MainForm.SingletonMainForm.ReceiveTimeout, queueDescription); + MainForm.SingletonMainForm.ReceiveTimeout, queueProperties); } if (subscriptionWrapper != null) @@ -581,21 +583,21 @@ DeadLetterMessageHandler CreateDeadLetterMessageHandler() MainForm.SingletonMainForm.ReceiveTimeout, subscriptionWrapper); } - throw new ArgumentException("queueDescription or subscriptionWrapper must be set."); + throw new ArgumentException("queueProperties or subscriptionWrapper must be set."); } SelectEntityForm CreateSelectEntityForm() { - if (queueDescription != null) + if (queueProperties != null) { if (subscriptionWrapper != null) { throw new ArgumentException( - "At least one of the arguments queueDescription and subscriptionWrapper must be null."); + "At least one of the arguments queueProperties and subscriptionWrapper must be null."); } return new SelectEntityForm(SelectEntityDialogTitle, SelectEntityGrouperTitle, - SelectEntityLabelText, queueDescription); + SelectEntityLabelText, queueProperties); } if (subscriptionWrapper != null) diff --git a/src/ServiceBusExplorer/Forms/SelectEntityForm.cs b/src/ServiceBusExplorer/Forms/SelectEntityForm.cs index d987ad6b..73732978 100644 --- a/src/ServiceBusExplorer/Forms/SelectEntityForm.cs +++ b/src/ServiceBusExplorer/Forms/SelectEntityForm.cs @@ -32,6 +32,8 @@ namespace ServiceBusExplorer.Forms { + using Azure.Messaging.ServiceBus.Administration; + public partial class SelectEntityForm : Form { #region Private Constants diff --git a/src/ServiceBusExplorer/ServiceBusExplorer.csproj b/src/ServiceBusExplorer/ServiceBusExplorer.csproj index 2e596a8d..9eb98e19 100644 --- a/src/ServiceBusExplorer/ServiceBusExplorer.csproj +++ b/src/ServiceBusExplorer/ServiceBusExplorer.csproj @@ -40,6 +40,13 @@ https://github.com/paolosalvatori/ServiceBusExplorer/releases servicebusexplorer azure azureservicebus servicebus explorer eventhub queue subscription relay notificationhub + + true + + + + + AnyCPU full