diff --git a/src/AzureCloudServiceBus/AzureCloudServiceBusResource.cs b/src/AzureCloudServiceBus/AzureCloudServiceBusResource.cs
index 5f19be31..8123682f 100644
--- a/src/AzureCloudServiceBus/AzureCloudServiceBusResource.cs
+++ b/src/AzureCloudServiceBus/AzureCloudServiceBusResource.cs
@@ -1,8 +1,8 @@
-using System;
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
-using System.Text;
+using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.ServiceBus;
using Squadron.AzureCloud;
@@ -10,12 +10,12 @@
using Xunit.Abstractions;
using Xunit.Sdk;
-namespace Squadron
+namespace Squadron
{
///
- /// Defines a Azure Cloud ServiceBus namespace
+ /// Defines a Azure Cloud ServiceBus namespace
///
- /// Option to initialize the resource
+ /// Option to initialize the resource
public class AzureCloudServiceBusResource
: AzureResource, IAsyncLifetime
where TOptions : AzureCloudServiceBusOptions,
@@ -26,10 +26,10 @@ public class AzureCloudServiceBusResource
private ServiceBusModel _serviceBusModel;
private readonly IMessageSink _messageSink;
- ///
- /// Initializes a new instance of the class.
- ///
- /// The message sink.
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The message sink.
public AzureCloudServiceBusResource(IMessageSink messageSink)
{
_messageSink = messageSink;
@@ -54,11 +54,11 @@ public ITopicClient GetTopicClient(string name,
}
- ///
- /// Creates a new topic
- ///
- /// The builder.
- /// Client to access the created topic
+ ///
+ /// Creates a new topic
+ ///
+ /// The builder.
+ /// Client to access the created topic
public async Task CreateTopicAsync(Action configure)
{
var builder = ServiceBusTopicBuilder.New();
@@ -133,9 +133,9 @@ private string GetQueue(string name)
return queue.CreatedName;
}
- ///
- /// Initialize the resource
- ///
+ ///
+ /// Initialize the resource
+ ///
public override async Task InitializeAsync()
{
await base.InitializeAsync();
@@ -149,7 +149,7 @@ public override async Task InitializeAsync()
}
private void BuildOptions()
- {
+ {
var builder = ServiceBusOptionsBuilder.New();
var options = new TOptions();
options.Configure(builder);
@@ -158,7 +158,7 @@ private void BuildOptions()
}
private void InitializeServiceBusManager()
- {
+ {
_serviceBusManager = new ServiceBusManager(
AzureConfig.Credentials,
new AzureResourceIdentifier
@@ -170,17 +170,22 @@ private void InitializeServiceBusManager()
}
private async Task PrepareNamespaceAsync()
- {
+ {
if (_serviceBusModel.Namespace == null)
{
_serviceBusModel.ProvisioningMode = ServiceBusProvisioningMode.CreateAndDelete;
_serviceBusModel.Namespace = await
- _serviceBusManager.CreateNamespaceAsync(AzureConfig.DefaultLocation);
+ _serviceBusManager.CreateRandomNamespaceAsync(AzureConfig.DefaultLocation);
+ }
+ else if (_serviceBusModel.ProvisioningMode == ServiceBusProvisioningMode.CreateIfNotExists)
+ {
+ _serviceBusModel.Namespace = await
+ _serviceBusManager.CreateNamespaceIfNotExistsAsync(AzureConfig.DefaultLocation, _serviceBusModel.Namespace);
}
}
private async Task PrepareQueuesAsync()
- {
+ {
foreach (ServiceBusQueueModel queue in _serviceBusModel.Queues)
{
if (_serviceBusModel.ProvisioningMode == ServiceBusProvisioningMode.UseExisting)
@@ -196,7 +201,7 @@ private async Task PrepareQueuesAsync()
}
private async Task PrepareTopicsAsync()
- {
+ {
foreach (ServiceBusTopicModel topic in _serviceBusModel.Topics)
{
_messageSink.OnMessage(
@@ -220,8 +225,8 @@ private async Task CreateTopicAsync(ServiceBusTopicModel topic)
}
///
- /// Cleans up the resource
- ///
+ /// Cleans up the resource
+ ///
public async Task DisposeAsync()
{
try
@@ -248,5 +253,5 @@ public async Task DisposeAsync()
//do not fail test
}
}
- }
-}
+ }
+}
diff --git a/src/AzureCloudServiceBus/Model/ServiceBusModel.cs b/src/AzureCloudServiceBus/Model/ServiceBusModel.cs
index 22ea1503..92544f46 100644
--- a/src/AzureCloudServiceBus/Model/ServiceBusModel.cs
+++ b/src/AzureCloudServiceBus/Model/ServiceBusModel.cs
@@ -4,60 +4,65 @@
namespace Squadron
{
- ///
- /// Azure ServiceBus model
- ///
- public class ServiceBusModel
+ ///
+ /// Azure ServiceBus model
+ ///
+ public class ServiceBusModel
{
- ///
- /// Gets or sets the namespace.
- ///
- ///
- /// The namespace.
- ///
+ ///
+ /// Gets or sets the namespace.
+ ///
+ ///
+ /// The namespace.
+ ///
public string Namespace { get; set; }
- ///
- /// Gets or sets the topics.
- ///
- ///
- /// The topics.
- ///
+ ///
+ /// Gets or sets the topics.
+ ///
+ ///
+ /// The topics.
+ ///
public List Topics { get; set; }
= new List();
- ///
- /// Gets or sets the queues.
- ///
- ///
- /// The queues.
- ///
+ ///
+ /// Gets or sets the queues.
+ ///
+ ///
+ /// The queues.
+ ///
public List Queues { get; set; }
= new List();
- ///
- /// Gets or sets the provisioning mode.
- ///
- ///
- /// The provisioning mode.
- ///
+ ///
+ /// Gets or sets the provisioning mode.
+ ///
+ ///
+ /// The provisioning mode.
+ ///
internal ServiceBusProvisioningMode ProvisioningMode { get; set; }
= ServiceBusProvisioningMode.UseExisting;
}
- ///
- /// Defines ServiceBUs provisioning modes
- ///
+ ///
+ /// Defines ServiceBUs provisioning modes
+ ///
internal enum ServiceBusProvisioningMode
{
- ///
- /// The uan existing Azure resource
- ///
+ ///
+ /// The uan existing Azure resource
+ ///
UseExisting,
- ///
- /// Provision and delete resource
- ///
- CreateAndDelete
+ ///
+ /// Provision and delete resource
+ ///
+ CreateAndDelete,
+
+ ///
+ /// Create or update resource
+ ///
+ CreateIfNotExists
}
}
diff --git a/src/AzureCloudServiceBus/ServiceBusManager.cs b/src/AzureCloudServiceBus/ServiceBusManager.cs
index 36223056..331a6f2a 100644
--- a/src/AzureCloudServiceBus/ServiceBusManager.cs
+++ b/src/AzureCloudServiceBus/ServiceBusManager.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Text;
+using System.Linq;
using System.Threading.Tasks;
using Microsoft.Azure.Management.ServiceBus;
using Microsoft.Azure.Management.ServiceBus.Models;
@@ -38,11 +38,47 @@ private async Task EnsureAuthenticatedAsync()
}
}
- internal async Task CreateNamespaceAsync(string location)
+ internal async Task CreateRandomNamespaceAsync(string location)
{
await EnsureAuthenticatedAsync();
var ns = $"squadron-{Guid.NewGuid().ToString("N").Substring(8)}";
+ return await CreateNamespaceAsync(location, ns);
+ }
+
+ internal async Task CreateNamespaceIfNotExistsAsync(string location, string serviceBusNamespace)
+ {
+ await EnsureAuthenticatedAsync();
+
+ if (await CheckServiceBusNamespaceExists(serviceBusNamespace) == false)
+ return await CreateNamespaceAsync(location, serviceBusNamespace);
+
+ _identifier.Name = serviceBusNamespace;
+ return serviceBusNamespace;
+ }
+
+ private async Task CheckServiceBusNamespaceExists(string serviceBusNamespace)
+ {
+ var serviceBusNamespaces = new List();
+
+ var listByResourceGroupAsync = await _client.Namespaces.ListByResourceGroupAsync(_identifier.ResourceGroupName);
+ serviceBusNamespaces.AddRange(listByResourceGroupAsync);
+
+ var nextPageLink = listByResourceGroupAsync.NextPageLink;
+ while (nextPageLink != null)
+ {
+ listByResourceGroupAsync = await _client.Namespaces.ListByResourceGroupNextAsync(nextPageLink);
+ nextPageLink = listByResourceGroupAsync.Any(x => x.Name == serviceBusNamespace) ?
+ null :
+ listByResourceGroupAsync.NextPageLink;
+ serviceBusNamespaces.AddRange(listByResourceGroupAsync);
+ }
+
+ return serviceBusNamespaces.Any(x => x.Name == serviceBusNamespace);
+ }
+
+ private async Task CreateNamespaceAsync(string location, string ns)
+ {
var pars = new SBNamespace
{
Sku = new SBSku(SkuName.Standard),
@@ -50,7 +86,7 @@ internal async Task CreateNamespaceAsync(string location)
};
SBNamespace res = await _client.Namespaces
- .CreateOrUpdateAsync(_identifier.ResourceGroupName, ns, pars);
+ .CreateOrUpdateAsync(_identifier.ResourceGroupName, ns, pars);
_identifier.Name = res.Name;
return res.Name;
diff --git a/src/AzureCloudServiceBus/ServiceBusOptionsBuilder.cs b/src/AzureCloudServiceBus/ServiceBusOptionsBuilder.cs
index d2c60d6b..8112c21f 100644
--- a/src/AzureCloudServiceBus/ServiceBusOptionsBuilder.cs
+++ b/src/AzureCloudServiceBus/ServiceBusOptionsBuilder.cs
@@ -4,19 +4,19 @@
namespace Squadron
{
- ///
- /// ServiceBusOptions builder
- ///
+ ///
+ /// ServiceBusOptions builder
+ ///
public class ServiceBusOptionsBuilder : AzureResourceOptionsBuilder
{
private ServiceBusModel _model = new ServiceBusModel();
private List _topics = new List();
private List _queues = new List();
- ///
- /// Creates a new empty builder
- ///
- ///
+ ///
+ /// Creates a new empty builder
+ ///
+ ///
public static ServiceBusOptionsBuilder New() => new ServiceBusOptionsBuilder();
@@ -26,23 +26,37 @@ private ServiceBusOptionsBuilder()
}
- ///
- /// Namespace
- ///
- /// The namespace.
- ///
+ ///
+ /// Namespace
+ ///
+ /// The namespace.
+ ///
public ServiceBusOptionsBuilder Namespace(string ns)
+ {
+ return Namespace(ns, createIfNotExists: false);
+ }
+
+ ///
+ /// Namespace
+ ///
+ /// The namespace.
+ /// creates namespace if doesn't exist.
+ ///
+ public ServiceBusOptionsBuilder Namespace(string ns, bool createIfNotExists)
{
_model.Namespace = ns;
+ _model.ProvisioningMode = createIfNotExists
+ ? ServiceBusProvisioningMode.CreateIfNotExists
+ : ServiceBusProvisioningMode.UseExisting;
return this;
}
- ///
- /// Adds a topic.
- ///
- /// The topic name.
- ///
+ ///
+ /// Adds a topic.
+ ///
+ /// The topic name.
+ ///
public ServiceBusTopicBuilder AddTopic(string name)
{
var topicBuilder = ServiceBusTopicBuilder.New(name);
@@ -51,11 +65,11 @@ public ServiceBusTopicBuilder AddTopic(string name)
}
- ///
- /// Adds a queue.
- ///
- /// The queue name.
- ///
+ ///
+ /// Adds a queue.
+ ///
+ /// The queue name.
+ ///
public ServiceBusQueueBuilder AddQueue(string name)
{
var queueBuilder = new ServiceBusQueueBuilder(name);
@@ -64,10 +78,10 @@ public ServiceBusQueueBuilder AddQueue(string name)
}
- ///
- /// Builds the options
- ///
- ///
+ ///
+ /// Builds the options
+ ///
+ ///
public ServiceBusModel Build()
{
foreach (ServiceBusTopicBuilder tb in _topics)