From c1aa957d926004fc4882f969c3bc59f3f134e3f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Weronika=20=C5=81abaj?= Date: Thu, 1 Oct 2015 16:20:04 +0200 Subject: [PATCH 1/8] fody upgrade --- src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj | 5 +++-- src/NServiceBus.Core.Tests/packages.config | 2 +- src/NServiceBus.Core/NServiceBus.Core.csproj | 6 +++--- src/NServiceBus.Core/packages.config | 2 +- .../NServiceBus.Hosting.Profiles.csproj | 6 +++--- src/NServiceBus.Hosting.Profiles/packages.config | 2 +- .../NServiceBus.Hosting.WindowsAnyCpu.csproj | 6 +++--- .../NServiceBus.Hosting.WindowsX86.csproj | 4 ++-- src/NServiceBus.Hosting.Windows/packages.config | 2 +- src/NServiceBus.Testing/NServiceBus.Testing.csproj | 6 +++--- src/NServiceBus.Testing/packages.config | 2 +- 11 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj b/src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj index 1a4f43abfed..67e4ab263b5 100644 --- a/src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj +++ b/src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj @@ -15,6 +15,7 @@ ..\Test.snk ..\ + d4be09db true @@ -280,11 +281,11 @@ - + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/packages.config b/src/NServiceBus.Core.Tests/packages.config index e95b74eff26..6e04b584aa6 100644 --- a/src/NServiceBus.Core.Tests/packages.config +++ b/src/NServiceBus.Core.Tests/packages.config @@ -1,6 +1,6 @@  - + diff --git a/src/NServiceBus.Core/NServiceBus.Core.csproj b/src/NServiceBus.Core/NServiceBus.Core.csproj index 17a4f3d5b78..16091a2dd6a 100644 --- a/src/NServiceBus.Core/NServiceBus.Core.csproj +++ b/src/NServiceBus.Core/NServiceBus.Core.csproj @@ -15,7 +15,7 @@ ..\NServiceBus.snk ..\ - 35040652 + 6b1fd03b False @@ -610,15 +610,15 @@ - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + + \ No newline at end of file diff --git a/src/NServiceBus.Core/packages.config b/src/NServiceBus.Core/packages.config index ec327b137d6..77d958564b4 100644 --- a/src/NServiceBus.Core/packages.config +++ b/src/NServiceBus.Core/packages.config @@ -1,7 +1,7 @@  - + diff --git a/src/NServiceBus.Hosting.Profiles/NServiceBus.Hosting.Profiles.csproj b/src/NServiceBus.Hosting.Profiles/NServiceBus.Hosting.Profiles.csproj index 07b7202dba8..a4c534de789 100644 --- a/src/NServiceBus.Hosting.Profiles/NServiceBus.Hosting.Profiles.csproj +++ b/src/NServiceBus.Hosting.Profiles/NServiceBus.Hosting.Profiles.csproj @@ -11,7 +11,7 @@ NServiceBus.Hosting.Profiles v4.5 512 - 04ead7c6 + 0b251d8b False @@ -69,15 +69,15 @@ - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + + \ No newline at end of file diff --git a/src/NServiceBus.Hosting.Profiles/packages.config b/src/NServiceBus.Hosting.Profiles/packages.config index 93e068568ac..1cd8eca29d9 100644 --- a/src/NServiceBus.Hosting.Profiles/packages.config +++ b/src/NServiceBus.Hosting.Profiles/packages.config @@ -1,6 +1,6 @@  - + diff --git a/src/NServiceBus.Hosting.Windows/NServiceBus.Hosting.WindowsAnyCpu.csproj b/src/NServiceBus.Hosting.Windows/NServiceBus.Hosting.WindowsAnyCpu.csproj index d7fc792cfe2..e8698442f33 100644 --- a/src/NServiceBus.Hosting.Windows/NServiceBus.Hosting.WindowsAnyCpu.csproj +++ b/src/NServiceBus.Hosting.Windows/NServiceBus.Hosting.WindowsAnyCpu.csproj @@ -15,7 +15,7 @@ ..\NServiceBus.snk ..\ - d8262524 + d8c6b0dc False @@ -167,15 +167,15 @@ - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + + \ No newline at end of file diff --git a/src/NServiceBus.Hosting.Windows/NServiceBus.Hosting.WindowsX86.csproj b/src/NServiceBus.Hosting.Windows/NServiceBus.Hosting.WindowsX86.csproj index 9e4d57c6ad6..67c76ceaea7 100644 --- a/src/NServiceBus.Hosting.Windows/NServiceBus.Hosting.WindowsX86.csproj +++ b/src/NServiceBus.Hosting.Windows/NServiceBus.Hosting.WindowsX86.csproj @@ -166,15 +166,15 @@ - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + + \ No newline at end of file diff --git a/src/NServiceBus.Hosting.Windows/packages.config b/src/NServiceBus.Hosting.Windows/packages.config index 7a9c0491192..873b85e519a 100644 --- a/src/NServiceBus.Hosting.Windows/packages.config +++ b/src/NServiceBus.Hosting.Windows/packages.config @@ -1,7 +1,7 @@  - + diff --git a/src/NServiceBus.Testing/NServiceBus.Testing.csproj b/src/NServiceBus.Testing/NServiceBus.Testing.csproj index 472e091afb0..b2bdfdcb7f6 100644 --- a/src/NServiceBus.Testing/NServiceBus.Testing.csproj +++ b/src/NServiceBus.Testing/NServiceBus.Testing.csproj @@ -15,7 +15,7 @@ ..\NServiceBus.snk ..\ - 5dea9ded + 7898461d False @@ -87,15 +87,15 @@ - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + + \ No newline at end of file diff --git a/src/NServiceBus.Testing/packages.config b/src/NServiceBus.Testing/packages.config index 93e068568ac..1cd8eca29d9 100644 --- a/src/NServiceBus.Testing/packages.config +++ b/src/NServiceBus.Testing/packages.config @@ -1,6 +1,6 @@  - + From d2256509abd20c5af99719627347bb54c98ffecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Weronika=20=C5=81abaj?= Date: Wed, 30 Sep 2015 08:52:02 +0200 Subject: [PATCH 2/8] Fix the timeout dispatch bug. Add tests (adapted from v4). --- .../NServiceBus.AcceptanceTests.csproj | 12 ++ ...hing_deferred_message_fails_without_dtc.cs | 117 +++++++++++ .../Timeouts/OutdatedTimeoutPersister.cs | 30 +++ .../Timeouts/TransportWithFakeQueues.cs | 51 +++++ .../Timeouts/UpdatedTimeoutPersister.cs | 40 ++++ ...ut_already_removed_from_timeout_storage.cs | 187 ++++++++++++++++++ ...utdated_sql_transport_with_disabled_dtc.cs | 79 ++++++++ ...nt_uses_outdated_sql_transport_with_dtc.cs | 59 ++++++ ...d_timeout_persistence_with_disabled_dtc.cs | 69 +++++++ ...s_outdated_timeout_persistence_with_dtc.cs | 49 +++++ ...utdated_timeout_persistence_without_dtc.cs | 61 ++++++ ...updated_sql_transport_with_disabled_dtc.cs | 67 +++++++ ...dpoint_uses_updated_timeout_persistence.cs | 49 +++++ src/NServiceBus.Core/NServiceBus.Core.csproj | 2 + .../InMemoryTimeoutPersister.cs | 16 +- .../Timeout/Core/IPersistTimeoutsV2.cs | 22 +++ .../Core/TimeoutPersistenceVersionCheck.cs | 146 ++++++++++++++ .../Windows/TimeoutDispatcherProcessor.cs | 33 +++- .../Windows/TimeoutMessageProcessor.cs | 2 +- .../Transports/Msmq/MsmqMessageSender.cs | 11 +- 20 files changed, 1095 insertions(+), 7 deletions(-) create mode 100644 src/NServiceBus.AcceptanceTests/NonDTC/When_dispatching_deferred_message_fails_without_dtc.cs create mode 100644 src/NServiceBus.AcceptanceTests/Timeouts/OutdatedTimeoutPersister.cs create mode 100644 src/NServiceBus.AcceptanceTests/Timeouts/TransportWithFakeQueues.cs create mode 100644 src/NServiceBus.AcceptanceTests/Timeouts/UpdatedTimeoutPersister.cs create mode 100644 src/NServiceBus.AcceptanceTests/Timeouts/When_dispatched_timeout_already_removed_from_timeout_storage.cs create mode 100644 src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_sql_transport_with_disabled_dtc.cs create mode 100644 src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_sql_transport_with_dtc.cs create mode 100644 src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_timeout_persistence_with_disabled_dtc.cs create mode 100644 src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_timeout_persistence_with_dtc.cs create mode 100644 src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_timeout_persistence_without_dtc.cs create mode 100644 src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_updated_sql_transport_with_disabled_dtc.cs create mode 100644 src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_updated_timeout_persistence.cs create mode 100644 src/NServiceBus.Core/Timeout/Core/IPersistTimeoutsV2.cs create mode 100644 src/NServiceBus.Core/Timeout/Core/TimeoutPersistenceVersionCheck.cs diff --git a/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj b/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj index a6b4c924f7f..3f55ad20092 100644 --- a/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj +++ b/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj @@ -73,7 +73,19 @@ + + + + + + + + + + + + diff --git a/src/NServiceBus.AcceptanceTests/NonDTC/When_dispatching_deferred_message_fails_without_dtc.cs b/src/NServiceBus.AcceptanceTests/NonDTC/When_dispatching_deferred_message_fails_without_dtc.cs new file mode 100644 index 00000000000..52a51cfbf34 --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/NonDTC/When_dispatching_deferred_message_fails_without_dtc.cs @@ -0,0 +1,117 @@ +namespace NServiceBus.AcceptanceTests.NonDTC +{ + using System; + using NServiceBus.AcceptanceTesting; + using NServiceBus.AcceptanceTests.EndpointTemplates; + using NServiceBus.Features; + using NServiceBus.ObjectBuilder; + using NServiceBus.Transports; + using NServiceBus.Unicast; + using NUnit.Framework; + + public class When_dispatching_deferred_message_fails_without_dtc : NServiceBusAcceptanceTest + { + [Test] + public void Message_should_be_received() + { + var context = new Context(); + Scenario.Define(context) + .WithEndpoint(b => b.Given((bus, c) => + { + bus.Defer(TimeSpan.FromSeconds(3), new MyMessage()); + })) + .AllowExceptions() + .Done(c => c.MessageReceivedByHandler) + .Run(); + + Assert.IsTrue(context.SendingMessageFailedOnce, "Sending message attempt should fail once."); + Assert.IsTrue(context.MessageReceivedByHandler, "Message should be sent and received by handler on second attempt."); + } + + public class Context : ScenarioContext + { + public bool MessageReceivedByHandler { get; set; } + public bool SendingMessageFailedOnce { get; set; } + } + + public class TimeoutHandlingEndpoint : EndpointConfigurationBuilder + { + public TimeoutHandlingEndpoint() + { + EndpointSetup(config => + { + config.EnableFeature(); + config.Transactions().DisableDistributedTransactions(); + }); + } + + public class DelayedMessageHandler : IHandleMessages + { + Context context; + + public DelayedMessageHandler(Context context) + { + this.context = context; + } + + public void Handle(MyMessage message) + { + context.MessageReceivedByHandler = true; + } + } + + public class EndpointConfiguration : IWantToRunBeforeConfigurationIsFinalized + { + public static IBuilder builder; + + public void Run(Configure config) + { + builder = config.Builder; + } + } + + public class DispatcherInterceptor : Feature + { + public DispatcherInterceptor() + { + EnableByDefault(); + DependsOn(); + } + + protected override void Setup(FeatureConfigurationContext context) + { + var originalDispatcher = EndpointConfiguration.builder.Build(); + var ctx = EndpointConfiguration.builder.Build(); + context.Container.ConfigureComponent(() => new SenderWrapper(originalDispatcher, ctx), DependencyLifecycle.SingleInstance); + } + } + + class SenderWrapper : ISendMessages + { + ISendMessages wrappedSender; + Context context; + + public SenderWrapper(ISendMessages wrappedSender, Context context) + { + this.wrappedSender = wrappedSender; + this.context = context; + } + + public void Send(TransportMessage message, SendOptions sendOptions) + { + string relatedTimeoutId; + if (message.Headers.TryGetValue("NServiceBus.RelatedToTimeoutId", out relatedTimeoutId) && !context.SendingMessageFailedOnce) + { + context.SendingMessageFailedOnce = true; + throw new Exception("simulated exception"); + } + + wrappedSender.Send(message, sendOptions); + } + } + } + + [Serializable] + public class MyMessage : IMessage { } + } +} diff --git a/src/NServiceBus.AcceptanceTests/Timeouts/OutdatedTimeoutPersister.cs b/src/NServiceBus.AcceptanceTests/Timeouts/OutdatedTimeoutPersister.cs new file mode 100644 index 00000000000..2f6b38d1811 --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/Timeouts/OutdatedTimeoutPersister.cs @@ -0,0 +1,30 @@ +namespace NServiceBus.AcceptanceTests.Timeouts +{ + using System; + using System.Collections.Generic; + using System.Linq; + using NServiceBus.Timeout.Core; + + class OutdatedTimeoutPersister : IPersistTimeouts + { + public IEnumerable> GetNextChunk(DateTime startSlice, out DateTime nextTimeToRunQuery) + { + nextTimeToRunQuery = DateTime.Now.AddYears(42); + return Enumerable.Empty>().ToList(); + } + + public void Add(TimeoutData timeout) + { + } + + public bool TryRemove(string timeoutId, out TimeoutData timeoutData) + { + timeoutData = null; + return false; + } + + public void RemoveTimeoutBy(Guid sagaId) + { + } + } +} diff --git a/src/NServiceBus.AcceptanceTests/Timeouts/TransportWithFakeQueues.cs b/src/NServiceBus.AcceptanceTests/Timeouts/TransportWithFakeQueues.cs new file mode 100644 index 00000000000..db78d1a8946 --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/Timeouts/TransportWithFakeQueues.cs @@ -0,0 +1,51 @@ + +namespace NServiceBus.AcceptanceTests.Timeouts +{ + using System; + using NServiceBus.Transports; + using NServiceBus.Unicast; + + public class TransportWithFakeQueues : TransportDefinition + { + protected override void Configure(BusConfiguration config) + { + config.RegisterComponents(c => c.ConfigureComponent(DependencyLifecycle.SingleInstance)); + config.RegisterComponents(c => c.ConfigureComponent(DependencyLifecycle.SingleInstance)); + config.RegisterComponents(c => c.ConfigureComponent(DependencyLifecycle.SingleInstance)); + } + } + + class FakeDequer : IDequeueMessages + { + + public void Init(Address address, Unicast.Transport.TransactionSettings transactionSettings, Func tryProcessMessage, Action endProcessMessage) + { + } + + public void Start(int maximumConcurrencyLevel) + { + + } + + public void Stop() + { + + } + } + + class FakeQueueCreator : ICreateQueues + { + public void CreateQueueIfNecessary(Address address, string account) + { + //no-op + } + } + + class FakeSender : ISendMessages + { + public void Send(TransportMessage message, SendOptions sendOptions) + { + + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/Timeouts/UpdatedTimeoutPersister.cs b/src/NServiceBus.AcceptanceTests/Timeouts/UpdatedTimeoutPersister.cs new file mode 100644 index 00000000000..1cc0eb8406b --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/Timeouts/UpdatedTimeoutPersister.cs @@ -0,0 +1,40 @@ +namespace NServiceBus.AcceptanceTests.Timeouts +{ + using System; + using System.Collections.Generic; + using System.Linq; + using NServiceBus.Timeout.Core; + + class UpdatedTimeoutPersister : IPersistTimeouts, IPersistTimeoutsV2 + { + public IEnumerable> GetNextChunk(DateTime startSlice, out DateTime nextTimeToRunQuery) + { + nextTimeToRunQuery = DateTime.Now.AddYears(42); + return Enumerable.Empty>().ToList(); + } + + public void Add(TimeoutData timeout) + { + } + + public bool TryRemove(string timeoutId, out TimeoutData timeoutData) + { + timeoutData = null; + return false; + } + + public void RemoveTimeoutBy(Guid sagaId) + { + } + + public TimeoutData Peek(string timeoutId) + { + return null; + } + + public bool TryRemove(string timeoutId) + { + return true; + } + } +} diff --git a/src/NServiceBus.AcceptanceTests/Timeouts/When_dispatched_timeout_already_removed_from_timeout_storage.cs b/src/NServiceBus.AcceptanceTests/Timeouts/When_dispatched_timeout_already_removed_from_timeout_storage.cs new file mode 100644 index 00000000000..5a2a2b72692 --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/Timeouts/When_dispatched_timeout_already_removed_from_timeout_storage.cs @@ -0,0 +1,187 @@ +namespace NServiceBus.AcceptanceTests.Timeouts +{ + using System; + using System.Collections.Generic; + using System.Transactions; + using NServiceBus.AcceptanceTesting; + using NServiceBus.AcceptanceTests.EndpointTemplates; + using NServiceBus.Features; + using NServiceBus.ObjectBuilder; + using NServiceBus.Timeout.Core; + using NUnit.Framework; + + public class When_timeout_already_removed : NServiceBusAcceptanceTest + { + [Test] + public void Should_rollback_and_not_deliver_timeout_when_using_dtc() + { + var context = new Context(); + + Scenario.Define(context) + .WithEndpoint(b => b + .CustomConfig(configure => configure.Transactions().EnableDistributedTransactions()) + .Given(bus => + { + bus.Defer(TimeSpan.FromSeconds(5), new MyMessage()); + })) + .Done(c => c.AttemptedToRemoveTimeout || c.MessageReceived) + .Run(); + + Assert.IsFalse(context.MessageReceived, "Message should not be delivered using dtc."); + Assert.AreEqual(2, context.NumberOfProcessingAttempts, "The rollback should cause a retry."); + Assert.IsTrue(context.AttemptedToRemoveTimeout); + } + + [Test] + public void Should_rollback_and_deliver_timeout_anyway_when_using_native_tx() + { + var context = new Context(); + + Scenario.Define(context) + .WithEndpoint(b => b + .CustomConfig(configure => configure.Transactions().DisableDistributedTransactions()) + .Given(bus => + { + bus.Defer(TimeSpan.FromSeconds(5), new MyMessage()); + })) + .Done(c => c.AttemptedToRemoveTimeout && c.MessageReceived) + .Run(); + + Assert.IsTrue(context.MessageReceived, "Message should be delivered although transaction was aborted."); + Assert.AreEqual(2, context.NumberOfProcessingAttempts, "The rollback should cause a retry."); + Assert.IsTrue(context.AttemptedToRemoveTimeout); + } + + [Test] + public void Should_deliver_timeout_anyway_when_using_no_tx() + { + var context = new Context(); + + Scenario.Define(context) + .WithEndpoint(b => b + .CustomConfig(configure => configure.Transactions().Disable()) + .Given(bus => + { + bus.Defer(TimeSpan.FromSeconds(5), new MyMessage()); + })) + .Done(c => c.AttemptedToRemoveTimeout && c.MessageReceived) + .Run(); + + Assert.IsTrue(context.MessageReceived, "Message should be delivered although timeout processing fails."); + Assert.AreEqual(1, context.NumberOfProcessingAttempts, "Should not retry without transactions enabled."); + Assert.IsTrue(context.AttemptedToRemoveTimeout); + } + + public class Context : ScenarioContext + { + public bool MessageReceived { get; set; } + public bool AttemptedToRemoveTimeout { get; set; } + public int NumberOfProcessingAttempts { get; set; } + } + + public class Endpoint : EndpointConfigurationBuilder + { + public Endpoint() + { + EndpointSetup(); + } + + public class DelayedMessageHandler : IHandleMessages + { + Context context; + + public DelayedMessageHandler(Context context) + { + this.context = context; + } + + public void Handle(MyMessage message) + { + context.MessageReceived = true; + } + } + + public class EndpointConfiguration : IWantToRunBeforeConfigurationIsFinalized + { + public static IBuilder builder; + + public void Run(Configure config) + { + builder = config.Builder; + } + } + + public class DispatcherInterceptor : Feature + { + public DispatcherInterceptor() + { + EnableByDefault(); + } + + protected override void Setup(FeatureConfigurationContext context) + { + var originalPersister = EndpointConfiguration.builder.Build(); + var ctx = EndpointConfiguration.builder.Build(); + context.Container.ConfigureComponent(() => new TimeoutPersistanceWrapper(originalPersister, originalPersister as IPersistTimeoutsV2, ctx), DependencyLifecycle.SingleInstance); + } + } + + class TimeoutPersistanceWrapper : IPersistTimeouts, IPersistTimeoutsV2 + { + IPersistTimeouts originalTimeoutPersister; + IPersistTimeoutsV2 originalTimeoutPersisterV2; + Context context; + + public TimeoutPersistanceWrapper(IPersistTimeouts originalTimeoutPersister, IPersistTimeoutsV2 originalTimeoutPersisterV2, Context context) + { + this.originalTimeoutPersister = originalTimeoutPersister; + this.originalTimeoutPersisterV2 = originalTimeoutPersisterV2; + this.context = context; + } + + public IEnumerable> GetNextChunk(DateTime startSlice, out DateTime nextTimeToRunQuery) + { + return originalTimeoutPersister.GetNextChunk(startSlice, out nextTimeToRunQuery); + } + + public void Add(TimeoutData timeout) + { + originalTimeoutPersister.Add(timeout); + } + + public bool TryRemove(string timeoutId, out TimeoutData timeoutData) + { + return originalTimeoutPersister.TryRemove(timeoutId, out timeoutData); + } + + public void RemoveTimeoutBy(Guid sagaId) + { + originalTimeoutPersister.RemoveTimeoutBy(sagaId); + } + + public TimeoutData Peek(string timeoutId) + { + context.NumberOfProcessingAttempts++; + return originalTimeoutPersisterV2.Peek(timeoutId); + } + + public bool TryRemove(string timeoutId) + { + context.AttemptedToRemoveTimeout = true; + + using (var tx = new TransactionScope(TransactionScopeOption.Suppress)) + { + // delete the timeout so it won't be available on retries + originalTimeoutPersisterV2.TryRemove(timeoutId); + tx.Complete(); + } + + return false; + } + } + } + + [Serializable] + public class MyMessage : IMessage { } + } +} diff --git a/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_sql_transport_with_disabled_dtc.cs b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_sql_transport_with_disabled_dtc.cs new file mode 100644 index 00000000000..a4c8aacbeb5 --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_sql_transport_with_disabled_dtc.cs @@ -0,0 +1,79 @@ + +namespace NServiceBus.AcceptanceTests.Timeouts +{ + using System; + using NServiceBus.AcceptanceTesting; + using NServiceBus.AcceptanceTesting.Support; + using NServiceBus.AcceptanceTests.EndpointTemplates; + using NServiceBus.Features; + using NServiceBus.Timeout.Core; + using NUnit.Framework; + + public class When_endpoint_uses_outdated_sql_transport_with_disabled_dtc : NServiceBusAcceptanceTest + { + [Test] + public void Endpoint_should_not_start_and_show_warning() + { + var context = new Context(); + var scenarioException = Assert.Throws(() => Scenario.Define(context) + .WithEndpoint() + .Done(c => c.EndpointsStarted) + .Run()) + .InnerException as ScenarioException; + + Assert.IsFalse(context.EndpointsStarted); + StringAssert.Contains("You are using an outdated transport which can lead to message loss!", scenarioException.InnerException.Message); + } + + [Test] + public void Endpoint_should_start_when_warning_suppressed() + { + var context = new Context(); + + Scenario.Define(context) + .WithEndpoint(c => c + .CustomConfig(configure => configure.SuppressOutdatedTransportWarning())) + .Done(c => c.EndpointsStarted) + .Run(); + + Assert.IsTrue(context.EndpointsStarted); + } + + public class Context : ScenarioContext { } + + public class Endpoint : EndpointConfigurationBuilder + { + public Endpoint() + { + EndpointSetup(config => + { + config.EnableFeature(); + config.Transactions().DisableDistributedTransactions(); + config.UseTransport(); + }); + } + } + + public class Initalizer : Feature + { + public Initalizer() + { + EnableByDefault(); + } + + protected override void Setup(FeatureConfigurationContext context) + { + context.Container.ConfigureComponent(DependencyLifecycle.SingleInstance); + } + } + + public class OutdatedSqlServerTransport : TransportWithFakeQueues + { + // needs to contain SqlServer in the name + public OutdatedSqlServerTransport() + { + HasSupportForDistributedTransactions = true; + } + } + } +} diff --git a/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_sql_transport_with_dtc.cs b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_sql_transport_with_dtc.cs new file mode 100644 index 00000000000..0c624db391b --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_sql_transport_with_dtc.cs @@ -0,0 +1,59 @@ +namespace NServiceBus.AcceptanceTests.Timeouts +{ + using NServiceBus.AcceptanceTesting; + using NServiceBus.AcceptanceTests.EndpointTemplates; + using NServiceBus.Features; + using NUnit.Framework; + + public class When_endpoint_uses_outdated_sql_transport_with_dtc : NServiceBusAcceptanceTest + { + [Test] + public void Endpoint_should_start() + { + var context = new Context(); + Scenario.Define(context) + .WithEndpoint() + .Done(c => c.EndpointsStarted) + .Run(); + + Assert.IsTrue(context.EndpointsStarted); + } + + public class Context : ScenarioContext { } + + public class Endpoint : EndpointConfigurationBuilder + { + public Endpoint() + { + EndpointSetup(config => + { + config.EnableFeature(); + config.Transactions().EnableDistributedTransactions(); + config.UseTransport(); + }); + } + } + + public class OutdatedSqlServerTransport : TransportWithFakeQueues + { + // needs to contain SqlServer in the name + public OutdatedSqlServerTransport() + { + HasSupportForDistributedTransactions = true; + } + } + + public class Initalizer : Feature + { + public Initalizer() + { + EnableByDefault(); + } + + protected override void Setup(FeatureConfigurationContext context) + { + context.Container.ConfigureComponent(DependencyLifecycle.SingleInstance); + } + } + } +} diff --git a/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_timeout_persistence_with_disabled_dtc.cs b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_timeout_persistence_with_disabled_dtc.cs new file mode 100644 index 00000000000..e4a7cc1f348 --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_timeout_persistence_with_disabled_dtc.cs @@ -0,0 +1,69 @@ +namespace NServiceBus.AcceptanceTests.Timeouts +{ + using System; + using NServiceBus.AcceptanceTesting; + using NServiceBus.AcceptanceTesting.Support; + using NServiceBus.AcceptanceTests.EndpointTemplates; + using NServiceBus.Features; + using NServiceBus.Timeout.Core; + using NUnit.Framework; + + class When_endpoint_uses_outdated_timeout_persistence_with_disabled_dtc : NServiceBusAcceptanceTest + { + [Test] + public void Endpoint_should_not_start_and_show_warning() + { + var context = new Context(); + var scenarioException = Assert.Throws(() => Scenario.Define(context) + .WithEndpoint() + .Done(c => c.EndpointsStarted) + .Run()) + .InnerException as ScenarioException; + + Assert.IsFalse(context.EndpointsStarted); + Assert.IsNotNull(scenarioException); + StringAssert.Contains("You are using an outdated timeout persistence which can lead to message loss!", scenarioException.InnerException.Message); + } + + [Test] + public void Endpoint_should_start_when_warning_suppressed() + { + var context = new Context(); + + Scenario.Define(context) + .WithEndpoint(c => c.CustomConfig(b => b.SuppressOutdatedTimeoutPersistenceWarning())) + .Done(c => c.EndpointsStarted) + .Run(); + + Assert.IsTrue(context.EndpointsStarted); + } + + + public class Context : ScenarioContext { } + + public class Endpoint : EndpointConfigurationBuilder + { + public Endpoint() + { + EndpointSetup(config => + { + config.EnableFeature(); + config.Transactions().DisableDistributedTransactions(); + }); + } + } + + public class Initalizer : Feature + { + public Initalizer() + { + EnableByDefault(); + } + + protected override void Setup(FeatureConfigurationContext context) + { + context.Container.ConfigureComponent(DependencyLifecycle.SingleInstance); + } + } + } +} diff --git a/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_timeout_persistence_with_dtc.cs b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_timeout_persistence_with_dtc.cs new file mode 100644 index 00000000000..9032ef7474d --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_timeout_persistence_with_dtc.cs @@ -0,0 +1,49 @@ +namespace NServiceBus.AcceptanceTests.Timeouts +{ + using NServiceBus.AcceptanceTesting; + using NServiceBus.AcceptanceTests.EndpointTemplates; + using NServiceBus.Features; + using NUnit.Framework; + + public class When_endpoint_uses_outdated_timeout_persistence_with_dtc : NServiceBusAcceptanceTest + { + [Test] + public void Endpoint_should_start() + { + var context = new Context(); + Scenario.Define(context) + .WithEndpoint() + .Done(c => c.EndpointsStarted) + .Run(); + + Assert.IsTrue(context.EndpointsStarted); + } + + public class Context : ScenarioContext { } + + public class Endpoint : EndpointConfigurationBuilder + { + public Endpoint() + { + EndpointSetup(config => + { + config.EnableFeature(); + config.Transactions().EnableDistributedTransactions(); + }); + } + } + + public class Initalizer : Feature + { + public Initalizer() + { + EnableByDefault(); + } + + protected override void Setup(FeatureConfigurationContext context) + { + context.Container.ConfigureComponent(DependencyLifecycle.SingleInstance); + } + } + } +} diff --git a/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_timeout_persistence_without_dtc.cs b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_timeout_persistence_without_dtc.cs new file mode 100644 index 00000000000..c60299f18be --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_timeout_persistence_without_dtc.cs @@ -0,0 +1,61 @@ +namespace NServiceBus.AcceptanceTests.Timeouts +{ + using System; + using NServiceBus.AcceptanceTesting; + using NServiceBus.AcceptanceTesting.Support; + using NServiceBus.AcceptanceTests.EndpointTemplates; + using NServiceBus.Features; + using NUnit.Framework; + + public class When_endpoint_uses_outdated_timeout_persistence_without_dtc + { + [Test] + public void Endpoint_should_not_start_and_show_warning() + { + var context = new Context(); + var scenarioException = Assert.Throws(() => Scenario.Define(context) + .WithEndpoint() + .Done(c => c.EndpointsStarted) + .Run()) + .InnerException as ScenarioException; + + Assert.IsFalse(context.EndpointsStarted); + Assert.IsNotNull(scenarioException); + StringAssert.Contains("You are using an outdated timeout persistence which can lead to message loss!", scenarioException.InnerException.Message); + } + + public class Context : ScenarioContext { } + + public class Endpoint : EndpointConfigurationBuilder + { + public Endpoint() + { + EndpointSetup(config => + { + config.EnableFeature(); + config.UseTransport(); + }); + } + } + public class Initalizer : Feature + { + public Initalizer() + { + EnableByDefault(); + } + + protected override void Setup(FeatureConfigurationContext context) + { + context.Container.ConfigureComponent(() => new OutdatedTimeoutPersister(), DependencyLifecycle.SingleInstance); + } + } + + public class NonDtcTransportDefinition : TransportWithFakeQueues + { + public NonDtcTransportDefinition() + { + HasSupportForDistributedTransactions = false; + } + } + } +} diff --git a/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_updated_sql_transport_with_disabled_dtc.cs b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_updated_sql_transport_with_disabled_dtc.cs new file mode 100644 index 00000000000..3f1c0f3d570 --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_updated_sql_transport_with_disabled_dtc.cs @@ -0,0 +1,67 @@ +namespace NServiceBus.AcceptanceTests.Timeouts +{ + using NServiceBus.AcceptanceTesting; + using NServiceBus.AcceptanceTests.EndpointTemplates; + using NServiceBus.Features; + using NUnit.Framework; + + class When_endpoint_uses_updated_sql_transport_with_disabled_dtc : NServiceBusAcceptanceTest + { + [Test] + public void Endpoint_should_start() + { + var context = new Context(); + Scenario.Define(context) + .WithEndpoint() + .Done(c => c.EndpointsStarted) + .Run(); + + Assert.IsTrue(context.EndpointsStarted); + } + + public class Context : ScenarioContext { } + + public class Endpoint : EndpointConfigurationBuilder + { + public Endpoint() + { + EndpointSetup(config => + { + config.EnableFeature(); + config.Transactions().DisableDistributedTransactions(); + config.UseTransport(); + }); + } + } + + public class Initalizer : Feature + { + public Initalizer() + { + EnableByDefault(); + } + + protected override void Setup(FeatureConfigurationContext context) + { + context.Container.ConfigureComponent(DependencyLifecycle.SingleInstance); + } + } + + public class UpdatedSqlServerTransport : TransportWithFakeQueues + { + // needs to contain SqlServer in the name + public UpdatedSqlServerTransport() + { + HasSupportForDistributedTransactions = true; + } + + public class AddNewSqlServerTransportSetting : IWantToRunBeforeConfigurationIsFinalized + { + public void Run(Configure config) + { + config.Settings.Set("NServiceBus.Transport.SupportsNativeTransactionSuppression", true); + } + } + } + } +} diff --git a/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_updated_timeout_persistence.cs b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_updated_timeout_persistence.cs new file mode 100644 index 00000000000..cda8be2efbb --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_updated_timeout_persistence.cs @@ -0,0 +1,49 @@ +namespace NServiceBus.AcceptanceTests.Timeouts +{ + using NServiceBus.AcceptanceTesting; + using NServiceBus.AcceptanceTests.EndpointTemplates; + using NServiceBus.Features; + using NUnit.Framework; + + class When_endpoint_uses_updated_timeout_persistence : NServiceBusAcceptanceTest + { + [Test] + public void Endpoint_should_start() + { + var context = new Context(); + Scenario.Define(context) + .WithEndpoint() + .Done(c => c.EndpointsStarted) + .Run(); + + Assert.IsTrue(context.EndpointsStarted); + } + + public class Context : ScenarioContext { } + + public class Endpoint : EndpointConfigurationBuilder + { + public Endpoint() + { + EndpointSetup(config => + { + config.EnableFeature(); + config.Transactions().DisableDistributedTransactions(); + }); + } + } + + public class Initalizer : Feature + { + public Initalizer() + { + EnableByDefault(); + } + + protected override void Setup(FeatureConfigurationContext context) + { + context.Container.ConfigureComponent(DependencyLifecycle.SingleInstance); + } + } + } +} diff --git a/src/NServiceBus.Core/NServiceBus.Core.csproj b/src/NServiceBus.Core/NServiceBus.Core.csproj index 16091a2dd6a..b8daf058ff2 100644 --- a/src/NServiceBus.Core/NServiceBus.Core.csproj +++ b/src/NServiceBus.Core/NServiceBus.Core.csproj @@ -202,6 +202,8 @@ + + diff --git a/src/NServiceBus.Core/Persistence/InMemory/TimeoutPersister/InMemoryTimeoutPersister.cs b/src/NServiceBus.Core/Persistence/InMemory/TimeoutPersister/InMemoryTimeoutPersister.cs index 43494d85ed1..fa533d345a7 100644 --- a/src/NServiceBus.Core/Persistence/InMemory/TimeoutPersister/InMemoryTimeoutPersister.cs +++ b/src/NServiceBus.Core/Persistence/InMemory/TimeoutPersister/InMemoryTimeoutPersister.cs @@ -5,7 +5,7 @@ namespace NServiceBus.InMemory.TimeoutPersister using System.Linq; using Timeout.Core; - class InMemoryTimeoutPersister : IPersistTimeouts + class InMemoryTimeoutPersister : IPersistTimeouts, IPersistTimeoutsV2 { readonly IList storage = new List(); readonly object lockObject = new object(); @@ -56,5 +56,19 @@ public void RemoveTimeoutBy(Guid sagaId) storage.Where(t => t.SagaId == sagaId).ToList().ForEach(item => storage.Remove(item)); } } + + public TimeoutData Peek(string timeoutId) + { + lock (lockObject) + { + return storage.SingleOrDefault(t => t.Id == timeoutId); + } + } + + public bool TryRemove(string timeoutId) + { + TimeoutData timeoutData; + return TryRemove(timeoutId, out timeoutData); + } } } diff --git a/src/NServiceBus.Core/Timeout/Core/IPersistTimeoutsV2.cs b/src/NServiceBus.Core/Timeout/Core/IPersistTimeoutsV2.cs new file mode 100644 index 00000000000..e02088492a6 --- /dev/null +++ b/src/NServiceBus.Core/Timeout/Core/IPersistTimeoutsV2.cs @@ -0,0 +1,22 @@ +namespace NServiceBus.Timeout.Core +{ + /// + /// Timeout persister contract. + /// + public interface IPersistTimeoutsV2 + { + /// + /// Reads timeout data. + /// + /// The timeout id to read. + /// of the timeout if it was found. null otherwise. + TimeoutData Peek(string timeoutId); + + /// + /// Removes the timeout if it hasn't been previously removed. + /// + /// The timeout id to remove. + /// true if the timeout has been successfully removed or false if there was no timeout to remove. + bool TryRemove(string timeoutId); + } +} diff --git a/src/NServiceBus.Core/Timeout/Core/TimeoutPersistenceVersionCheck.cs b/src/NServiceBus.Core/Timeout/Core/TimeoutPersistenceVersionCheck.cs new file mode 100644 index 00000000000..5878ae67518 --- /dev/null +++ b/src/NServiceBus.Core/Timeout/Core/TimeoutPersistenceVersionCheck.cs @@ -0,0 +1,146 @@ +namespace NServiceBus.Timeout.Core +{ + using NServiceBus.Config; + using System; + using System.Configuration; + using NServiceBus.ObjectBuilder; + using NServiceBus.Settings; + using NServiceBus.Transports; + + /// + /// + /// + public static class TimeoutPersistenceVersionCheckExtension + { + /// + /// + /// + /// + /// + public static BusConfiguration SuppressOutdatedTimeoutPersistenceWarning(this BusConfiguration configure) + { + configure.Settings.Set(TimeoutPersistenceVersionCheck.SuppressOutdatedTimeoutPersistenceWarning, true); + return configure; + } + + /// + /// + /// + /// + /// + public static BusConfiguration SuppressOutdatedTransportWarning(this BusConfiguration configure) + { + configure.Settings.Set(TimeoutPersistenceVersionCheck.SuppressOutdatedTransportWarning, true); + return configure; + } + } + + internal class TimeoutPersistenceVersionCheck : IWantToRunWhenConfigurationIsComplete + { + internal const string SuppressOutdatedTimeoutPersistenceWarning = "NServiceBus/suppress-outdated-timeout-persistence-warning"; + internal const string SuppressOutdatedTransportWarning = "NServiceBus/suppress-outdated-persistence-warning"; + + readonly IBuilder builder; + internal SettingsHolder settingsHolder; + + public TimeoutPersistenceVersionCheck(IBuilder builder) + { + this.builder = builder; + } + + public void Run(Configure config) + { + settingsHolder = config.Settings; + var suppressDtc = settingsHolder.Get("Transactions.SuppressDistributedTransactions"); + if (IsTransportSupportingDtc() && !suppressDtc) + { + // there is no issue with the timeout persistence when using dtc + return; + } + + var timeoutPersister = TryResolveTimeoutPersister(); + if (timeoutPersister == null) + { + // no timeouts used + return; + } + + if (!(timeoutPersister is IPersistTimeoutsV2) && !UserSuppressedTimeoutPersistenceWarning()) + { + throw new Exception("You are using an outdated timeout persistence which can lead to message loss! Please update the configured timeout persistence. You can suppress this warning by configuring your bus using 'config.SuppressOutdatedTimeoutPersistenceWarning()' or by adding 'NServiceBus/suppress-outdated-timeout-persistence-warning' with value 'true' to the appSettings section of your application configuration file."); + } + + if (TransactionalTransportMissesNativeTxSuppression() && !UserSuppressedTransportWarning()) + { + throw new Exception("You are using an outdated transport which can lead to message loss! Please update the configured transport. You can suppress this warning by configuring your bus using 'config.SuppressOutdatedTransportWarning()' or by adding 'NServiceBus/suppress-outdated-transport-warning' with value 'true' to the appSettings section of your application configuration file."); + } + } + + bool TransactionalTransportMissesNativeTxSuppression() + { + // transports allowing native cross-queue transactions (without dtc) need to support sending messages suppressing an active transaction + // this currently only affects SqlServer transport since only MSMQ and SqlServer transports support this scenario whereas MSMQ already supports the suppresion. + + var selectedTransport = settingsHolder.GetOrDefault("NServiceBus.Transports.TransportDefinition"); + return selectedTransport.GetType().Name.Contains("SqlServer") && !settingsHolder.GetOrDefault("NServiceBus.Transport.SupportsNativeTransactionSuppression"); + } + + IPersistTimeouts TryResolveTimeoutPersister() + { + IPersistTimeouts timeoutPersister = null; + try + { + timeoutPersister = builder.Build(); + } + catch (Exception) + { + // catch potential DI exception when interface not registered. + } + + return timeoutPersister; + } + + bool UserSuppressedTimeoutPersistenceWarning() + { + if (settingsHolder.HasSetting(SuppressOutdatedTimeoutPersistenceWarning)) + { + return settingsHolder.GetOrDefault(SuppressOutdatedTimeoutPersistenceWarning); + } + + var appSetting = ConfigurationManager.AppSettings[SuppressOutdatedTimeoutPersistenceWarning]; + if (appSetting != null) + { + return bool.Parse(appSetting); + } + + return false; + } + + bool UserSuppressedTransportWarning() + { + if (settingsHolder.HasSetting(SuppressOutdatedTransportWarning)) + { + return settingsHolder.GetOrDefault(SuppressOutdatedTransportWarning); + } + + var appSetting = ConfigurationManager.AppSettings[SuppressOutdatedTransportWarning]; + if (appSetting != null) + { + return bool.Parse(appSetting); + } + + return false; + } + + bool IsTransportSupportingDtc() + { + var selectedTransport = settingsHolder.GetOrDefault("NServiceBus.Transports.TransportDefinition"); + if (selectedTransport.HasSupportForDistributedTransactions.HasValue) + { + return selectedTransport.HasSupportForDistributedTransactions.Value; + } + + return !selectedTransport.GetType().Name.Contains("RabbitMQ"); + } + } +} diff --git a/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutDispatcherProcessor.cs b/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutDispatcherProcessor.cs index 97d0d4d8490..a4fedc095db 100644 --- a/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutDispatcherProcessor.cs +++ b/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutDispatcherProcessor.cs @@ -2,6 +2,7 @@ namespace NServiceBus.Timeout.Hosting.Windows { using System; using Core; + using NServiceBus.Pipeline; using Satellites; using Transports; using Unicast.Transport; @@ -19,6 +20,8 @@ public TimeoutDispatcherProcessor() public TimeoutPersisterReceiver TimeoutPersisterReceiver { get; set; } + public PipelineExecutor PipelineExecutor { get; set; } + public Configure Configure { get; set; } public Address InputAddress { get; set; } @@ -28,11 +31,35 @@ public TimeoutDispatcherProcessor() public bool Handle(TransportMessage message) { var timeoutId = message.Headers["Timeout.Id"]; - TimeoutData timeoutData; - if (TimeoutsPersister.TryRemove(timeoutId, out timeoutData)) + var persisterV2 = TimeoutsPersister as IPersistTimeoutsV2; + if (persisterV2 != null) + { + var timeoutData = persisterV2.Peek(timeoutId); + if (timeoutData == null) + { + return true; + } + + try + { + PipelineExecutor.CurrentContext.Set("do-not-enlist-in-native-transaction", true); + MessageSender.Send(timeoutData.ToTransportMessage(), timeoutData.ToSendOptions(Configure.LocalAddress)); + } + finally + { + PipelineExecutor.CurrentContext.Set("do-not-enlist-in-native-transaction", false); + } + + return persisterV2.TryRemove(timeoutId); + } + else { - MessageSender.Send(timeoutData.ToTransportMessage(), timeoutData.ToSendOptions(Configure.LocalAddress)); + TimeoutData timeoutData; + if (TimeoutsPersister.TryRemove(timeoutId, out timeoutData)) + { + MessageSender.Send(timeoutData.ToTransportMessage(), timeoutData.ToSendOptions(Configure.LocalAddress)); + } } return true; diff --git a/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutMessageProcessor.cs b/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutMessageProcessor.cs index 214f599d46f..0016e00402d 100644 --- a/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutMessageProcessor.cs +++ b/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutMessageProcessor.cs @@ -76,8 +76,8 @@ void HandleBackwardsCompatibility(TransportMessage message) destination = Address.Parse(routeExpiredTimeoutTo); } - TimeoutManager.RemoveTimeout(timeoutId); MessageSender.Send(message, new SendOptions(destination)); + TimeoutManager.RemoveTimeout(timeoutId); } void HandleInternal(TransportMessage message) diff --git a/src/NServiceBus.Core/Transports/Msmq/MsmqMessageSender.cs b/src/NServiceBus.Core/Transports/Msmq/MsmqMessageSender.cs index 176bf758469..3df349dc39c 100644 --- a/src/NServiceBus.Core/Transports/Msmq/MsmqMessageSender.cs +++ b/src/NServiceBus.Core/Transports/Msmq/MsmqMessageSender.cs @@ -4,6 +4,7 @@ namespace NServiceBus.Transports.Msmq using System.Messaging; using System.Transactions; using Config; + using NServiceBus.Pipeline; using Unicast; using Unicast.Queuing; @@ -22,6 +23,11 @@ public class MsmqMessageSender : ISendMessages /// public MsmqUnitOfWork UnitOfWork { get; set; } + /// + /// PipelineExecutor + /// + public PipelineExecutor PipelineExecutor { get; set; } + /// /// SuppressDistributedTransactions /// @@ -50,8 +56,9 @@ public void Send(TransportMessage message, SendOptions sendOptions) toSend.ResponseQueue = new MessageQueue(NServiceBus.MsmqUtilities.GetReturnAddress(replyToAddress.ToString(), address.ToString())); } - - if (sendOptions.EnlistInReceiveTransaction && UnitOfWork.HasActiveTransaction()) + bool suppressNativeTransactions; + PipelineExecutor.CurrentContext.TryGet("do-not-enlist-in-native-transaction", out suppressNativeTransactions); + if (sendOptions.EnlistInReceiveTransaction && UnitOfWork.HasActiveTransaction() && !suppressNativeTransactions) { q.Send(toSend, UnitOfWork.Transaction); } From b736a927565f44cdc91d872bbbd920b769fdd1e1 Mon Sep 17 00:00:00 2001 From: Tim Bussmann Date: Fri, 2 Oct 2015 17:18:54 +0200 Subject: [PATCH 3/8] using native transaction suppression mechanism of v5 --- .../NServiceBus.AcceptanceTests.csproj | 3 - .../Timeouts/TransportWithFakeQueues.cs | 8 +- ...utdated_sql_transport_with_disabled_dtc.cs | 79 ------------------- ...nt_uses_outdated_sql_transport_with_dtc.cs | 59 -------------- ...updated_sql_transport_with_disabled_dtc.cs | 67 ---------------- .../Core/TimeoutPersistenceVersionCheck.cs | 42 ---------- .../Windows/TimeoutDispatcherProcessor.cs | 33 ++++++-- .../Transports/Msmq/MsmqMessageSender.cs | 10 +-- 8 files changed, 29 insertions(+), 272 deletions(-) delete mode 100644 src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_sql_transport_with_disabled_dtc.cs delete mode 100644 src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_sql_transport_with_dtc.cs delete mode 100644 src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_updated_sql_transport_with_disabled_dtc.cs diff --git a/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj b/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj index 3f55ad20092..58229d94dfb 100644 --- a/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj +++ b/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj @@ -79,12 +79,9 @@ - - - diff --git a/src/NServiceBus.AcceptanceTests/Timeouts/TransportWithFakeQueues.cs b/src/NServiceBus.AcceptanceTests/Timeouts/TransportWithFakeQueues.cs index db78d1a8946..0f61edad0f9 100644 --- a/src/NServiceBus.AcceptanceTests/Timeouts/TransportWithFakeQueues.cs +++ b/src/NServiceBus.AcceptanceTests/Timeouts/TransportWithFakeQueues.cs @@ -9,13 +9,13 @@ public class TransportWithFakeQueues : TransportDefinition { protected override void Configure(BusConfiguration config) { - config.RegisterComponents(c => c.ConfigureComponent(DependencyLifecycle.SingleInstance)); + config.RegisterComponents(c => c.ConfigureComponent(DependencyLifecycle.SingleInstance)); config.RegisterComponents(c => c.ConfigureComponent(DependencyLifecycle.SingleInstance)); config.RegisterComponents(c => c.ConfigureComponent(DependencyLifecycle.SingleInstance)); } } - class FakeDequer : IDequeueMessages + class FakeDequeuer : IDequeueMessages { public void Init(Address address, Unicast.Transport.TransactionSettings transactionSettings, Func tryProcessMessage, Action endProcessMessage) @@ -24,12 +24,10 @@ public void Init(Address address, Unicast.Transport.TransactionSettings transact public void Start(int maximumConcurrencyLevel) { - } public void Stop() { - } } @@ -37,7 +35,6 @@ class FakeQueueCreator : ICreateQueues { public void CreateQueueIfNecessary(Address address, string account) { - //no-op } } @@ -45,7 +42,6 @@ class FakeSender : ISendMessages { public void Send(TransportMessage message, SendOptions sendOptions) { - } } } \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_sql_transport_with_disabled_dtc.cs b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_sql_transport_with_disabled_dtc.cs deleted file mode 100644 index a4c8aacbeb5..00000000000 --- a/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_sql_transport_with_disabled_dtc.cs +++ /dev/null @@ -1,79 +0,0 @@ - -namespace NServiceBus.AcceptanceTests.Timeouts -{ - using System; - using NServiceBus.AcceptanceTesting; - using NServiceBus.AcceptanceTesting.Support; - using NServiceBus.AcceptanceTests.EndpointTemplates; - using NServiceBus.Features; - using NServiceBus.Timeout.Core; - using NUnit.Framework; - - public class When_endpoint_uses_outdated_sql_transport_with_disabled_dtc : NServiceBusAcceptanceTest - { - [Test] - public void Endpoint_should_not_start_and_show_warning() - { - var context = new Context(); - var scenarioException = Assert.Throws(() => Scenario.Define(context) - .WithEndpoint() - .Done(c => c.EndpointsStarted) - .Run()) - .InnerException as ScenarioException; - - Assert.IsFalse(context.EndpointsStarted); - StringAssert.Contains("You are using an outdated transport which can lead to message loss!", scenarioException.InnerException.Message); - } - - [Test] - public void Endpoint_should_start_when_warning_suppressed() - { - var context = new Context(); - - Scenario.Define(context) - .WithEndpoint(c => c - .CustomConfig(configure => configure.SuppressOutdatedTransportWarning())) - .Done(c => c.EndpointsStarted) - .Run(); - - Assert.IsTrue(context.EndpointsStarted); - } - - public class Context : ScenarioContext { } - - public class Endpoint : EndpointConfigurationBuilder - { - public Endpoint() - { - EndpointSetup(config => - { - config.EnableFeature(); - config.Transactions().DisableDistributedTransactions(); - config.UseTransport(); - }); - } - } - - public class Initalizer : Feature - { - public Initalizer() - { - EnableByDefault(); - } - - protected override void Setup(FeatureConfigurationContext context) - { - context.Container.ConfigureComponent(DependencyLifecycle.SingleInstance); - } - } - - public class OutdatedSqlServerTransport : TransportWithFakeQueues - { - // needs to contain SqlServer in the name - public OutdatedSqlServerTransport() - { - HasSupportForDistributedTransactions = true; - } - } - } -} diff --git a/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_sql_transport_with_dtc.cs b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_sql_transport_with_dtc.cs deleted file mode 100644 index 0c624db391b..00000000000 --- a/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_outdated_sql_transport_with_dtc.cs +++ /dev/null @@ -1,59 +0,0 @@ -namespace NServiceBus.AcceptanceTests.Timeouts -{ - using NServiceBus.AcceptanceTesting; - using NServiceBus.AcceptanceTests.EndpointTemplates; - using NServiceBus.Features; - using NUnit.Framework; - - public class When_endpoint_uses_outdated_sql_transport_with_dtc : NServiceBusAcceptanceTest - { - [Test] - public void Endpoint_should_start() - { - var context = new Context(); - Scenario.Define(context) - .WithEndpoint() - .Done(c => c.EndpointsStarted) - .Run(); - - Assert.IsTrue(context.EndpointsStarted); - } - - public class Context : ScenarioContext { } - - public class Endpoint : EndpointConfigurationBuilder - { - public Endpoint() - { - EndpointSetup(config => - { - config.EnableFeature(); - config.Transactions().EnableDistributedTransactions(); - config.UseTransport(); - }); - } - } - - public class OutdatedSqlServerTransport : TransportWithFakeQueues - { - // needs to contain SqlServer in the name - public OutdatedSqlServerTransport() - { - HasSupportForDistributedTransactions = true; - } - } - - public class Initalizer : Feature - { - public Initalizer() - { - EnableByDefault(); - } - - protected override void Setup(FeatureConfigurationContext context) - { - context.Container.ConfigureComponent(DependencyLifecycle.SingleInstance); - } - } - } -} diff --git a/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_updated_sql_transport_with_disabled_dtc.cs b/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_updated_sql_transport_with_disabled_dtc.cs deleted file mode 100644 index 3f1c0f3d570..00000000000 --- a/src/NServiceBus.AcceptanceTests/Timeouts/When_endpoint_uses_updated_sql_transport_with_disabled_dtc.cs +++ /dev/null @@ -1,67 +0,0 @@ -namespace NServiceBus.AcceptanceTests.Timeouts -{ - using NServiceBus.AcceptanceTesting; - using NServiceBus.AcceptanceTests.EndpointTemplates; - using NServiceBus.Features; - using NUnit.Framework; - - class When_endpoint_uses_updated_sql_transport_with_disabled_dtc : NServiceBusAcceptanceTest - { - [Test] - public void Endpoint_should_start() - { - var context = new Context(); - Scenario.Define(context) - .WithEndpoint() - .Done(c => c.EndpointsStarted) - .Run(); - - Assert.IsTrue(context.EndpointsStarted); - } - - public class Context : ScenarioContext { } - - public class Endpoint : EndpointConfigurationBuilder - { - public Endpoint() - { - EndpointSetup(config => - { - config.EnableFeature(); - config.Transactions().DisableDistributedTransactions(); - config.UseTransport(); - }); - } - } - - public class Initalizer : Feature - { - public Initalizer() - { - EnableByDefault(); - } - - protected override void Setup(FeatureConfigurationContext context) - { - context.Container.ConfigureComponent(DependencyLifecycle.SingleInstance); - } - } - - public class UpdatedSqlServerTransport : TransportWithFakeQueues - { - // needs to contain SqlServer in the name - public UpdatedSqlServerTransport() - { - HasSupportForDistributedTransactions = true; - } - - public class AddNewSqlServerTransportSetting : IWantToRunBeforeConfigurationIsFinalized - { - public void Run(Configure config) - { - config.Settings.Set("NServiceBus.Transport.SupportsNativeTransactionSuppression", true); - } - } - } - } -} diff --git a/src/NServiceBus.Core/Timeout/Core/TimeoutPersistenceVersionCheck.cs b/src/NServiceBus.Core/Timeout/Core/TimeoutPersistenceVersionCheck.cs index 5878ae67518..49d8154bcd1 100644 --- a/src/NServiceBus.Core/Timeout/Core/TimeoutPersistenceVersionCheck.cs +++ b/src/NServiceBus.Core/Timeout/Core/TimeoutPersistenceVersionCheck.cs @@ -22,23 +22,11 @@ public static BusConfiguration SuppressOutdatedTimeoutPersistenceWarning(this Bu configure.Settings.Set(TimeoutPersistenceVersionCheck.SuppressOutdatedTimeoutPersistenceWarning, true); return configure; } - - /// - /// - /// - /// - /// - public static BusConfiguration SuppressOutdatedTransportWarning(this BusConfiguration configure) - { - configure.Settings.Set(TimeoutPersistenceVersionCheck.SuppressOutdatedTransportWarning, true); - return configure; - } } internal class TimeoutPersistenceVersionCheck : IWantToRunWhenConfigurationIsComplete { internal const string SuppressOutdatedTimeoutPersistenceWarning = "NServiceBus/suppress-outdated-timeout-persistence-warning"; - internal const string SuppressOutdatedTransportWarning = "NServiceBus/suppress-outdated-persistence-warning"; readonly IBuilder builder; internal SettingsHolder settingsHolder; @@ -69,20 +57,6 @@ public void Run(Configure config) { throw new Exception("You are using an outdated timeout persistence which can lead to message loss! Please update the configured timeout persistence. You can suppress this warning by configuring your bus using 'config.SuppressOutdatedTimeoutPersistenceWarning()' or by adding 'NServiceBus/suppress-outdated-timeout-persistence-warning' with value 'true' to the appSettings section of your application configuration file."); } - - if (TransactionalTransportMissesNativeTxSuppression() && !UserSuppressedTransportWarning()) - { - throw new Exception("You are using an outdated transport which can lead to message loss! Please update the configured transport. You can suppress this warning by configuring your bus using 'config.SuppressOutdatedTransportWarning()' or by adding 'NServiceBus/suppress-outdated-transport-warning' with value 'true' to the appSettings section of your application configuration file."); - } - } - - bool TransactionalTransportMissesNativeTxSuppression() - { - // transports allowing native cross-queue transactions (without dtc) need to support sending messages suppressing an active transaction - // this currently only affects SqlServer transport since only MSMQ and SqlServer transports support this scenario whereas MSMQ already supports the suppresion. - - var selectedTransport = settingsHolder.GetOrDefault("NServiceBus.Transports.TransportDefinition"); - return selectedTransport.GetType().Name.Contains("SqlServer") && !settingsHolder.GetOrDefault("NServiceBus.Transport.SupportsNativeTransactionSuppression"); } IPersistTimeouts TryResolveTimeoutPersister() @@ -116,22 +90,6 @@ bool UserSuppressedTimeoutPersistenceWarning() return false; } - bool UserSuppressedTransportWarning() - { - if (settingsHolder.HasSetting(SuppressOutdatedTransportWarning)) - { - return settingsHolder.GetOrDefault(SuppressOutdatedTransportWarning); - } - - var appSetting = ConfigurationManager.AppSettings[SuppressOutdatedTransportWarning]; - if (appSetting != null) - { - return bool.Parse(appSetting); - } - - return false; - } - bool IsTransportSupportingDtc() { var selectedTransport = settingsHolder.GetOrDefault("NServiceBus.Transports.TransportDefinition"); diff --git a/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutDispatcherProcessor.cs b/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutDispatcherProcessor.cs index a4fedc095db..673e44d115e 100644 --- a/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutDispatcherProcessor.cs +++ b/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutDispatcherProcessor.cs @@ -3,6 +3,7 @@ namespace NServiceBus.Timeout.Hosting.Windows using System; using Core; using NServiceBus.Pipeline; + using NServiceBus.Settings; using Satellites; using Transports; using Unicast.Transport; @@ -26,6 +27,8 @@ public TimeoutDispatcherProcessor() public Address InputAddress { get; set; } + public ReadOnlySettings Settings { get; set; } + public bool Disabled { get; set; } public bool Handle(TransportMessage message) @@ -41,16 +44,15 @@ public bool Handle(TransportMessage message) return true; } - try - { - PipelineExecutor.CurrentContext.Set("do-not-enlist-in-native-transaction", true); - MessageSender.Send(timeoutData.ToTransportMessage(), timeoutData.ToSendOptions(Configure.LocalAddress)); - } - finally + var sendOptions = timeoutData.ToSendOptions(Configure.LocalAddress); + + if (ShouldSuppressTransaction()) { - PipelineExecutor.CurrentContext.Set("do-not-enlist-in-native-transaction", false); + sendOptions.EnlistInReceiveTransaction = false; } + MessageSender.Send(timeoutData.ToTransportMessage(), sendOptions); + return persisterV2.TryRemove(timeoutId); } else @@ -84,5 +86,22 @@ public Action GetReceiverCustomization() receiver.FailureManager = new ManageMessageFailuresWithoutSlr(receiver.FailureManager, MessageSender, Configure); }; } + + bool ShouldSuppressTransaction() + { + var suppressDtc = Settings.Get("Transactions.SuppressDistributedTransactions"); + return !IsTransportSupportingDtc() || suppressDtc; + } + + bool IsTransportSupportingDtc() + { + var selectedTransport = Settings.GetOrDefault("NServiceBus.Transports.TransportDefinition"); + if (selectedTransport.HasSupportForDistributedTransactions.HasValue) + { + return selectedTransport.HasSupportForDistributedTransactions.Value; + } + + return !selectedTransport.GetType().Name.Contains("RabbitMQ"); + } } } diff --git a/src/NServiceBus.Core/Transports/Msmq/MsmqMessageSender.cs b/src/NServiceBus.Core/Transports/Msmq/MsmqMessageSender.cs index 3df349dc39c..ba1422119dd 100644 --- a/src/NServiceBus.Core/Transports/Msmq/MsmqMessageSender.cs +++ b/src/NServiceBus.Core/Transports/Msmq/MsmqMessageSender.cs @@ -4,7 +4,6 @@ namespace NServiceBus.Transports.Msmq using System.Messaging; using System.Transactions; using Config; - using NServiceBus.Pipeline; using Unicast; using Unicast.Queuing; @@ -23,11 +22,6 @@ public class MsmqMessageSender : ISendMessages /// public MsmqUnitOfWork UnitOfWork { get; set; } - /// - /// PipelineExecutor - /// - public PipelineExecutor PipelineExecutor { get; set; } - /// /// SuppressDistributedTransactions /// @@ -56,9 +50,7 @@ public void Send(TransportMessage message, SendOptions sendOptions) toSend.ResponseQueue = new MessageQueue(NServiceBus.MsmqUtilities.GetReturnAddress(replyToAddress.ToString(), address.ToString())); } - bool suppressNativeTransactions; - PipelineExecutor.CurrentContext.TryGet("do-not-enlist-in-native-transaction", out suppressNativeTransactions); - if (sendOptions.EnlistInReceiveTransaction && UnitOfWork.HasActiveTransaction() && !suppressNativeTransactions) + if (sendOptions.EnlistInReceiveTransaction && UnitOfWork.HasActiveTransaction()) { q.Send(toSend, UnitOfWork.Transaction); } From d5c2de454a5581c0b1b01f4b459bc95cdc22d56f Mon Sep 17 00:00:00 2001 From: Particular Bot Date: Mon, 5 Oct 2015 11:02:33 +0300 Subject: [PATCH 4/8] SyncOMatic update --- .gitattributes | 4 +- .gitignore | 68 ++++++++++-- src/NServiceBus.sln.DotSettings | 186 ++++++++++++++++++++++++++++++-- src/nuget.config | 3 +- 4 files changed, 242 insertions(+), 19 deletions(-) diff --git a/.gitattributes b/.gitattributes index 610350288e6..0b6aa02467e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -55,9 +55,11 @@ *.fs text *.fsx text *.hs text - +*.targets text *.psm1 text *.ps1 text +*.md text +*.DotSettings text *.txt text eol=crlf *.bat text eol=crlf diff --git a/.gitignore b/.gitignore index 1a2e20de589..ef7a9f241f2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,13 @@ nugets +deploy build32 binaries -obj -bin *.vshost.* .nu -_ReSharper.* _UpgradeReport.* -*.csproj.user -*.resharper.user -*.resharper -*.suo *.cache *~ *.swp -*.user -TestResults -TestResult.xml results CommonAssemblyInfo.cs lib/sqlite/System.Data.SQLite.dll @@ -35,3 +26,60 @@ _NCrunch_NServiceBus/* logs run-git.cmd src/Chocolatey/Build/* + +installer/[F|f]iles +installer/[C|c]ustom[A|a]ctions +installer/ServiceControl-cache + +# Created by https://www.gitignore.io + +### VisualStudio ### +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates +.vs/ + +# mac temp file ignore +.DS_Store + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ + +# Roslyn cache directories +*.ide/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +#NUNIT +*.VisualState.xml +TestResult.xml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +src/scaffolding.config + +# Approval tests temp file +*.received.* \ No newline at end of file diff --git a/src/NServiceBus.sln.DotSettings b/src/NServiceBus.sln.DotSettings index 4084c6aeb48..87e28c5706a 100644 --- a/src/NServiceBus.sln.DotSettings +++ b/src/NServiceBus.sln.DotSettings @@ -1,6 +1,6 @@  - - + + CSharp60 True True True @@ -12,11 +12,15 @@ DO_NOT_SHOW DO_NOT_SHOW DO_NOT_SHOW + WARNING ERROR ERROR ERROR ERROR ERROR + DO_NOT_SHOW + DO_NOT_SHOW + DO_NOT_SHOW ERROR ERROR ERROR @@ -60,7 +64,8 @@ ERROR ERROR ERROR - ERROR + SUGGESTION + SUGGESTION ERROR ERROR ERROR @@ -100,12 +105,14 @@ DoHide DoHide DoHide - DoHide DoHide ERROR ERROR ERROR ERROR + ERROR + ERROR + ERROR ERROR ERROR ERROR @@ -116,9 +123,9 @@ DO_NOT_SHOW SUGGESTION WARNING - + WARNING ERROR - ERROR + HINT ERROR ERROR ERROR @@ -141,6 +148,142 @@ CHOP_ALWAYS True True + <?xml version="1.0" encoding="utf-16"?> +<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"> + <TypePattern DisplayName="COM interfaces or structs"> + <TypePattern.Match> + <Or> + <And> + <Kind Is="Interface" /> + <Or> + <HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" /> + <HasAttribute Name="System.Runtime.InteropServices.ComImport" /> + </Or> + </And> + <Kind Is="Struct" /> + </Or> + </TypePattern.Match> + </TypePattern> + <TypePattern DisplayName="NUnit Test Fixtures" RemoveRegions="All"> + <TypePattern.Match> + <And> + <Kind Is="Class" /> + <HasAttribute Name="NUnit.Framework.TestFixtureAttribute" Inherited="True" /> + <HasAttribute Name="NUnit.Framework.TestCaseFixtureAttribute" Inherited="True" /> + </And> + </TypePattern.Match> + <Entry DisplayName="Setup/Teardown Methods"> + <Entry.Match> + <And> + <Kind Is="Method" /> + <Or> + <HasAttribute Name="NUnit.Framework.SetUpAttribute" Inherited="True" /> + <HasAttribute Name="NUnit.Framework.TearDownAttribute" Inherited="True" /> + <HasAttribute Name="NUnit.Framework.FixtureSetUpAttribute" Inherited="True" /> + <HasAttribute Name="NUnit.Framework.FixtureTearDownAttribute" Inherited="True" /> + </Or> + </And> + </Entry.Match> + </Entry> + <Entry DisplayName="All other members" /> + <Entry Priority="100" DisplayName="Test Methods"> + <Entry.Match> + <And> + <Kind Is="Method" /> + <HasAttribute Name="NUnit.Framework.TestAttribute" /> + </And> + </Entry.Match> + <Entry.SortBy> + <Name /> + </Entry.SortBy> + </Entry> + </TypePattern> + <TypePattern DisplayName="Default Pattern"> + <Entry Priority="100" DisplayName="Public Delegates"> + <Entry.Match> + <And> + <Access Is="Public" /> + <Kind Is="Delegate" /> + </And> + </Entry.Match> + <Entry.SortBy> + <Name /> + </Entry.SortBy> + </Entry> + <Entry Priority="100" DisplayName="Public Enums"> + <Entry.Match> + <And> + <Access Is="Public" /> + <Kind Is="Enum" /> + </And> + </Entry.Match> + <Entry.SortBy> + <Name /> + </Entry.SortBy> + </Entry> + <Entry DisplayName="Static Fields and Constants"> + <Entry.Match> + <Or> + <Kind Is="Constant" /> + <And> + <Kind Is="Field" /> + <Static /> + </And> + </Or> + </Entry.Match> + <Entry.SortBy> + <Kind Order="Constant Field" /> + </Entry.SortBy> + </Entry> + <Entry DisplayName="Constructors"> + <Entry.Match> + <Kind Is="Constructor" /> + </Entry.Match> + <Entry.SortBy> + <Static /> + </Entry.SortBy> + </Entry> + <Entry DisplayName="Properties, Indexers"> + <Entry.Match> + <Or> + <Kind Is="Property" /> + <Kind Is="Indexer" /> + </Or> + </Entry.Match> + </Entry> + <Entry Priority="100" DisplayName="Interface Implementations"> + <Entry.Match> + <And> + <Kind Is="Member" /> + <ImplementsInterface /> + </And> + </Entry.Match> + <Entry.SortBy> + <ImplementsInterface Immediate="True" /> + </Entry.SortBy> + </Entry> + <Entry DisplayName="All other members" /> + <Entry DisplayName="Fields"> + <Entry.Match> + <And> + <Kind Is="Field" /> + <Not> + <Static /> + </Not> + </And> + </Entry.Match> + <Entry.SortBy> + <Readonly /> + <Name /> + </Entry.SortBy> + </Entry> + <Entry DisplayName="Nested Types"> + <Entry.Match> + <Kind Is="Type" /> + </Entry.Match> + </Entry> + </TypePattern> +</Patterns> <?xml version="1.0" encoding="utf-8" ?> <!-- @@ -381,6 +524,8 @@ II.2.12 <HandlesEvent /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> @@ -388,6 +533,27 @@ II.2.12 <HandlesEvent /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> $object$_On$event$ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> @@ -405,7 +571,15 @@ II.2.12 <HandlesEvent /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + True + True + True True + True True diff --git a/src/nuget.config b/src/nuget.config index f75c22c19cd..9f16f776eef 100644 --- a/src/nuget.config +++ b/src/nuget.config @@ -6,9 +6,8 @@ - - + From f67abc4247cdf4c53d1adc9139498bd9f730178b Mon Sep 17 00:00:00 2001 From: Tim Bussmann Date: Mon, 5 Oct 2015 11:14:48 +0200 Subject: [PATCH 5/8] fix scheduler task naming for vs15 --- .../NServiceBus.Core.Tests.csproj | 6 +++++ .../Scheduler/ScheduleTests.cs | 21 +++++++++++++++--- .../TestDlls/NServiceBus.NewCompilerBits.dll | Bin 0 -> 5120 bytes .../TestDlls/NServiceBus.OldCompilerBits.dll | Bin 0 -> 5120 bytes .../InMemory/Outbox/InMemoryOutboxStorage.cs | 12 +++++----- src/NServiceBus.Core/Scheduling/Schedule.cs | 18 ++++++++++----- 6 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 src/NServiceBus.Core.Tests/TestDlls/NServiceBus.NewCompilerBits.dll create mode 100644 src/NServiceBus.Core.Tests/TestDlls/NServiceBus.OldCompilerBits.dll diff --git a/src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj b/src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj index 67e4ab263b5..b1a6926cf99 100644 --- a/src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj +++ b/src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj @@ -43,6 +43,12 @@ false + + TestDlls\NServiceBus.NewCompilerBits.dll + + + TestDlls\NServiceBus.OldCompilerBits.dll + ..\packages\NUnit.2.6.3\lib\nunit.framework.dll diff --git a/src/NServiceBus.Core.Tests/Scheduler/ScheduleTests.cs b/src/NServiceBus.Core.Tests/Scheduler/ScheduleTests.cs index 768816f165d..4456d266c47 100644 --- a/src/NServiceBus.Core.Tests/Scheduler/ScheduleTests.cs +++ b/src/NServiceBus.Core.Tests/Scheduler/ScheduleTests.cs @@ -15,7 +15,8 @@ public class ScheduleTests FakeBus bus = new FakeBus(); Schedule schedule; - DefaultScheduler defaultScheduler ; + DefaultScheduler defaultScheduler; + [SetUp] public void SetUp() { @@ -36,15 +37,29 @@ public void When_scheduling_an_action_with_a_name_the_task_should_get_that_name( [Test] public void When_scheduling_an_action_without_a_name_the_task_should_get_the_DeclaringType_as_name() { - schedule.Every(TimeSpan.FromMinutes(5), () => { }); + schedule.Every(TimeSpan.FromMinutes(5), () => { }); Assert.That(EnsureThatNameExists("ScheduleTests")); } + [Test] + public void Ensure_retrieving_name_from_type_works_for_old_compiler() + { + schedule.Every(TimeSpan.FromMinutes(5), OldCompilerBits.ActionProvider.SimpleAction()); + Assert.That(EnsureThatNameExists("ActionProvider")); + } + + [Test] + public void Ensure_retrieving_name_from_type_works_for_new_compiler() + { + schedule.Every(TimeSpan.FromMinutes(5), NewCompilerBits.ActionProvider.SimpleAction()); + Assert.That(EnsureThatNameExists("ActionProvider")); + } + [Test] public void Schedule_tasks_using_multiple_threads() { Parallel.For(0, 20, i => schedule.Every(TimeSpan.FromSeconds(1), () => { })); - + bus.DeferWasCalled = 0; Parallel.ForEach(defaultScheduler.scheduledTasks, diff --git a/src/NServiceBus.Core.Tests/TestDlls/NServiceBus.NewCompilerBits.dll b/src/NServiceBus.Core.Tests/TestDlls/NServiceBus.NewCompilerBits.dll new file mode 100644 index 0000000000000000000000000000000000000000..849bb494804432820a1262cdefb5e17e3bd598e9 GIT binary patch literal 5120 zcmeHKeQ;FO6+dqimhd5v1R;D3JV?TKp4oiRFk(ou8zKS;&4wU$$MD|n&E~<|eam}q zA+aq6DO$vWk+zC0Ra>Vsj58LeFfw&O3VxJv7;LACSnQ-)wPjlMFIyM}`n&h-ZZ-)Y zPXBbgZ|`~co^$TGzjN++_ugH7-{X`+M7gNft`Qx@o0mF4Z%%q49yjxM(XsGVVO}&jmcp(9yc9XW3rWu%X(Z6v;^gt8DYw8w~a1InO@UKv`WgM-|Ts% zEj?R5&6dYVw$#c2K=i@D-)}azj5N(f(n=`ze@Y0J4{_h_l__bjtSLMHfcdE-- zC_3!6@J1cX^B@c@8;Hh&_tZS1=|g2V>&qGFLMspbyR-BahjlyXzcva4GT|$5XBU}h zgJRiM7)*h!4h`-o2b5LnfL^hfVM0-eHbBU26`*F7I--WGu4o?MaYfyLjDT4pK*^C>s3(GxJ3YkQdPul<@x3p~XoNeglUiFRud>e}~y0n)|MlU4qg4v#V z`P};jijDAld%5NSvw#-Tf`;Hd4HCDA!u{J)rIag`<(0lAoHK$9(0MReyp8C`cz?m$ zLC4bLQJZW00Q2&tEnXX>AEM3Ep}1-7iU8hEp??9UiyI76L!TE6m)1@6&?q$MvQ$Zv zgg+vj{9EB{41bUKUdHVw1GKNG0VbIemO+Bwn$yoq=( zhZa-6=WRGOm;Ov^WIp1jG|TfIWZOmW;i48;mgrH@>nmF8`Cypr86n$26XA=5Y-#aG zhzB1x1#~pc2c1AZL6-P(Nf+(Sg7yg72kNC=pfhQ^Xe%^^{zeKF z(nZi|G)hvamvppmz%D7yOk}3w}^=z9VRu+QHdGy`VPzND3pe=cK8W+v~0& zq3}p4bPN&YS(7fMv`#d0#QM|H+HgllK(`Zy+T%A=+b*Z2K|Pi*Sbf;h&3LWW(cvS1 zuw-fNl8z3)8t!6|`nVbIiJ3`zHFLVmNPrnEsyeKKmaaA)(7$GZJWh3qo+-GvQ;x|OO3FY zYHb>@(xzHb<}Aln&bFG_g7lc>0NBnf8{Q6#N(=pFyi<=Rf&IGT0JFoEo)|22ofacn znW1)zmOb3|8VlhHJHrKjGtpz|(XQ)?VhJ_gGccw#8F%y;<8xvjO*eEWOB(F49Trnk zN=nL2>?qV6WY!iv%o>um(#*D|7pg&bY$akC!Q z*fBX3uhiTDU5&;~+tI^z#(;}iSrK=bWhPQchKbXdGIBRbfF60q?3=kjE!svv%p|TJ zxA`$8ihZfy{`k2!S03$r?82eNwSS~sS(5T{WRgapk)O}I<2do;j+6=-N5~#&dQslX z4}{vMRQ2!beU?h_MfGBjhBYtWuh4G|*8BKp#&@g-Cw*AhbuBl4$K@kWod3tazxCihRq_?n*k)BYXre%yDc;i133KlT?z#~z=NzlbWIxc}vIk1V=lvX|Z4_xkB~tS9%k zB)&iCv#0mgo$vl4^4ZKQ_KCkNYbwyE6~DUPOcsuBKHYt`JGt#dm3Cjp+)rLv^G4CW z8P7jsYJ1N$Y(6!A{pT;ep5rYTi`ob{1&!F~r93Hh{g}bwwRtA3v(!Yh8E@a?oSh$j(_%`C5lJryPZFFRLU*!61(|%6Pac%zigI5y(R_(YYP3pU zMNPR@R#Q>wE32wp!phW&#lA9DU9D=1nHH{zRN*Ydv_2e#c!*X=G*xMCY|DJFi&8mz z7mmwnpdU9eBT8*s&G@nl_!v1Ok)fN*;VpgdgL7l%Ub^Raf7@g8Jf~m1Q+ddFvv6}r ze$w(EFZtK5tA{S%@ySO&J27#t=fM|$IVO3zL4CO7uG*bd%6@z23$yypsD!&t5AarbOsOl&f#ao0*=M%-?P8~T4Z{MJBJ zH0-L!)1L@g);riL=el>td+TtQ<(H#Wc`XMCO6@p%J3t$$6)l|oxS@35-Av2fTQ?oc z{rswX;<~onHqo+_9ej)Kd7J9EK7NXG!Rk!*BPgB8|s@redT-e%OoQVHoXT7PrjKk|o6aJ@8f) zdMOp!NVA}oMjn6#o5BJ|Vi3+|;A7x#0m3j^4U~kYB4)PGR}e#kA}J(^R3t3u=@~@j z*ue(oY8Uow$kVa#!Ag0i;tvNBN)pj@gl-(zjVuptgsBFpdR6Ul)8YMgq6WOnGOP%OclWDBW#ki09LZ?xT_t3-5BgzxZ$N&gkY8X)RLNm zuQvB79e>{AtH^K9*N^vC^-UA&x(4%@@HdGybFw0LWBWV?Uv)jJ#Ci^%W9X_5UDFyd prXCToMSL`P--DRkY8*oHP5HV z1aUgUbf!~pa)0lfbI(2Z+;i^NZrXN`77&pWb!v*}B)+^f3%oLnp*i>ZXLISv?3YVV zN*iA;4GgQM95?icp+x175{v1U9AvU#$7D4o`?~ycR1Y)vqD497Nz>hJL>r|A^znVq z1yZA(BS+~%X(7=ykhl`k+?DvssLiNEd4hH%{N{qB8qpXS$bWW`Ft4HgT$TUNe3L8} zp*&ehw1pGRL=!v^bIVY|jomAVmd$Ou5-$^FrL|{)zd4O}TWrJvUz7tto0u#7PA@Xi zklQeg5QM_FW)M74xu|KS8Q!}Mrs+`RA)_HwZmR$_tuzz0rm=$j2=nKK`{tkw$}1(( zGKsQ>&wupeiCY{ezp`fQ55jwY@%Kg1r^e6w4tk@7_n+9jbbR53 zstXN&oGR#hd<*;JjKl7~GxP8(MMRP64W6O{k52yc!mHQj?Ejmp{ww32?Q6ST=YLZF z!@IuJzWCGe@Dq>RU6GSH8Gfg`<=Aic9=W*stz{XcpbEGr5#`e!ptHKL=#mTBb(siB&KMW1O0?vxBG=00junNF^Ci~m-_R=Yo+vz) zyXxIF?z);fPZO79kOs^{Y|Hi#?dCCt)iS?jsIiF2HFjqt@?O^Kr+Yy2rB~M8+u_6a z2>91wx~x^xgIpN}CZsJzjzqjKR@70k@S6}4kwWeXh9LMSY;itS;d0Vb7ctt7J)j9Z zPUE0|PtO3)3!DoSFRg{6umB3pl4#_@x2Iv(Mzre3kKO{TpA)rY=1>Q*$(vYzH zS8|S};*F(0PUOgIDHD_ z8nuKhRgZNW`Ytuhj4P>A)C}o{rUuDBYFaExUBO#f$VyruzZ#8eEMbn^Axk%sdhQ-O zW~ou;?qi0Dv9P`=pcoNmt;gBUZr6>SEf$u2(6-og7q&x#ZD>=AX|iZg8x5!y%ug$( z#6D(*3^mSG=Qn!w*bX&f8_H)jN8?ItbbddCBW#DP`3+t@K5D3u;mb4y3?O8R6{ zK6-7XtVfdPH71AksY)cK zo0b|f$;X0rB%;h3Dj`Ffu!fj9oswi0Q!6OlTP!IN;vS|cBZ4w#TuP>&_d`=q)l@4j z^EXI&w zXihH<9CWhS2YH(}biDQYgX@2}ZC&8IZ-yEv>*+fN`j*z8`?eEzS~j#Krz}ai92^;d z{5DQzjUA_Q?5;7Kw6NpirxW-de~X9Tn*2<i# z4;^TJW8|ao2iJdUzWA4$+6&a{%3j#2+l7lePmTOx#NP8_eQ?|0SKocE`!^+rm;d;f z9z1Zi^|oJEZvF7YOE}4;1+Ic@CqKe7WQVk@#F;4-WOqn(t-G@=Fuk{`lFMK%?wcCTT)SIl(=2IA(9fnhz$27G$Rj;4e7Bdy2+p&zJ9GBJA;ba<0dJJM=fB@`q}&^e@2iKz-z= zL0}v8fa;(w>IB~bTo0O;N#}=`_}QGOT*7Ihn*=7_N_^j^7atf2RuwW}N5!j`!Dfth zkS^59`EgGHv?`FAXjjOBo(?WiCY&c>RDw?yv{c9=m$7t2=+t1|iNAUZ@)*EgDf*^H z_F;6BLc&gb);OK8&miB05kjC^$%ZC>KkAS&P+hPU7JQWA$(b0?Q(;H^oWOWlX=C*X zdnVdbbMe4R&2;5I{bcC#XjnowhPi8qw?a|y1nTlWUD*>iywvc=b6o)Y8(}LVEc3a< zX;jQULcWIvt(?q@2doVz;yhDENrF^-No*vNyG z7LCu2$A6NedXb~qW6aIe+&tk?gZZ~0%O+wO#mdqUMH#D_ub7z(&+UiMUELxle&^=h Ocy-NwVeNk-0{;dkPf`p3 literal 0 HcmV?d00001 diff --git a/src/NServiceBus.Core/Persistence/InMemory/Outbox/InMemoryOutboxStorage.cs b/src/NServiceBus.Core/Persistence/InMemory/Outbox/InMemoryOutboxStorage.cs index a8bf1398073..5d0c5a46664 100644 --- a/src/NServiceBus.Core/Persistence/InMemory/Outbox/InMemoryOutboxStorage.cs +++ b/src/NServiceBus.Core/Persistence/InMemory/Outbox/InMemoryOutboxStorage.cs @@ -86,14 +86,14 @@ public override bool Equals(object obj) { return false; } - return Equals((StoredMessage) obj); + return Equals((StoredMessage)obj); } public override int GetHashCode() { unchecked { - return ((Id != null ? Id.GetHashCode() : 0)*397) ^ Dispatched.GetHashCode(); + return ((Id != null ? Id.GetHashCode() : 0) * 397) ^ Dispatched.GetHashCode(); } } @@ -102,14 +102,16 @@ public override int GetHashCode() public void RemoveEntriesOlderThan(DateTime dateTime) { - var entriesToRemove = storage.Where(e => e.Value.Dispatched && e.Value.StoredAt < dateTime) - .Select(e=>e.Key); + var entriesToRemove = storage + .Where(e => e.Value.Dispatched && e.Value.StoredAt < dateTime) + .Select(e => e.Key) + .ToList(); foreach (var entry in entriesToRemove) { StoredMessage toRemove; - storage.TryRemove(entry, out toRemove); + storage.TryRemove(entry, out toRemove); } } } diff --git a/src/NServiceBus.Core/Scheduling/Schedule.cs b/src/NServiceBus.Core/Scheduling/Schedule.cs index 7b5c35c4124..edd7ecfb8c7 100644 --- a/src/NServiceBus.Core/Scheduling/Schedule.cs +++ b/src/NServiceBus.Core/Scheduling/Schedule.cs @@ -1,6 +1,7 @@ namespace NServiceBus { using System; + using System.Linq; using System.Threading; using ObjectBuilder; using Scheduling; @@ -29,7 +30,15 @@ public Schedule(IBuilder builder) /// The to execute. public void Every(TimeSpan timeSpan, Action task) { - Every(timeSpan, task.Method.DeclaringType.Name, task); + var declaringType = task.Method.DeclaringType; + + while (declaringType.DeclaringType != null && + declaringType.CustomAttributes.Any(a => a.AttributeType.Name == "CompilerGeneratedAttribute")) + { + declaringType = declaringType.DeclaringType; + } + + Every(timeSpan, declaringType.Name, task); } /// @@ -43,11 +52,10 @@ public void Every(TimeSpan timeSpan, string name, Action task) builder.Build() .Schedule(new TaskDefinition { - Every = timeSpan, - Name = name, + Every = timeSpan, + Name = name, Task = task }); } - } -} +} \ No newline at end of file From 2d52402a079e52c53147c8fc70b44bcedafbf626 Mon Sep 17 00:00:00 2001 From: Tim Bussmann Date: Mon, 5 Oct 2015 14:14:59 +0200 Subject: [PATCH 6/8] removed StackTrace dependent ATTs --- ...When_Uow_Begin_and_different_End_throws.cs | 196 ----------------- .../Exceptions/When_Uow_Begin_throws.cs | 123 ----------- .../Exceptions/When_Uow_End_throws.cs | 122 ---------- .../When_handler_and_Uow_End_throws.cs | 208 ------------------ .../Exceptions/When_handler_throws.cs | 114 ---------- .../When_handler_throws_AggregateException.cs | 140 ------------ .../NServiceBus.AcceptanceTests.csproj | 18 -- 7 files changed, 921 deletions(-) delete mode 100644 src/NServiceBus.AcceptanceTests/Exceptions/When_Uow_Begin_and_different_End_throws.cs delete mode 100644 src/NServiceBus.AcceptanceTests/Exceptions/When_Uow_Begin_throws.cs delete mode 100644 src/NServiceBus.AcceptanceTests/Exceptions/When_Uow_End_throws.cs delete mode 100644 src/NServiceBus.AcceptanceTests/Exceptions/When_handler_and_Uow_End_throws.cs delete mode 100644 src/NServiceBus.AcceptanceTests/Exceptions/When_handler_throws.cs delete mode 100644 src/NServiceBus.AcceptanceTests/Exceptions/When_handler_throws_AggregateException.cs diff --git a/src/NServiceBus.AcceptanceTests/Exceptions/When_Uow_Begin_and_different_End_throws.cs b/src/NServiceBus.AcceptanceTests/Exceptions/When_Uow_Begin_and_different_End_throws.cs deleted file mode 100644 index dd749160b7c..00000000000 --- a/src/NServiceBus.AcceptanceTests/Exceptions/When_Uow_Begin_and_different_End_throws.cs +++ /dev/null @@ -1,196 +0,0 @@ -namespace NServiceBus.AcceptanceTests.Exceptions -{ - using System; - using System.Runtime.CompilerServices; - using NServiceBus.AcceptanceTesting; - using NServiceBus.AcceptanceTests.EndpointTemplates; - using NServiceBus.Config; - using NServiceBus.Faults; - using NServiceBus.Features; - using NServiceBus.UnitOfWork; - using NUnit.Framework; - - public class When_Uow_Begin_and_different_End_throws : NServiceBusAcceptanceTest - { - [Test] - public void Should_receive_AggregateException_with_both_exceptions() - { - var context = new Context(); - - Scenario.Define(context) - .WithEndpoint(b => b.Given(bus => bus.SendLocal(new Message()))) - .AllowExceptions() - .Done(c => c.ExceptionReceived) - .Run(); - - Assert.AreEqual(typeof(BeginException), context.InnerExceptionOneType); - Assert.AreEqual(typeof(EndException), context.InnerExceptionTwoType); - - -#if (!DEBUG) - - StackTraceAssert.StartsWith( -@"at NServiceBus.UnitOfWorkBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ChildContainerBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ProcessingStatisticsBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.Pipeline.PipelineExecutor.Execute[T](BehaviorChain`1 pipelineAction, T context) -at NServiceBus.Unicast.Transport.TransportReceiver.ProcessMessage(TransportMessage message) -at NServiceBus.Unicast.Transport.TransportReceiver.TryProcess(TransportMessage message)", context.StackTrace); - - StackTraceAssert.StartsWith( -string.Format(@"at NServiceBus.AcceptanceTests.Exceptions.When_Uow_Begin_and_different_End_throws.Endpoint.{0}.End(Exception ex) -at NServiceBus.UnitOfWorkBehavior.AppendEndExceptionsAndRethrow(Exception initialException)", context.TypeName), context.InnerExceptionTwoStackTrace); - -#endif - - } - - public class Context : ScenarioContext - { - public bool ExceptionReceived { get; set; } - public string StackTrace { get; set; } - public Type ExceptionType { get; set; } - public string InnerExceptionOneStackTrace { get; set; } - public string InnerExceptionTwoStackTrace { get; set; } - public Type InnerExceptionOneType { get; set; } - public Type InnerExceptionTwoType { get; set; } - public bool FirstOneExecuted { get; set; } - public string TypeName { get; set; } - } - - public class Endpoint : EndpointConfigurationBuilder - { - public Endpoint() - { - EndpointSetup(b => - { - b.RegisterComponents(c => - { - c.ConfigureComponent(DependencyLifecycle.SingleInstance); - c.ConfigureComponent(DependencyLifecycle.InstancePerUnitOfWork); - c.ConfigureComponent(DependencyLifecycle.InstancePerUnitOfWork); - }); - b.DisableFeature(); - }) - .WithConfig(c => - { - c.MaxRetries = 0; - }); - } - - class CustomFaultManager : IManageMessageFailures - { - public Context Context { get; set; } - - public void SerializationFailedForMessage(TransportMessage message, Exception e) - { - } - - public void ProcessingAlwaysFailsForMessage(TransportMessage message, Exception e) - { - var aggregateException = (AggregateException)e; - Context.StackTrace = aggregateException.StackTrace; - var innerExceptions = aggregateException.InnerExceptions; - Context.InnerExceptionOneStackTrace = innerExceptions[0].StackTrace; - Context.InnerExceptionTwoStackTrace = innerExceptions[1].StackTrace; - Context.InnerExceptionOneType = innerExceptions[0].GetType(); - Context.InnerExceptionTwoType = innerExceptions[1].GetType(); - Context.ExceptionReceived = true; - } - - public void Init(Address address) - { - - } - } - - public class UnitOfWorkThatThrows1 : IManageUnitsOfWork - { - public Context Context { get; set; } - - bool throwAtEnd; - - [MethodImpl(MethodImplOptions.NoInlining)] - public void Begin() - { - if (Context.FirstOneExecuted) - { - throw new BeginException(); - } - - Context.FirstOneExecuted = throwAtEnd = true; - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public void End(Exception ex = null) - { - if (throwAtEnd) - { - Context.TypeName = GetType().Name; - - throw new EndException(); - } - } - } - public class UnitOfWorkThatThrows2 : IManageUnitsOfWork - { - public Context Context { get; set; } - - bool throwAtEnd; - - [MethodImpl(MethodImplOptions.NoInlining)] - public void Begin() - { - if (Context.FirstOneExecuted) - { - throw new BeginException(); - } - - Context.FirstOneExecuted = throwAtEnd = true; - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public void End(Exception ex = null) - { - if (throwAtEnd) - { - Context.TypeName = GetType().Name; - - throw new EndException(); - } - } - } - - class Handler : IHandleMessages - { - [MethodImpl(MethodImplOptions.NoInlining)] - public void Handle(Message message) - { - } - } - - } - - [Serializable] - public class Message : IMessage - { - } - public class BeginException : Exception - { - public BeginException() - : base("BeginException") - { - - } - } - public class EndException : Exception - { - public EndException() - : base("EndException") - { - - } - } - } - -} \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/Exceptions/When_Uow_Begin_throws.cs b/src/NServiceBus.AcceptanceTests/Exceptions/When_Uow_Begin_throws.cs deleted file mode 100644 index 9b6ca1fec14..00000000000 --- a/src/NServiceBus.AcceptanceTests/Exceptions/When_Uow_Begin_throws.cs +++ /dev/null @@ -1,123 +0,0 @@ -namespace NServiceBus.AcceptanceTests.Exceptions -{ - using System; - using System.Runtime.CompilerServices; - using NServiceBus.AcceptanceTesting; - using NServiceBus.AcceptanceTests.EndpointTemplates; - using NServiceBus.Config; - using NServiceBus.Faults; - using NServiceBus.Features; - using NServiceBus.UnitOfWork; - using NUnit.Framework; - - public class When_Uow_Begin_throws : NServiceBusAcceptanceTest - { - [Test] - public void Should_receive_exception_thrown_from_begin() - { - var context = new Context(); - - Scenario.Define(context) - .WithEndpoint(b => b.Given(bus => bus.SendLocal(new Message()))) - .AllowExceptions() - .Done(c => c.ExceptionReceived) - .Run(); - - Assert.AreEqual(typeof(BeginException), context.ExceptionType); -#if (!DEBUG) - StackTraceAssert.StartsWith( -@"at NServiceBus.AcceptanceTests.Exceptions.When_Uow_Begin_throws.Endpoint.UnitOfWorkThatThrowsInBegin.Begin() -at NServiceBus.UnitOfWorkBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ChildContainerBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ProcessingStatisticsBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.Pipeline.PipelineExecutor.Execute[T](BehaviorChain`1 pipelineAction, T context) -at NServiceBus.Unicast.Transport.TransportReceiver.ProcessMessage(TransportMessage message) -at NServiceBus.Unicast.Transport.TransportReceiver.TryProcess(TransportMessage message)", context.StackTrace); -#endif - } - - public class Context : ScenarioContext - { - public bool ExceptionReceived { get; set; } - public string StackTrace { get; set; } - public Type ExceptionType { get; set; } - } - - public class Endpoint : EndpointConfigurationBuilder - { - public Endpoint() - { - EndpointSetup(b => - { - b.RegisterComponents(c => - { - c.ConfigureComponent(DependencyLifecycle.SingleInstance); - c.ConfigureComponent(DependencyLifecycle.InstancePerUnitOfWork); - }); - b.DisableFeature(); - }) - .WithConfig(c => - { - c.MaxRetries = 0; - }); - } - - class CustomFaultManager : IManageMessageFailures - { - public Context Context { get; set; } - - public void SerializationFailedForMessage(TransportMessage message, Exception e) - { - } - - public void ProcessingAlwaysFailsForMessage(TransportMessage message, Exception e) - { - Context.ExceptionType = e.GetType(); - Context.StackTrace = e.StackTrace; - Context.ExceptionReceived = true; - } - - public void Init(Address address) - { - - } - } - - public class UnitOfWorkThatThrowsInBegin : IManageUnitsOfWork - { - [MethodImpl(MethodImplOptions.NoInlining)] - public void Begin() - { - throw new BeginException(); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public void End(Exception ex = null) - { - } - } - - class Handler : IHandleMessages - { - [MethodImpl(MethodImplOptions.NoInlining)] - public void Handle(Message message) - { - } - } - } - - [Serializable] - public class Message : IMessage - { - } - public class BeginException : Exception - { - public BeginException() - : base("BeginException") - { - - } - } - } - -} \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/Exceptions/When_Uow_End_throws.cs b/src/NServiceBus.AcceptanceTests/Exceptions/When_Uow_End_throws.cs deleted file mode 100644 index 237f520a025..00000000000 --- a/src/NServiceBus.AcceptanceTests/Exceptions/When_Uow_End_throws.cs +++ /dev/null @@ -1,122 +0,0 @@ -namespace NServiceBus.AcceptanceTests.Exceptions -{ - using System; - using System.Runtime.CompilerServices; - using NServiceBus.AcceptanceTesting; - using NServiceBus.AcceptanceTests.EndpointTemplates; - using NServiceBus.Config; - using NServiceBus.Faults; - using NServiceBus.Features; - using NServiceBus.UnitOfWork; - using NUnit.Framework; - - public class When_Uow_End_throws : NServiceBusAcceptanceTest - { - [Test] - public void Should_receive_exception_thrown_from_end() - { - var context = new Context(); - - Scenario.Define(context) - .WithEndpoint(b => b.Given(bus => bus.SendLocal(new Message()))) - .AllowExceptions() - .Done(c => c.ExceptionReceived) - .Run(); - - Assert.AreEqual(typeof(EndException), context.ExceptionType); -#if(!DEBUG) - StackTraceAssert.StartsWith( -@"at NServiceBus.AcceptanceTests.Exceptions.When_Uow_End_throws.Endpoint.UnitOfWorkThatThrowsInEnd.End(Exception ex) -at NServiceBus.UnitOfWorkBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ChildContainerBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ProcessingStatisticsBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.Pipeline.PipelineExecutor.Execute[T](BehaviorChain`1 pipelineAction, T context) -at NServiceBus.Unicast.Transport.TransportReceiver.ProcessMessage(TransportMessage message) -at NServiceBus.Unicast.Transport.TransportReceiver.TryProcess(TransportMessage message)", context.StackTrace); -#endif - } - - public class Context : ScenarioContext - { - public bool ExceptionReceived { get; set; } - public string StackTrace { get; set; } - public Type ExceptionType { get; set; } - } - - public class Endpoint : EndpointConfigurationBuilder - { - public Endpoint() - { - EndpointSetup(b => - { - b.RegisterComponents(c => - { - c.ConfigureComponent(DependencyLifecycle.SingleInstance); - c.ConfigureComponent(DependencyLifecycle.InstancePerUnitOfWork); - }); - b.DisableFeature(); - }) - .WithConfig(c => - { - c.MaxRetries = 0; - }); - } - - class CustomFaultManager : IManageMessageFailures - { - public Context Context { get; set; } - - public void SerializationFailedForMessage(TransportMessage message, Exception e) - { - } - - public void ProcessingAlwaysFailsForMessage(TransportMessage message, Exception e) - { - Context.ExceptionType = e.GetType(); - Context.StackTrace = e.StackTrace; - Context.ExceptionReceived = true; - } - - public void Init(Address address) - { - - } - } - - class UnitOfWorkThatThrowsInEnd : IManageUnitsOfWork - { - [MethodImpl(MethodImplOptions.NoInlining)] - public void Begin() - { - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public void End(Exception ex = null) - { - throw new EndException(); - } - } - class Handler : IHandleMessages - { - [MethodImpl(MethodImplOptions.NoInlining)] - public void Handle(Message message) - { - } - } - } - - [Serializable] - public class Message : IMessage - { - } - public class EndException : Exception - { - public EndException() - : base("EndException") - { - - } - } - } - -} \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/Exceptions/When_handler_and_Uow_End_throws.cs b/src/NServiceBus.AcceptanceTests/Exceptions/When_handler_and_Uow_End_throws.cs deleted file mode 100644 index 5faaa999475..00000000000 --- a/src/NServiceBus.AcceptanceTests/Exceptions/When_handler_and_Uow_End_throws.cs +++ /dev/null @@ -1,208 +0,0 @@ -namespace NServiceBus.AcceptanceTests.Exceptions -{ - using System; - using System.Runtime.CompilerServices; - using NServiceBus.AcceptanceTesting; - using NServiceBus.AcceptanceTests.EndpointTemplates; - using NServiceBus.Config; - using NServiceBus.Faults; - using NServiceBus.Features; - using NServiceBus.UnitOfWork; - using NUnit.Framework; - - public class When_handler_and_Uow_End_throws : NServiceBusAcceptanceTest - { - [Test] - public void Should_receive_AggregateException_with_both_exceptions() - { - var context = new Context(); - - Scenario.Define(context) - .WithEndpoint(b => b.Given(bus => bus.SendLocal(new Message()))) - .AllowExceptions() - .Done(c => c.ExceptionReceived) - .Run(); - - Assert.AreEqual(typeof(HandlerException), context.InnerExceptionOneType); - Assert.AreEqual(typeof(EndException), context.InnerExceptionTwoType); - -#if (!DEBUG) - StackTraceAssert.StartsWith( -@"at NServiceBus.UnitOfWorkBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ChildContainerBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ProcessingStatisticsBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.Pipeline.PipelineExecutor.Execute[T](BehaviorChain`1 pipelineAction, T context) -at NServiceBus.Unicast.Transport.TransportReceiver.ProcessMessage(TransportMessage message) -at NServiceBus.Unicast.Transport.TransportReceiver.TryProcess(TransportMessage message)", context.StackTrace); - - StackTraceAssert.StartsWith( -@"at NServiceBus.AcceptanceTests.Exceptions.When_handler_and_Uow_End_throws.Endpoint.Handler.Handle(Message message) -at NServiceBus.Unicast.MessageHandlerRegistry.Invoke(Object handler, Object message, Dictionary`2 dictionary) -at NServiceBus.InvokeHandlersBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.SetCurrentMessageBeingHandledBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.LoadHandlersBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ApplyIncomingMessageMutatorsBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ExecuteLogicalMessagesBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.CallbackInvocationBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.DeserializeLogicalMessagesBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ApplyIncomingTransportMessageMutatorsBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.SubscriptionReceiverBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.UnitOfWorkBehavior.Invoke(IncomingContext context, Action next)", context.InnerExceptionOneStackTrace); - - StackTraceAssert.StartsWith( -string.Format(@"at NServiceBus.AcceptanceTests.Exceptions.When_handler_and_Uow_End_throws.Endpoint.{0}.End(Exception ex) -at NServiceBus.UnitOfWorkBehavior.AppendEndExceptionsAndRethrow(Exception initialException)", context.TypeName), context.InnerExceptionTwoStackTrace); - -#endif - } - - public class Context : ScenarioContext - { - public bool ExceptionReceived { get; set; } - public string StackTrace { get; set; } - public string InnerExceptionOneStackTrace { get; set; } - public string InnerExceptionTwoStackTrace { get; set; } - public Type InnerExceptionOneType { get; set; } - public Type InnerExceptionTwoType { get; set; } - public bool FirstOneExecuted { get; set; } - public string TypeName { get; set; } - } - - public class Endpoint : EndpointConfigurationBuilder - { - public Endpoint() - { - EndpointSetup(b => - { - b.RegisterComponents(c => - { - c.ConfigureComponent(DependencyLifecycle.SingleInstance); - c.ConfigureComponent(DependencyLifecycle.InstancePerUnitOfWork); - c.ConfigureComponent(DependencyLifecycle.InstancePerUnitOfWork); - }); - b.DisableFeature(); - }) - .WithConfig(c => - { - c.MaxRetries = 0; - }); - } - - class CustomFaultManager : IManageMessageFailures - { - public Context Context { get; set; } - - public void SerializationFailedForMessage(TransportMessage message, Exception e) - { - } - - public void ProcessingAlwaysFailsForMessage(TransportMessage message, Exception e) - { - var aggregateException = (AggregateException)e; - Context.StackTrace = aggregateException.StackTrace; - var exceptions = aggregateException.InnerExceptions; - Context.InnerExceptionOneStackTrace = exceptions[0].StackTrace; - Context.InnerExceptionTwoStackTrace = exceptions[1].StackTrace; - Context.InnerExceptionOneType = exceptions[0].GetType(); - Context.InnerExceptionTwoType = exceptions[1].GetType(); - Context.ExceptionReceived = true; - } - - public void Init(Address address) - { - - } - } - - public class UnitOfWorkThatThrows1 : IManageUnitsOfWork - { - public Context Context { get; set; } - - bool executedInSecondPlace; - - [MethodImpl(MethodImplOptions.NoInlining)] - public void Begin() - { - if (Context.FirstOneExecuted) - { - executedInSecondPlace = true; - } - - Context.FirstOneExecuted = true; - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public void End(Exception ex = null) - { - if (executedInSecondPlace) - { - Context.TypeName = GetType().Name; - - throw new EndException(); - } - } - } - - public class UnitOfWorkThatThrows2 : IManageUnitsOfWork - { - public Context Context { get; set; } - - bool executedInSecondPlace; - - [MethodImpl(MethodImplOptions.NoInlining)] - public void Begin() - { - if (Context.FirstOneExecuted) - { - executedInSecondPlace = true; - } - - Context.FirstOneExecuted = true; - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public void End(Exception ex = null) - { - if (executedInSecondPlace) - { - Context.TypeName = GetType().Name; - - throw new EndException(); - } - } - } - - class Handler : IHandleMessages - { - [MethodImpl(MethodImplOptions.NoInlining)] - public void Handle(Message message) - { - throw new HandlerException(); - } - } - - } - - [Serializable] - public class Message : IMessage - { - } - public class HandlerException : Exception - { - public HandlerException() - : base("HandlerException") - { - - } - } - public class EndException : Exception - { - public EndException() - : base("EndException") - { - - } - } - } - -} \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/Exceptions/When_handler_throws.cs b/src/NServiceBus.AcceptanceTests/Exceptions/When_handler_throws.cs deleted file mode 100644 index 45ac933f63b..00000000000 --- a/src/NServiceBus.AcceptanceTests/Exceptions/When_handler_throws.cs +++ /dev/null @@ -1,114 +0,0 @@ -namespace NServiceBus.AcceptanceTests.Exceptions -{ - using System; - using System.Runtime.CompilerServices; - using NServiceBus.AcceptanceTesting; - using NServiceBus.AcceptanceTests.EndpointTemplates; - using NServiceBus.Config; - using NServiceBus.Faults; - using NServiceBus.Features; - using NUnit.Framework; - - public class When_handler_throws : NServiceBusAcceptanceTest - { - [Test] - public void Should_receive_exception_from_handler() - { - var context = new Context(); - - Scenario.Define(context) - .WithEndpoint(b => b.Given(bus => bus.SendLocal(new Message()))) - .AllowExceptions() - .Done(c => c.ExceptionReceived) - .Run(); - Assert.AreEqual(typeof(HandlerException), context.ExceptionType); -#if (!DEBUG) - StackTraceAssert.StartsWith( -@"at NServiceBus.AcceptanceTests.Exceptions.When_handler_throws.Endpoint.Handler.Handle(Message message) -at NServiceBus.Unicast.MessageHandlerRegistry.Invoke(Object handler, Object message, Dictionary`2 dictionary) -at NServiceBus.InvokeHandlersBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.SetCurrentMessageBeingHandledBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.LoadHandlersBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ApplyIncomingMessageMutatorsBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ExecuteLogicalMessagesBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.CallbackInvocationBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.DeserializeLogicalMessagesBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ApplyIncomingTransportMessageMutatorsBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.SubscriptionReceiverBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.UnitOfWorkBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ChildContainerBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ProcessingStatisticsBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.Pipeline.PipelineExecutor.Execute[T](BehaviorChain`1 pipelineAction, T context) -at NServiceBus.Unicast.Transport.TransportReceiver.ProcessMessage(TransportMessage message) -at NServiceBus.Unicast.Transport.TransportReceiver.TryProcess(TransportMessage message) -at NServiceBus.Transports.Msmq.MsmqDequeueStrategy.Action()", context.StackTrace); -#endif - } - - public class Context : ScenarioContext - { - public bool ExceptionReceived { get; set; } - public string StackTrace { get; set; } - public Type ExceptionType { get; set; } - } - - public class Endpoint : EndpointConfigurationBuilder - { - public Endpoint() - { - EndpointSetup(b => - { - b.RegisterComponents(c => c.ConfigureComponent(DependencyLifecycle.SingleInstance)); - b.DisableFeature(); - }) - .WithConfig(c => - { - c.MaxRetries = 0; - }); - } - - class CustomFaultManager : IManageMessageFailures - { - public Context Context { get; set; } - - public void SerializationFailedForMessage(TransportMessage message, Exception e) - { - } - - public void ProcessingAlwaysFailsForMessage(TransportMessage message, Exception e) - { - Context.ExceptionType = e.GetType(); - Context.StackTrace = e.StackTrace; - Context.ExceptionReceived = true; - } - - public void Init(Address address) - { - } - } - - class Handler : IHandleMessages - { - [MethodImpl(MethodImplOptions.NoInlining)] - public void Handle(Message message) - { - throw new HandlerException(); - } - } - } - - [Serializable] - public class Message : IMessage - { - } - public class HandlerException : Exception - { - public HandlerException() - : base("HandlerException") - { - - } - } - } - -} \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/Exceptions/When_handler_throws_AggregateException.cs b/src/NServiceBus.AcceptanceTests/Exceptions/When_handler_throws_AggregateException.cs deleted file mode 100644 index 8eaca08b821..00000000000 --- a/src/NServiceBus.AcceptanceTests/Exceptions/When_handler_throws_AggregateException.cs +++ /dev/null @@ -1,140 +0,0 @@ -namespace NServiceBus.AcceptanceTests.Exceptions -{ - using System; - using System.Runtime.CompilerServices; - using NServiceBus.AcceptanceTesting; - using NServiceBus.AcceptanceTests.EndpointTemplates; - using NServiceBus.Config; - using NServiceBus.Faults; - using NServiceBus.Features; - using NUnit.Framework; - - public class When_handler_throws_AggregateException : NServiceBusAcceptanceTest - { - [Test] - public void Should_receive_exact_AggregateException_exception_from_handler() - { - var context = new Context(); - - Scenario.Define(context) - .WithEndpoint(b => b.Given(bus => bus.SendLocal(new Message()))) - .AllowExceptions() - .Done(c => c.ExceptionReceived) - .Run(); - Assert.AreEqual(typeof(AggregateException), context.ExceptionType); - Assert.AreEqual(typeof(Exception), context.InnerExceptionType); - Assert.AreEqual("My Exception", context.ExceptionMessage); - Assert.AreEqual("My Inner Exception", context.InnerExceptionMessage); - -#if (!DEBUG) - StackTraceAssert.StartsWith( - @"at NServiceBus.AcceptanceTests.Exceptions.When_handler_throws_AggregateException.Endpoint.Handler.Handle(Message message) -at NServiceBus.Unicast.MessageHandlerRegistry.Invoke(Object handler, Object message, Dictionary`2 dictionary) -at NServiceBus.InvokeHandlersBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.SetCurrentMessageBeingHandledBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.LoadHandlersBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ApplyIncomingMessageMutatorsBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ExecuteLogicalMessagesBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.CallbackInvocationBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.DeserializeLogicalMessagesBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ApplyIncomingTransportMessageMutatorsBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.SubscriptionReceiverBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.UnitOfWorkBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ChildContainerBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.ProcessingStatisticsBehavior.Invoke(IncomingContext context, Action next) -at NServiceBus.Pipeline.PipelineExecutor.Execute[T](BehaviorChain`1 pipelineAction, T context) -at NServiceBus.Unicast.Transport.TransportReceiver.ProcessMessage(TransportMessage message) -at NServiceBus.Unicast.Transport.TransportReceiver.TryProcess(TransportMessage message) -at NServiceBus.Transports.Msmq.MsmqDequeueStrategy.Action()", context.StackTrace); - - StackTraceAssert.StartsWith( - @"at NServiceBus.AcceptanceTests.Exceptions.When_handler_throws_AggregateException.Endpoint.Handler.MethodThatThrows() -at NServiceBus.AcceptanceTests.Exceptions.When_handler_throws_AggregateException.Endpoint.Handler.Handle(Message message)", context.InnerStackTrace); -#endif - } - - public class Context : ScenarioContext - { - public bool ExceptionReceived { get; set; } - public string StackTrace { get; set; } - public string InnerStackTrace { get; set; } - public Type InnerExceptionType { get; set; } - public string ExceptionMessage { get; set; } - public string InnerExceptionMessage { get; set; } - public Type ExceptionType { get; set; } - } - - public class Endpoint : EndpointConfigurationBuilder - { - public Endpoint() - { - EndpointSetup(b => - { - b.RegisterComponents(c => - { - c.ConfigureComponent(DependencyLifecycle.SingleInstance); - }); - b.DisableFeature(); - }) - .WithConfig(c => - { - c.MaxRetries = 0; - }); - } - - class CustomFaultManager : IManageMessageFailures - { - public Context Context { get; set; } - - public void SerializationFailedForMessage(TransportMessage message, Exception e) - { - } - - public void ProcessingAlwaysFailsForMessage(TransportMessage message, Exception e) - { - Context.ExceptionMessage = e.Message; - Context.StackTrace = e.StackTrace; - Context.ExceptionType = e.GetType(); - if (e.InnerException != null) - { - Context.InnerExceptionMessage = e.InnerException.Message; - Context.InnerExceptionType = e.InnerException.GetType(); - Context.InnerStackTrace = e.InnerException.StackTrace; - } - Context.ExceptionReceived = true; - } - - public void Init(Address address) - { - } - } - - class Handler : IHandleMessages - { - [MethodImpl(MethodImplOptions.NoInlining)] - public void Handle(Message message) - { - try - { - MethodThatThrows(); - } - catch (Exception exception) - { - throw new AggregateException("My Exception", exception); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - void MethodThatThrows() - { - throw new Exception("My Inner Exception"); - } - } - } - - [Serializable] - public class Message : IMessage - { - } - } -} \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj b/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj index 58229d94dfb..779a8ebbbfb 100644 --- a/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj +++ b/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj @@ -90,27 +90,9 @@ - - Code - - - Code - - - Code - Code - - Code - - - Code - - - Code - From e59022d083080e9eb1f7df6ce72e9a76cccf9711 Mon Sep 17 00:00:00 2001 From: Tim Bussmann Date: Wed, 7 Oct 2015 11:14:18 +0200 Subject: [PATCH 7/8] allowing queue creation exceptions --- .../DataBus/When_sending_with_custom_IDataBus.cs | 3 ++- .../Timeout/Hosting/Windows/TimeoutDispatcherProcessor.cs | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/NServiceBus.AcceptanceTests/DataBus/When_sending_with_custom_IDataBus.cs b/src/NServiceBus.AcceptanceTests/DataBus/When_sending_with_custom_IDataBus.cs index 2f406f86eed..62956f93e18 100644 --- a/src/NServiceBus.AcceptanceTests/DataBus/When_sending_with_custom_IDataBus.cs +++ b/src/NServiceBus.AcceptanceTests/DataBus/When_sending_with_custom_IDataBus.cs @@ -21,7 +21,8 @@ public void Should_receive_the_message_the_correctly() Payload = new DataBusProperty(PayloadToSend) }))) .WithEndpoint() - .Done(context => context.ReceivedPayload != null) + .AllowExceptions(e => e.Message.Contains("A queue with the same path name already exists")) + .Done(ctx => ctx.ReceivedPayload != null) .Repeat(r => r.For()) .Should(c => Assert.AreEqual(PayloadToSend, c.ReceivedPayload, "The large payload should be marshalled correctly using the databus")) .Run(); diff --git a/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutDispatcherProcessor.cs b/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutDispatcherProcessor.cs index 673e44d115e..0aa3d4055d1 100644 --- a/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutDispatcherProcessor.cs +++ b/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutDispatcherProcessor.cs @@ -2,7 +2,6 @@ namespace NServiceBus.Timeout.Hosting.Windows { using System; using Core; - using NServiceBus.Pipeline; using NServiceBus.Settings; using Satellites; using Transports; @@ -21,8 +20,6 @@ public TimeoutDispatcherProcessor() public TimeoutPersisterReceiver TimeoutPersisterReceiver { get; set; } - public PipelineExecutor PipelineExecutor { get; set; } - public Configure Configure { get; set; } public Address InputAddress { get; set; } From 3dabcf5bc064b3c305e92cbd5743c94c03d49060 Mon Sep 17 00:00:00 2001 From: Tim Bussmann Date: Wed, 7 Oct 2015 12:41:21 +0200 Subject: [PATCH 8/8] splitting TimeoutPersistenceVersionCheck and Extension classes --- src/NServiceBus.Core/NServiceBus.Core.csproj | 1 + .../Core/TimeoutPersistenceVersionCheck.cs | 19 +------------------ ...TimeoutPersistenceVersionCheckExtension.cs | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 18 deletions(-) create mode 100644 src/NServiceBus.Core/Timeout/Core/TimeoutPersistenceVersionCheckExtension.cs diff --git a/src/NServiceBus.Core/NServiceBus.Core.csproj b/src/NServiceBus.Core/NServiceBus.Core.csproj index b8daf058ff2..d40a546e038 100644 --- a/src/NServiceBus.Core/NServiceBus.Core.csproj +++ b/src/NServiceBus.Core/NServiceBus.Core.csproj @@ -204,6 +204,7 @@ + diff --git a/src/NServiceBus.Core/Timeout/Core/TimeoutPersistenceVersionCheck.cs b/src/NServiceBus.Core/Timeout/Core/TimeoutPersistenceVersionCheck.cs index 49d8154bcd1..9fe35ceac27 100644 --- a/src/NServiceBus.Core/Timeout/Core/TimeoutPersistenceVersionCheck.cs +++ b/src/NServiceBus.Core/Timeout/Core/TimeoutPersistenceVersionCheck.cs @@ -7,24 +7,7 @@ using NServiceBus.Settings; using NServiceBus.Transports; - /// - /// - /// - public static class TimeoutPersistenceVersionCheckExtension - { - /// - /// - /// - /// - /// - public static BusConfiguration SuppressOutdatedTimeoutPersistenceWarning(this BusConfiguration configure) - { - configure.Settings.Set(TimeoutPersistenceVersionCheck.SuppressOutdatedTimeoutPersistenceWarning, true); - return configure; - } - } - - internal class TimeoutPersistenceVersionCheck : IWantToRunWhenConfigurationIsComplete + class TimeoutPersistenceVersionCheck : IWantToRunWhenConfigurationIsComplete { internal const string SuppressOutdatedTimeoutPersistenceWarning = "NServiceBus/suppress-outdated-timeout-persistence-warning"; diff --git a/src/NServiceBus.Core/Timeout/Core/TimeoutPersistenceVersionCheckExtension.cs b/src/NServiceBus.Core/Timeout/Core/TimeoutPersistenceVersionCheckExtension.cs new file mode 100644 index 00000000000..90f04fe937b --- /dev/null +++ b/src/NServiceBus.Core/Timeout/Core/TimeoutPersistenceVersionCheckExtension.cs @@ -0,0 +1,19 @@ +namespace NServiceBus.Timeout.Core +{ + /// + /// Provides methods for suppressing startup checks regarding the selected TimeoutPersistance. + /// + public static class TimeoutPersistenceVersionCheckExtension + { + /// + /// Suppresses warning if selected TimeoutPersistance doesn't contain the hotfix preventing potential message loss. + /// + /// The instance. + /// + public static BusConfiguration SuppressOutdatedTimeoutPersistenceWarning(this BusConfiguration configure) + { + configure.Settings.Set(TimeoutPersistenceVersionCheck.SuppressOutdatedTimeoutPersistenceWarning, true); + return configure; + } + } +} \ No newline at end of file