Skip to content

Commit

Permalink
#686: Move Relay management functions to separate class (#822)
Browse files Browse the repository at this point in the history
* Move Relay management functions to separate class

* Don't seal internal class

---------

Co-authored-by: supereddie <>
  • Loading branch information
supereddie authored Jan 20, 2025
1 parent df05f3f commit 6734b2a
Show file tree
Hide file tree
Showing 3 changed files with 209 additions and 88 deletions.
98 changes: 10 additions & 88 deletions src/Common/Helpers/ServiceBusHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,6 @@ public class ServiceBusHelper
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 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.";
Expand Down Expand Up @@ -187,6 +184,7 @@ public class ServiceBusHelper
private IServiceBusTopic serviceBusTopic;
private IServiceBusSubscription serviceBusSubscription;
private IServiceBusRule serviceBusRule;
private IServiceBusRelay serviceBusRelay;
#endregion

#region Private Static Fields
Expand Down Expand Up @@ -250,6 +248,7 @@ public ServiceBusHelper(WriteToLogDelegate writeToLog, ServiceBusHelper serviceB
serviceBusTopic = serviceBusHelper.serviceBusTopic;
serviceBusSubscription = serviceBusHelper.serviceBusSubscription;
serviceBusRule = serviceBusHelper.serviceBusRule;
serviceBusRelay = serviceBusHelper.serviceBusRelay;
}
#endregion

Expand Down Expand Up @@ -789,6 +788,7 @@ public bool Connect(ServiceBusNamespace serviceBusNamespace)
serviceBusTopic = CreateServiceBusEntity(static (sbn, nsmgr) => new ServiceBusTopic(sbn, nsmgr));
serviceBusSubscription = CreateServiceBusEntity(static (sbn, nsmgr) => new ServiceBusSubscription(sbn, nsmgr));
serviceBusRule = CreateServiceBusEntity(static (sbn, nsmgr) => new ServiceBusRule(sbn, nsmgr));
serviceBusRelay = CreateServiceBusEntity(static (sbn, nsmgr) => new ServiceBusRelay(sbn, nsmgr));

WriteToLogIf(traceEnabled, string.Format(CultureInfo.CurrentCulture, ServiceBusIsConnected, namespaceManager.Address.AbsoluteUri));
namespaceUri = namespaceManager.Address;
Expand All @@ -812,15 +812,7 @@ public bool Connect(ServiceBusNamespace serviceBusNamespace)
/// <returns>A RelayDescription handle to the relay, or null if the relay does not exist in the service namespace. </returns>
public RelayDescription GetRelay(string path)
{
if (string.IsNullOrWhiteSpace(path))
{
throw new ArgumentException(PathCannotBeNull);
}
if (namespaceManager != null)
{
return RetryHelper.RetryFunc(() => namespaceManager.GetRelayAsync(path).Result, writeToLog);
}
throw new ApplicationException(ServiceBusIsDisconnected);
return serviceBusRelay.GetRelay(path);
}

/// <summary>
Expand All @@ -830,27 +822,7 @@ public RelayDescription GetRelay(string path)
/// Returns an empty collection if no relay exists in this service namespace.</returns>
public IEnumerable<RelayDescription> GetRelays(int timeoutInSeconds)
{
if (namespaceManager != null)
{
var taskList = new List<Task>();
var task = namespaceManager.GetRelaysAsync();
taskList.Add(task);
taskList.Add(Task.Delay(TimeSpan.FromSeconds(timeoutInSeconds)));
Task.WaitAny(taskList.ToArray());
if (task.IsCompleted)
{
try
{
return task.Result;
}
catch (AggregateException ex)
{
throw ex.InnerExceptions.First();
}
}
throw new TimeoutException();
}
throw new ApplicationException(ServiceBusIsDisconnected);
return serviceBusRelay.GetRelays(timeoutInSeconds);
}

/// <summary>
Expand All @@ -860,18 +832,7 @@ public IEnumerable<RelayDescription> GetRelays(int timeoutInSeconds)
/// <returns>Returns a newly-created RelayDescription object.</returns>
public RelayDescription CreateRelay(RelayDescription description)
{
if (description == null)
{
throw new ArgumentException(DescriptionCannotBeNull);
}
if (namespaceManager != null)
{
var relayService = RetryHelper.RetryFunc(() => namespaceManager.CreateRelayAsync(description).Result, writeToLog);
WriteToLogIf(traceEnabled, string.Format(CultureInfo.CurrentCulture, RelayCreated, description.Path));
OnCreate?.Invoke(new ServiceBusHelperEventArgs(relayService, EntityType.Relay));
return relayService;
}
throw new ApplicationException(ServiceBusIsDisconnected);
return serviceBusRelay.CreateRelay(description);
}

/// <summary>
Expand All @@ -880,20 +841,7 @@ public RelayDescription CreateRelay(RelayDescription description)
/// <param name="path">Path of the relay relative to the service namespace base address.</param>
public async Task DeleteRelay(string path)
{
if (string.IsNullOrWhiteSpace(path))
{
throw new ArgumentException(PathCannotBeNull);
}
if (namespaceManager != null)
{
await RetryHelper.RetryActionAsync(() => namespaceManager.DeleteRelayAsync(path), writeToLog);
WriteToLogIf(traceEnabled, string.Format(CultureInfo.CurrentCulture, RelayDeleted, path));
OnDelete?.Invoke(new ServiceBusHelperEventArgs(path, EntityType.Relay));
}
else
{
throw new ApplicationException(ServiceBusIsDisconnected);
}
await serviceBusRelay.DeleteRelay(path);
}

/// <summary>
Expand All @@ -902,11 +850,7 @@ public async Task DeleteRelay(string path)
/// </summary>
public async Task DeleteRelays(IEnumerable<string> relayServices)
{
if (relayServices == null)
{
return;
}
await Task.WhenAll(relayServices.Select(DeleteRelay));
await serviceBusRelay.DeleteRelays(relayServices);
}

/// <summary>
Expand All @@ -916,18 +860,7 @@ public async Task DeleteRelays(IEnumerable<string> relayServices)
/// <returns>Returns an updated RelayDescription object.</returns>
public RelayDescription UpdateRelay(RelayDescription description)
{
if (description == null)
{
throw new ArgumentException(DescriptionCannotBeNull);
}
if (namespaceManager != null)
{
var relayService = RetryHelper.RetryFunc(() => namespaceManager.UpdateRelayAsync(description).Result, writeToLog);
WriteToLogIf(traceEnabled, string.Format(CultureInfo.CurrentCulture, RelayUpdated, description.Path));
OnCreate?.Invoke(new ServiceBusHelperEventArgs(relayService, EntityType.Relay));
return relayService;
}
throw new ApplicationException(ServiceBusIsDisconnected);
return serviceBusRelay.UpdateRelay(description);
}

/// <summary>
Expand All @@ -937,18 +870,7 @@ public RelayDescription UpdateRelay(RelayDescription description)
/// <returns>The absolute uri of the relay.</returns>
public Uri GetRelayUri(RelayDescription description)
{
if (description == null)
{
throw new ArgumentException(DescriptionCannotBeNull);
}
if (namespaceManager == null)
{
return null;
}
var currentScheme = description.RelayType != RelayType.Http
? scheme
: description.RequiresTransportSecurity ? "https" : "http";
return Microsoft.ServiceBus.ServiceBusEnvironment.CreateServiceUri(currentScheme, Namespace, string.Concat(ServicePath, description.Path));
return serviceBusRelay.GetRelayUri(description);
}

/// <summary>
Expand Down
24 changes: 24 additions & 0 deletions src/Common/WindowsAzure/IServiceBusRelay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.ServiceBus.Messaging;

namespace ServiceBusExplorer.WindowsAzure
{
internal interface IServiceBusRelay : IServiceBusEntity
{
RelayDescription CreateRelay(RelayDescription description);

Task DeleteRelay(string path);

Task DeleteRelays(IEnumerable<string> relayServices);

RelayDescription GetRelay(string path);

IEnumerable<RelayDescription> GetRelays(int timeoutInSeconds);

Uri GetRelayUri(RelayDescription description);

RelayDescription UpdateRelay(RelayDescription description);
}
}
175 changes: 175 additions & 0 deletions src/Common/WindowsAzure/ServiceBusRelay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using ServiceBusExplorer.Enums;
using ServiceBusExplorer.Helpers;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;

namespace ServiceBusExplorer.WindowsAzure
{
internal class ServiceBusRelay : ServiceBusEntity, IServiceBusRelay
{
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 readonly string servicePath = string.Empty;

public ServiceBusRelay(ServiceBusNamespace serviceBusNamespace, Microsoft.ServiceBus.NamespaceManager namespaceManager)
: base(serviceBusNamespace, namespaceManager)
{
}

protected override EntityType EntityType => EntityType.Relay;

/// <summary>
/// Retrieves the relay from the service namespace.
/// </summary>
/// <param name="path">Path of the relay relative to the service namespace base address.</param>
/// <returns>A RelayDescription handle to the relay, or null if the relay does not exist in the service namespace. </returns>
public RelayDescription GetRelay(string path)
{
if (string.IsNullOrWhiteSpace(path))
{
throw new ArgumentException(PathCannotBeNull);
}
if (NamespaceManager != null)
{
return RetryHelper.RetryFunc(() => NamespaceManager.GetRelayAsync(path).Result, WriteToLog);
}
throw new ApplicationException(ServiceBusIsDisconnected);
}

/// <summary>
/// Retrieves an enumerable collection of all relays in the service bus namespace.
/// </summary>
/// <returns>Returns an IEnumerable<RelayDescription/> collection of all relays in the service namespace.
/// Returns an empty collection if no relay exists in this service namespace.</returns>
public IEnumerable<RelayDescription> GetRelays(int timeoutInSeconds)
{
if (NamespaceManager != null)
{
var taskList = new List<Task>();
var task = NamespaceManager.GetRelaysAsync();
taskList.Add(task);
taskList.Add(Task.Delay(TimeSpan.FromSeconds(timeoutInSeconds)));
Task.WaitAny(taskList.ToArray());
if (task.IsCompleted)
{
try
{
return task.Result;
}
catch (AggregateException ex)
{
throw ex.InnerExceptions.First();
}
}
throw new TimeoutException();
}
throw new ApplicationException(ServiceBusIsDisconnected);
}

/// <summary>
/// Creates a new relay in the service namespace with the given name.
/// </summary>
/// <param name="description">A RelayDescription object describing the attributes with which the new event hub will be created.</param>
/// <returns>Returns a newly-created RelayDescription object.</returns>
public RelayDescription CreateRelay(RelayDescription description)
{
if (description == null)
{
throw new ArgumentException(DescriptionCannotBeNull);
}
if (NamespaceManager != null)
{
var relayService = RetryHelper.RetryFunc(() => NamespaceManager.CreateRelayAsync(description).Result, WriteToLog);
Log(string.Format(CultureInfo.CurrentCulture, RelayCreated, description.Path));
OnCreated(relayService);
return relayService;
}
throw new ApplicationException(ServiceBusIsDisconnected);
}

/// <summary>
/// Deletes the relay described by the relative name of the service namespace base address.
/// </summary>
/// <param name="path">Path of the relay relative to the service namespace base address.</param>
public async Task DeleteRelay(string path)
{
if (string.IsNullOrWhiteSpace(path))
{
throw new ArgumentException(PathCannotBeNull);
}
if (NamespaceManager != null)
{
await RetryHelper.RetryActionAsync(() => NamespaceManager.DeleteRelayAsync(path), WriteToLog);
Log(string.Format(CultureInfo.CurrentCulture, RelayDeleted, path));
OnDeleted(new ServiceBusHelperEventArgs(path, EntityType));
}
else
{
throw new ApplicationException(ServiceBusIsDisconnected);
}
}

/// <summary>
/// Deletes all the relays in the list.
/// <param name="relayServices">A list of relays to delete.</param>
/// </summary>
public async Task DeleteRelays(IEnumerable<string> relayServices)
{
if (relayServices == null)
{
return;
}
await Task.WhenAll(relayServices.Select(DeleteRelay));
}

/// <summary>
/// Updates a relay in the service namespace with the given name.
/// </summary>
/// <param name="description">A RelayDescription object describing the attributes with which the new relay will be updated.</param>
/// <returns>Returns an updated RelayDescription object.</returns>
public RelayDescription UpdateRelay(RelayDescription description)
{
if (description == null)
{
throw new ArgumentException(DescriptionCannotBeNull);
}
if (NamespaceManager != null)
{
var relayService = RetryHelper.RetryFunc(() => NamespaceManager.UpdateRelayAsync(description).Result, WriteToLog);
Log(string.Format(CultureInfo.CurrentCulture, RelayUpdated, description.Path));
OnCreated(relayService);
return relayService;
}
throw new ApplicationException(ServiceBusIsDisconnected);
}

/// <summary>
/// Gets the uri of a relay.
/// </summary>
/// <param name="description">The description of a relay.</param>
/// <returns>The absolute uri of the relay.</returns>
public Uri GetRelayUri(RelayDescription description)
{
if (description == null)
{
throw new ArgumentException(DescriptionCannotBeNull);
}
if (NamespaceManager == null)
{
return null;
}
var currentScheme = description.RelayType != RelayType.Http
? Scheme
: description.RequiresTransportSecurity ? "https" : "http";
return Microsoft.ServiceBus.ServiceBusEnvironment.CreateServiceUri(currentScheme, Namespace, string.Concat(servicePath, description.Path));
}

}
}

0 comments on commit 6734b2a

Please sign in to comment.