Skip to content
2 changes: 2 additions & 0 deletions src/Ev.ServiceBus.Abstractions/Configuration/ClientOptions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// ReSharper disable once CheckNamespace

using Ev.ServiceBus.Abstractions.Configuration;

namespace Ev.ServiceBus.Abstractions;

public abstract class ClientOptions : IClientOptions
Expand Down
51 changes: 13 additions & 38 deletions src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
using Azure.Core;
using Azure.Messaging.ServiceBus;
using System;
using Azure.Messaging.ServiceBus;
using Azure.Core;

namespace Ev.ServiceBus.Abstractions;
namespace Ev.ServiceBus.Abstractions.Configuration;

public class ConnectionSettings
{
internal ConnectionSettings(string connectionString, ServiceBusClientOptions options)
{
ConnectionString = connectionString;
Options = options;
Endpoint = GetEndpointFromConnectionString(connectionString);
Endpoint = ServiceBusConnectionStringProperties.Parse(connectionString).Endpoint.AbsoluteUri;
}

internal ConnectionSettings(string fullyQualifiedNamespace, TokenCredential credentials, ServiceBusClientOptions options)
{
if (!fullyQualifiedNamespace.StartsWith("Endpoint=", StringComparison.OrdinalIgnoreCase))
{
fullyQualifiedNamespace = $"Endpoint={fullyQualifiedNamespace}";
}

var connectionStringProperties = ServiceBusConnectionStringProperties.Parse(fullyQualifiedNamespace);

Options = options;
FullyQualifiedNamespace = fullyQualifiedNamespace;
FullyQualifiedNamespace = connectionStringProperties.FullyQualifiedNamespace;
Credentials = credentials;
Endpoint = GetEndpointFromFullyQualifiedNamespace(fullyQualifiedNamespace);
Endpoint = connectionStringProperties.Endpoint.AbsoluteUri;
}

public string Endpoint { get; }
Expand All @@ -31,38 +38,6 @@ internal ConnectionSettings(string fullyQualifiedNamespace, TokenCredential cred

public TokenCredential? Credentials { get; }

private string GetEndpointFromConnectionString(string connectionString)
{
var KeyValuePairDelimiter = ';';
var KeyValueSeparator = '=';
var EndpointConfigName = "Endpoint";

// First split based on ';'
var keyValuePairs = connectionString.Split(new[] { KeyValuePairDelimiter }, StringSplitOptions.RemoveEmptyEntries);
foreach (var keyValuePair in keyValuePairs)
{
// Now split based on the _first_ '='
var keyAndValue = keyValuePair.Split(new[] { KeyValueSeparator }, 2);
var key = keyAndValue[0];
if (keyAndValue.Length != 2)
{
return string.Empty;
}

var value = keyAndValue[1].Trim();
if (key.Equals(EndpointConfigName, StringComparison.OrdinalIgnoreCase))
{
return value;
}
}
return string.Empty;
}

private string GetEndpointFromFullyQualifiedNamespace(string fullyQualifiedNamespace)
{
return $"sb://{fullyQualifiedNamespace}/";
}

private bool Equals(ConnectionSettings other) =>
string.Equals(Endpoint, other.Endpoint, StringComparison.Ordinal)
&& string.Equals(ConnectionString, other.ConnectionString, StringComparison.Ordinal)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Azure.Core;
using Azure.Messaging.ServiceBus;
using Ev.ServiceBus.Abstractions.Configuration;

// ReSharper disable once CheckNamespace
namespace Ev.ServiceBus.Abstractions;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
// ReSharper disable once CheckNamespace

using Ev.ServiceBus.Abstractions.Configuration;

namespace Ev.ServiceBus.Abstractions;

public interface IClientOptions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Azure.Core;
using Azure.Messaging.ServiceBus;
using Ev.ServiceBus.Abstractions.Configuration;

namespace Ev.ServiceBus.Abstractions;

Expand Down
6 changes: 2 additions & 4 deletions src/Ev.ServiceBus.AsyncApi/DocumentFilter.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Encodings.Web;
using System.Text.Json;
using Ev.ServiceBus.Abstractions;
using Ev.ServiceBus.Abstractions.Configuration;
using Microsoft.Extensions.Options;
using Microsoft.VisualBasic;
using NJsonSchema;
using Saunter.AsyncApiSchema.v2;
using Saunter.AsyncApiSchema.v2.Bindings;
Expand Down Expand Up @@ -117,7 +115,7 @@ private Operation CreatePublishOperation(string channelName, ClientOptions optio

private IMessage GenerateMessage(string payloadTypeId, Type payloadType, DocumentFilterContext context, AsyncApiSchemaResolver asyncApiSchemaResolver)
{
var message = new Saunter.AsyncApiSchema.v2.Message()
var message = new Message()
{
Name = payloadTypeId.Replace("/", "¤"),
Payload = GetOrCreatePayloadSchema(payloadType, context),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using Ev.ServiceBus.Abstractions;
using Ev.ServiceBus.Abstractions.Configuration;

namespace Ev.ServiceBus.HealthChecks;

Expand Down
2 changes: 1 addition & 1 deletion src/Ev.ServiceBus/Management/Factories/ClientFactory.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using Azure.Messaging.ServiceBus;
using Ev.ServiceBus.Abstractions;
using Ev.ServiceBus.Abstractions.Configuration;

namespace Ev.ServiceBus;

Expand Down
2 changes: 1 addition & 1 deletion src/Ev.ServiceBus/Management/Factories/IClientFactory.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Azure.Messaging.ServiceBus;
using Ev.ServiceBus.Abstractions;
using Ev.ServiceBus.Abstractions.Configuration;

// ReSharper disable once CheckNamespace
namespace Ev.ServiceBus;
Expand Down
1 change: 1 addition & 0 deletions src/Ev.ServiceBus/Management/ServiceBusRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using Azure.Messaging.ServiceBus;
using Ev.ServiceBus.Abstractions;
using Ev.ServiceBus.Abstractions.Configuration;
using Microsoft.Extensions.Options;

namespace Ev.ServiceBus.Management;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Linq;
using Azure.Messaging.ServiceBus;
using Ev.ServiceBus.Abstractions;
using Ev.ServiceBus.Abstractions.Configuration;

namespace Ev.ServiceBus;

Expand Down
4 changes: 2 additions & 2 deletions tests/Ev.ServiceBus.HealthChecks.UnitTests/ComplexTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public void MultipleRegistrationsGoesWell_case4()

services.AddServiceBus(settings =>
{
settings.WithConnection("Endpoint=testConnectionString;", new ServiceBusClientOptions());
settings.WithConnection("Endpoint=acmecompany.servicebus.windows.net;", new ServiceBusClientOptions());
});

services.AddHealthChecks().AddEvServiceBusChecks();
Expand Down Expand Up @@ -174,7 +174,7 @@ public void HealthCheckWorksWithEntraAuthorization()

services.AddServiceBus(settings =>
{
settings.WithConnection("fullyQualifiedNamespace", new DefaultAzureCredential(), new ServiceBusClientOptions());
settings.WithConnection("acmecompany.servicebus.windows.net", new DefaultAzureCredential(), new ServiceBusClientOptions());
});

services.AddHealthChecks().AddEvServiceBusChecks();
Expand Down
2 changes: 1 addition & 1 deletion tests/Ev.ServiceBus.TestHelpers/FailingClientFactory.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using Azure.Messaging.ServiceBus;
using Ev.ServiceBus.Abstractions;
using Ev.ServiceBus.Abstractions.Configuration;

namespace Ev.ServiceBus.UnitTests.Helpers;

Expand Down
2 changes: 1 addition & 1 deletion tests/Ev.ServiceBus.TestHelpers/FakeClientFactory.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using Azure.Messaging.ServiceBus;
using Ev.ServiceBus.Abstractions;
using Ev.ServiceBus.Abstractions.Configuration;

namespace Ev.ServiceBus.TestHelpers;

Expand Down
2 changes: 1 addition & 1 deletion tests/Ev.ServiceBus.TestHelpers/ServiceBusClientMock.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using Azure.Messaging.ServiceBus;
using Ev.ServiceBus.Abstractions;
using Ev.ServiceBus.Abstractions.Configuration;
using Moq;

namespace Ev.ServiceBus.TestHelpers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Threading.Tasks;
using Azure.Messaging.ServiceBus;
using Ev.ServiceBus.Abstractions;
using Ev.ServiceBus.Abstractions.Configuration;
using Ev.ServiceBus.Management;
using Ev.ServiceBus.UnitTests.Helpers;
using FluentAssertions;
Expand Down Expand Up @@ -362,25 +363,26 @@ public void SendToQueue_ArgumentCannotBeNull()
public async Task CustomizeConnection_ChangesAreAppliedToClient()
{
var composer = new Composer();
var serviceBusClientOptions = new ServiceBusClientOptions()
var serviceBusClientOptions = new ServiceBusClientOptions
{
EnableCrossEntityTransactions = true,
TransportType = ServiceBusTransportType.AmqpWebSockets
};

var factory = new Mock<IClientFactory>();
const string connectionString = "Endpoint=sb://acmecompany.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=kFCrVU8u5v0LASbKGA3MHDpnCOguiNwL++r1cAvblhc=";
factory.Setup(o => o.Create(It.Is<ConnectionSettings>(settings =>
settings.ConnectionString == "Endpoint=newConnectionString;"
settings.ConnectionString == connectionString
&& settings.Options == serviceBusClientOptions
&& settings.Endpoint == "newConnectionString")))
&& settings.Endpoint == "sb://acmecompany.servicebus.windows.net/")))
.Returns(new Mock<ServiceBusClient>().Object);

composer.WithAdditionalServices(services =>
{
services.RegisterServiceBusDispatch()
.ToTopic("testTopic", builder =>
{
builder.CustomizeConnection("Endpoint=newConnectionString;", serviceBusClientOptions);
builder.CustomizeConnection(connectionString, serviceBusClientOptions);
builder.RegisterDispatch<PublishedEvent>();
});
services.OverrideClientFactory(factory.Object);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ public async Task CustomizeMessageHandling_ChangesAreAppliedToClient()
[Fact]
public async Task CustomizeConnection_ChangesAreAppliedToClient()
{
const string connectionString = "Endpoint=sb://acmecompany.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=kFCrVU8u5v0LASbKGA3MHDpnCOguiNwL++r1cAvblhc=";
var composer = new Composer();

composer.WithAdditionalServices(services =>
Expand All @@ -365,7 +366,7 @@ public async Task CustomizeConnection_ChangesAreAppliedToClient()
.FromSubscription("testTopic", "testSubscription",
builder =>
{
builder.CustomizeConnection("Endpoint=newConnectionString;", new ServiceBusClientOptions()
builder.CustomizeConnection(connectionString, new ServiceBusClientOptions
{
EnableCrossEntityTransactions = true,
TransportType = ServiceBusTransportType.AmqpWebSockets
Expand All @@ -376,7 +377,7 @@ public async Task CustomizeConnection_ChangesAreAppliedToClient()
});

await composer.Compose();
var client = composer.ClientFactory.GetAssociatedMock("newConnectionString");
var client = composer.ClientFactory.GetAssociatedMock("sb://acmecompany.servicebus.windows.net/");
client.ConnectionSettings.Options.EnableCrossEntityTransactions.Should().Be(true);
client.ConnectionSettings.Options.TransportType.Should().Be(ServiceBusTransportType.AmqpWebSockets);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,19 @@ public async Task ServiceBusSettingsStateByDefault()
[Fact]
public async Task ServiceBusSettingsStateAfterCallOfWithConnection_string()
{
const string connectionString = "Endpoint=sb://acmecompany.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=kFCrVU8u5v0LASbKGA3MHDpnCOguiNwL++r1cAvblhc=";
var composer = new Composer();

composer.WithDefaultSettings(
settings =>
{
settings.WithConnection("Endpoint=testConnectionString;", new ServiceBusClientOptions());
settings.WithConnection(connectionString, new ServiceBusClientOptions());
});
var provider = await composer.Compose();

var options = provider.GetService<IOptions<ServiceBusOptions>>();

options.Value.Settings.ConnectionSettings.Should().NotBeNull();
options.Value.Settings.ConnectionSettings!.Endpoint.Should().Be("testConnectionString");
options.Value.Settings.ConnectionSettings!.Endpoint.Should().Be("sb://acmecompany.servicebus.windows.net/");
}
}
22 changes: 12 additions & 10 deletions tests/Ev.ServiceBus.UnitTests/DispatchTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
Expand Down Expand Up @@ -408,10 +407,11 @@ await Assert.ThrowsAsync<ArgumentNullException>(
public async Task SendDispatch()
{
// configure
const string connectionString = "Endpoint=sb://acmecompany.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=kFCrVU8u5v0LASbKGA3MHDpnCOguiNwL++r1cAvblhc=";
var services = new ServiceCollection();
services.AddServiceBus(settings =>
{
settings.WithConnection("myConnection", new ServiceBusClientOptions());
settings.WithConnection(connectionString, new ServiceBusClientOptions());
});
services.OverrideClientFactory();
services.RegisterServiceBusDispatch().ToQueue("myQueue", builder =>
Expand Down Expand Up @@ -447,25 +447,26 @@ public async Task SendDispatch()
public async Task SendDispatchesPaginateMessages()
{
// configure
const string connectionString = "Endpoint=sb://acmecompany.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=kFCrVU8u5v0LASbKGA3MHDpnCOguiNwL++r1cAvblhc=";
var services = new ServiceCollection();
services.AddServiceBus(settings =>
{
settings.WithConnection("myConnection", new ServiceBusClientOptions());
settings.WithConnection(connectionString, new ServiceBusClientOptions());
});
services.OverrideClientFactory();
services.RegisterServiceBusDispatch().ToQueue("myQueue", builder =>
{
builder.RegisterDispatch<SubscribedEvent>();
});
var provider = services.BuildServiceProvider();
await provider.SimulateStartHost(new CancellationToken());
await provider.SimulateStartHost(CancellationToken.None);

// Act
var messages = new SubscribedEvent[10000];
int i = 0;
while (i < 10000)
{
messages[i] = new SubscribedEvent()
messages[i] = new SubscribedEvent
{
SomeNumber = i + 1,
SomeString = $"Event number {i+1}"
Expand All @@ -484,32 +485,33 @@ public async Task SendDispatchesPaginateMessages()
mock.Mock.Verify(o => o.SendMessagesAsync(It.IsAny<ServiceBusMessageBatch>(), It.IsAny<CancellationToken>()), Times.Exactly(1));

// Dispose
await provider.SimulateStopHost(new CancellationToken());
await provider.SimulateStopHost(CancellationToken.None);
}

[Fact]
public async Task ScheduleDispatchesPaginateMessages()
{
// configure
const string connectionString = "Endpoint=sb://acmecompany.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=kFCrVU8u5v0LASbKGA3MHDpnCOguiNwL++r1cAvblhc=";
var services = new ServiceCollection();
services.AddServiceBus(settings =>
{
settings.WithConnection("myConnection", new ServiceBusClientOptions());
settings.WithConnection(connectionString, new ServiceBusClientOptions());
});
services.OverrideClientFactory();
services.RegisterServiceBusDispatch().ToQueue("myQueue", builder =>
{
builder.RegisterDispatch<SubscribedEvent>();
});
var provider = services.BuildServiceProvider();
await provider.SimulateStartHost(new CancellationToken());
await provider.SimulateStartHost(CancellationToken.None);

// Act
var messages = new SubscribedEvent[253];
int i = 0;
while (i < 253)
{
messages[i] = new SubscribedEvent()
messages[i] = new SubscribedEvent
{
SomeNumber = i + 1,
SomeString = $"Event number {i+1}"
Expand All @@ -530,7 +532,7 @@ public async Task ScheduleDispatchesPaginateMessages()
mock.Mock.Verify(o => o.ScheduleMessagesAsync(It.IsAny<IEnumerable<ServiceBusMessage>>(), schedule, It.IsAny<CancellationToken>()), Times.Exactly(3));

// Dispose
await provider.SimulateStopHost(new CancellationToken());
await provider.SimulateStopHost(CancellationToken.None);
}

[Fact]
Expand Down
Loading