diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/ClientOptions.cs b/src/Ev.ServiceBus.Abstractions/Configuration/ClientOptions.cs index 958590b..2631376 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/ClientOptions.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/ClientOptions.cs @@ -1,5 +1,7 @@ // ReSharper disable once CheckNamespace +using Ev.ServiceBus.Abstractions.Configuration; + namespace Ev.ServiceBus.Abstractions; public abstract class ClientOptions : IClientOptions diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs b/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs index 216646a..027053c 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs @@ -1,8 +1,8 @@ -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 { @@ -10,15 +10,22 @@ internal ConnectionSettings(string connectionString, ServiceBusClientOptions opt { 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; } @@ -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) diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/Extensions/ClientOptionsExtensions.cs b/src/Ev.ServiceBus.Abstractions/Configuration/Extensions/ClientOptionsExtensions.cs index 54194df..89876f1 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/Extensions/ClientOptionsExtensions.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/Extensions/ClientOptionsExtensions.cs @@ -1,5 +1,6 @@ using Azure.Core; using Azure.Messaging.ServiceBus; +using Ev.ServiceBus.Abstractions.Configuration; // ReSharper disable once CheckNamespace namespace Ev.ServiceBus.Abstractions; diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/IClientOptions.cs b/src/Ev.ServiceBus.Abstractions/Configuration/IClientOptions.cs index 7eaf25d..0294a21 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/IClientOptions.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/IClientOptions.cs @@ -1,4 +1,7 @@ // ReSharper disable once CheckNamespace + +using Ev.ServiceBus.Abstractions.Configuration; + namespace Ev.ServiceBus.Abstractions; public interface IClientOptions diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/ServiceBusSettings.cs b/src/Ev.ServiceBus.Abstractions/Configuration/ServiceBusSettings.cs index af86620..2cd3f28 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/ServiceBusSettings.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/ServiceBusSettings.cs @@ -1,5 +1,6 @@ using Azure.Core; using Azure.Messaging.ServiceBus; +using Ev.ServiceBus.Abstractions.Configuration; namespace Ev.ServiceBus.Abstractions; diff --git a/src/Ev.ServiceBus.AsyncApi/DocumentFilter.cs b/src/Ev.ServiceBus.AsyncApi/DocumentFilter.cs index 9acbdba..7bb0950 100644 --- a/src/Ev.ServiceBus.AsyncApi/DocumentFilter.cs +++ b/src/Ev.ServiceBus.AsyncApi/DocumentFilter.cs @@ -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; @@ -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), diff --git a/src/Ev.ServiceBus.HealthChecks/ConnectionSettingsComparer.cs b/src/Ev.ServiceBus.HealthChecks/ConnectionSettingsComparer.cs index 696bb26..8576fc9 100644 --- a/src/Ev.ServiceBus.HealthChecks/ConnectionSettingsComparer.cs +++ b/src/Ev.ServiceBus.HealthChecks/ConnectionSettingsComparer.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using Ev.ServiceBus.Abstractions; +using Ev.ServiceBus.Abstractions.Configuration; namespace Ev.ServiceBus.HealthChecks; diff --git a/src/Ev.ServiceBus/Management/Factories/ClientFactory.cs b/src/Ev.ServiceBus/Management/Factories/ClientFactory.cs index 53641d2..e9786b6 100644 --- a/src/Ev.ServiceBus/Management/Factories/ClientFactory.cs +++ b/src/Ev.ServiceBus/Management/Factories/ClientFactory.cs @@ -1,6 +1,6 @@ using System; using Azure.Messaging.ServiceBus; -using Ev.ServiceBus.Abstractions; +using Ev.ServiceBus.Abstractions.Configuration; namespace Ev.ServiceBus; diff --git a/src/Ev.ServiceBus/Management/Factories/IClientFactory.cs b/src/Ev.ServiceBus/Management/Factories/IClientFactory.cs index 9231571..ac6b1fd 100644 --- a/src/Ev.ServiceBus/Management/Factories/IClientFactory.cs +++ b/src/Ev.ServiceBus/Management/Factories/IClientFactory.cs @@ -1,5 +1,5 @@ using Azure.Messaging.ServiceBus; -using Ev.ServiceBus.Abstractions; +using Ev.ServiceBus.Abstractions.Configuration; // ReSharper disable once CheckNamespace namespace Ev.ServiceBus; diff --git a/src/Ev.ServiceBus/Management/ServiceBusRegistry.cs b/src/Ev.ServiceBus/Management/ServiceBusRegistry.cs index ebfe19a..0c9f0fc 100644 --- a/src/Ev.ServiceBus/Management/ServiceBusRegistry.cs +++ b/src/Ev.ServiceBus/Management/ServiceBusRegistry.cs @@ -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; diff --git a/src/Ev.ServiceBus/Management/Wrappers/ComposedReceiverOptions.cs b/src/Ev.ServiceBus/Management/Wrappers/ComposedReceiverOptions.cs index a7a5c3b..27dc320 100644 --- a/src/Ev.ServiceBus/Management/Wrappers/ComposedReceiverOptions.cs +++ b/src/Ev.ServiceBus/Management/Wrappers/ComposedReceiverOptions.cs @@ -2,6 +2,7 @@ using System.Linq; using Azure.Messaging.ServiceBus; using Ev.ServiceBus.Abstractions; +using Ev.ServiceBus.Abstractions.Configuration; namespace Ev.ServiceBus; diff --git a/tests/Ev.ServiceBus.HealthChecks.UnitTests/ComplexTest.cs b/tests/Ev.ServiceBus.HealthChecks.UnitTests/ComplexTest.cs index 8bf8ca2..ef410d1 100644 --- a/tests/Ev.ServiceBus.HealthChecks.UnitTests/ComplexTest.cs +++ b/tests/Ev.ServiceBus.HealthChecks.UnitTests/ComplexTest.cs @@ -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(); @@ -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(); diff --git a/tests/Ev.ServiceBus.TestHelpers/FailingClientFactory.cs b/tests/Ev.ServiceBus.TestHelpers/FailingClientFactory.cs index f32e70d..4d54e59 100644 --- a/tests/Ev.ServiceBus.TestHelpers/FailingClientFactory.cs +++ b/tests/Ev.ServiceBus.TestHelpers/FailingClientFactory.cs @@ -1,6 +1,6 @@ using System; using Azure.Messaging.ServiceBus; -using Ev.ServiceBus.Abstractions; +using Ev.ServiceBus.Abstractions.Configuration; namespace Ev.ServiceBus.UnitTests.Helpers; diff --git a/tests/Ev.ServiceBus.TestHelpers/FakeClientFactory.cs b/tests/Ev.ServiceBus.TestHelpers/FakeClientFactory.cs index ac892ce..36bd972 100644 --- a/tests/Ev.ServiceBus.TestHelpers/FakeClientFactory.cs +++ b/tests/Ev.ServiceBus.TestHelpers/FakeClientFactory.cs @@ -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; diff --git a/tests/Ev.ServiceBus.TestHelpers/ServiceBusClientMock.cs b/tests/Ev.ServiceBus.TestHelpers/ServiceBusClientMock.cs index 16d181f..a9c080e 100644 --- a/tests/Ev.ServiceBus.TestHelpers/ServiceBusClientMock.cs +++ b/tests/Ev.ServiceBus.TestHelpers/ServiceBusClientMock.cs @@ -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; diff --git a/tests/Ev.ServiceBus.UnitTests/Configuration/DispatchConfigurationTest.cs b/tests/Ev.ServiceBus.UnitTests/Configuration/DispatchConfigurationTest.cs index 35106af..3893942 100644 --- a/tests/Ev.ServiceBus.UnitTests/Configuration/DispatchConfigurationTest.cs +++ b/tests/Ev.ServiceBus.UnitTests/Configuration/DispatchConfigurationTest.cs @@ -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; @@ -362,17 +363,18 @@ 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(); + const string connectionString = "Endpoint=sb://acmecompany.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=kFCrVU8u5v0LASbKGA3MHDpnCOguiNwL++r1cAvblhc="; factory.Setup(o => o.Create(It.Is(settings => - settings.ConnectionString == "Endpoint=newConnectionString;" + settings.ConnectionString == connectionString && settings.Options == serviceBusClientOptions - && settings.Endpoint == "newConnectionString"))) + && settings.Endpoint == "sb://acmecompany.servicebus.windows.net/"))) .Returns(new Mock().Object); composer.WithAdditionalServices(services => @@ -380,7 +382,7 @@ public async Task CustomizeConnection_ChangesAreAppliedToClient() services.RegisterServiceBusDispatch() .ToTopic("testTopic", builder => { - builder.CustomizeConnection("Endpoint=newConnectionString;", serviceBusClientOptions); + builder.CustomizeConnection(connectionString, serviceBusClientOptions); builder.RegisterDispatch(); }); services.OverrideClientFactory(factory.Object); diff --git a/tests/Ev.ServiceBus.UnitTests/Configuration/ReceptionConfigurationTest.cs b/tests/Ev.ServiceBus.UnitTests/Configuration/ReceptionConfigurationTest.cs index c55238f..fe42bff 100644 --- a/tests/Ev.ServiceBus.UnitTests/Configuration/ReceptionConfigurationTest.cs +++ b/tests/Ev.ServiceBus.UnitTests/Configuration/ReceptionConfigurationTest.cs @@ -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 => @@ -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 @@ -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); } diff --git a/tests/Ev.ServiceBus.UnitTests/Configuration/ServiceBusSettingsTests.cs b/tests/Ev.ServiceBus.UnitTests/Configuration/ServiceBusSettingsTests.cs index 1e3780e..ad60a02 100644 --- a/tests/Ev.ServiceBus.UnitTests/Configuration/ServiceBusSettingsTests.cs +++ b/tests/Ev.ServiceBus.UnitTests/Configuration/ServiceBusSettingsTests.cs @@ -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>(); 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/"); } } \ No newline at end of file diff --git a/tests/Ev.ServiceBus.UnitTests/DispatchTest.cs b/tests/Ev.ServiceBus.UnitTests/DispatchTest.cs index ef65051..1009089 100644 --- a/tests/Ev.ServiceBus.UnitTests/DispatchTest.cs +++ b/tests/Ev.ServiceBus.UnitTests/DispatchTest.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -408,10 +407,11 @@ await Assert.ThrowsAsync( 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 => @@ -447,10 +447,11 @@ 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 => @@ -458,14 +459,14 @@ public async Task SendDispatchesPaginateMessages() builder.RegisterDispatch(); }); 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}" @@ -484,17 +485,18 @@ public async Task SendDispatchesPaginateMessages() mock.Mock.Verify(o => o.SendMessagesAsync(It.IsAny(), It.IsAny()), 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 => @@ -502,14 +504,14 @@ public async Task ScheduleDispatchesPaginateMessages() builder.RegisterDispatch(); }); 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}" @@ -530,7 +532,7 @@ public async Task ScheduleDispatchesPaginateMessages() mock.Mock.Verify(o => o.ScheduleMessagesAsync(It.IsAny>(), schedule, It.IsAny()), Times.Exactly(3)); // Dispose - await provider.SimulateStopHost(new CancellationToken()); + await provider.SimulateStopHost(CancellationToken.None); } [Fact]