diff --git a/.gitignore b/.gitignore index 6e225451119..c4cdf00b240 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,6 @@ csx *.ncrunchsolution _NCrunch_NServiceBus/* logs -run-git.cmd \ No newline at end of file +run-git.cmd + +*.jtconfig \ No newline at end of file diff --git a/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.Custom/App.config b/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.Custom/App.config deleted file mode 100644 index 49cc43e1d8f..00000000000 --- a/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.Custom/App.config +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.Custom/Program.cs b/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.Custom/Program.cs index 3e55bd39b07..eeda06c6fff 100644 --- a/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.Custom/Program.cs +++ b/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.Custom/Program.cs @@ -8,7 +8,7 @@ public class Program static void Main() { var bus = Configure.With() - .UnityBuilder() + .DefaultBuilder() .UseTransport() .UnicastBus() .SendOnly(); @@ -21,5 +21,6 @@ static void Main() Console.ReadKey(); } } + public class TestMessage : IMessage{} } diff --git a/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.Custom/SendOnlyEndpoint.Custom.csproj b/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.Custom/SendOnlyEndpoint.Custom.csproj index f1063087680..3f9fb568125 100644 --- a/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.Custom/SendOnlyEndpoint.Custom.csproj +++ b/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.Custom/SendOnlyEndpoint.Custom.csproj @@ -35,33 +35,12 @@ 4 - - ..\..\..\binaries\log4net.dll - - - ..\packages\CommonServiceLocator.1.0\lib\NET35\Microsoft.Practices.ServiceLocation.dll - - - ..\packages\Unity.2.1.505.0\lib\NET35\Microsoft.Practices.Unity.dll - - - ..\packages\Unity.2.1.505.0\lib\NET35\Microsoft.Practices.Unity.Configuration.dll - - - ..\packages\Unity.Interception.2.1.505.0\lib\NET35\Microsoft.Practices.Unity.Interception.dll - - - ..\packages\Unity.Interception.2.1.505.0\lib\NET35\Microsoft.Practices.Unity.Interception.Configuration.dll - ..\..\..\binaries\NServiceBus.dll ..\..\..\binaries\NServiceBus.Core.dll - - ..\..\..\binaries\containers\unity\NServiceBus.ObjectBuilder.Unity.dll - @@ -69,10 +48,6 @@ - - - - \ No newline at end of file diff --git a/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.NServiceBusHost/EndpointConfig.cs b/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.NServiceBusHost/EndpointConfig.cs index 4f8b36c3380..edd2fe74872 100644 --- a/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.NServiceBusHost/EndpointConfig.cs +++ b/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.NServiceBusHost/EndpointConfig.cs @@ -1,9 +1,13 @@ -namespace SendOnlyEndpoint.NServiceBusHost +using NServiceBus.Hosting.Roles; +using NServiceBus.Unicast.Config; + +namespace SendOnlyEndpoint.NServiceBusHost { - using System.Threading; + + using System; using NServiceBus; - public class EndpointConfig : IConfigureThisEndpoint, IWantCustomInitialization + public class EndpointConfig : IConfigureThisEndpoint, IWantCustomInitialization, SendOnly { /// /// Perform initialization logic. @@ -16,8 +20,25 @@ public void Init() .UnicastBus() .SendOnly(); - var messageSender = new Thread(MessageSender.SendMessage); - messageSender.Start(bus); + Console.Out.WriteLine("Press any key to send a message."); + Console.ReadKey(); + bus.Send("SendOnlyDestination@someserver", new TestMessage()); + Console.WriteLine("Message sent to remote endpoint, you can verify this by looking at the outgoing queues in you msmq MMC-snapin"); + } + } + + public class TestMessage : IMessage { } + + public interface SendOnly : IRole + { + + } + + public class RoleSendOnly : IConfigureRole + { + public ConfigUnicastBus ConfigureRole(IConfigureThisEndpoint specifier) + { + return null; } } } diff --git a/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.NServiceBusHost/MessageSender.cs b/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.NServiceBusHost/MessageSender.cs deleted file mode 100644 index 4a8a5ced211..00000000000 --- a/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.NServiceBusHost/MessageSender.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace SendOnlyEndpoint.NServiceBusHost -{ - using System; - using NServiceBus; - - public static class MessageSender - { - public static void SendMessage(object bus) - { - Console.Out.WriteLine("Press any key to send a message."); - Console.ReadKey(); - if ((bus as IBus) != null) - (bus as IBus).Send("SendOnlyDestination@someserver", new TestMessage()); - Console.WriteLine("Message sent to remote endpoint, you can verify this by looking at the outgoing queues in you msmq MMC-snapin"); - } - } - public class TestMessage : IMessage{} -} diff --git a/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.NServiceBusHost/SendOnlyEndpoint.NServiceBusHost.csproj b/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.NServiceBusHost/SendOnlyEndpoint.NServiceBusHost.csproj index 1119f278101..86cbe7bf5a8 100644 --- a/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.NServiceBusHost/SendOnlyEndpoint.NServiceBusHost.csproj +++ b/IntegrationTests/SendOnlyEndpoint/SendOnlyEndpoint.NServiceBusHost/SendOnlyEndpoint.NServiceBusHost.csproj @@ -50,7 +50,6 @@ - diff --git a/IntegrationTests/TimeoutManager/MyServer/Starter.cs b/IntegrationTests/TimeoutManager/MyServer/Starter.cs index d99a0b21c5a..2ced7110972 100644 --- a/IntegrationTests/TimeoutManager/MyServer/Starter.cs +++ b/IntegrationTests/TimeoutManager/MyServer/Starter.cs @@ -1,4 +1,5 @@ using MyServer.Scheduling; +using NServiceBus.Hosting; namespace MyServer { @@ -13,6 +14,8 @@ class Starter : IWantToRunWhenBusStartsAndStops { public IBus Bus { get; set; } + public HostInformation HostInformation { get; set; } + public void Start() { Console.WriteLine("Press 'S' to start the saga"); diff --git a/buildsupport/FubuCore.dll b/buildsupport/FubuCore.dll index bc83892c383..19712e0f596 100644 Binary files a/buildsupport/FubuCore.dll and b/buildsupport/FubuCore.dll differ diff --git a/buildsupport/FubuCore.pdb b/buildsupport/FubuCore.pdb index 2c861d0a3e1..05d9a6e0f81 100644 Binary files a/buildsupport/FubuCore.pdb and b/buildsupport/FubuCore.pdb differ diff --git a/buildsupport/GitFlowVersion/Build/GitFlowVersionTask.targets b/buildsupport/GitFlowVersion/Build/GitFlowVersionTask.targets index a86a24af6b2..368f84e44fb 100644 --- a/buildsupport/GitFlowVersion/Build/GitFlowVersionTask.targets +++ b/buildsupport/GitFlowVersion/Build/GitFlowVersionTask.targets @@ -11,7 +11,8 @@ @@ -32,6 +33,10 @@ + + + + diff --git a/buildsupport/GitFlowVersion/GitFlowVersion.exe b/buildsupport/GitFlowVersion/GitFlowVersion.exe index 67eb8d6f030..df38c906a41 100644 Binary files a/buildsupport/GitFlowVersion/GitFlowVersion.exe and b/buildsupport/GitFlowVersion/GitFlowVersion.exe differ diff --git a/buildsupport/GitFlowVersion/GitFlowVersion.pdb b/buildsupport/GitFlowVersion/GitFlowVersion.pdb index 31104f7f47c..98047eb7413 100644 Binary files a/buildsupport/GitFlowVersion/GitFlowVersion.pdb and b/buildsupport/GitFlowVersion/GitFlowVersion.pdb differ diff --git a/buildsupport/GitFlowVersion/GitFlowVersionTask.dll b/buildsupport/GitFlowVersion/GitFlowVersionTask.dll index b66b7b812fc..ac2dc5bbdf1 100644 Binary files a/buildsupport/GitFlowVersion/GitFlowVersionTask.dll and b/buildsupport/GitFlowVersion/GitFlowVersionTask.dll differ diff --git a/buildsupport/GitFlowVersion/GitFlowVersionTask.pdb b/buildsupport/GitFlowVersion/GitFlowVersionTask.pdb index 2f1e3143d02..34b0222bccb 100644 Binary files a/buildsupport/GitFlowVersion/GitFlowVersionTask.pdb and b/buildsupport/GitFlowVersion/GitFlowVersionTask.pdb differ diff --git a/buildsupport/ripple.exe b/buildsupport/ripple.exe index 6daed2576b2..7d6d4f7df94 100644 Binary files a/buildsupport/ripple.exe and b/buildsupport/ripple.exe differ diff --git a/buildsupport/ripple.pdb b/buildsupport/ripple.pdb index 25d4f108c56..4276c35908b 100644 Binary files a/buildsupport/ripple.pdb and b/buildsupport/ripple.pdb differ diff --git a/lib/ConventionBasedHandlers.dll b/lib/ConventionBasedHandlers.dll deleted file mode 100644 index 7a8889f4477..00000000000 Binary files a/lib/ConventionBasedHandlers.dll and /dev/null differ diff --git a/packaging/nuget/nservicebus.acceptancetesting.nuspec b/packaging/nuget/nservicebus.acceptancetesting.nuspec index 636b08986e3..083e1a355ed 100644 --- a/packaging/nuget/nservicebus.acceptancetesting.nuspec +++ b/packaging/nuget/nservicebus.acceptancetesting.nuspec @@ -12,7 +12,7 @@ true Acceptance tests for nservicebus core functionality - Copyright 2010-2013 NServiceBus. All rights reserved + Copyright 2010-2014 NServiceBus. All rights reserved nservicebus servicebus msmq cqrs publish subscribe diff --git a/packaging/nuget/nservicebus.acceptancetests.nuspec b/packaging/nuget/nservicebus.acceptancetests.sources.nuspec similarity index 81% rename from packaging/nuget/nservicebus.acceptancetests.nuspec rename to packaging/nuget/nservicebus.acceptancetests.sources.nuspec index 4bdfbf4f48e..fe43edd490b 100644 --- a/packaging/nuget/nservicebus.acceptancetests.nuspec +++ b/packaging/nuget/nservicebus.acceptancetests.sources.nuspec @@ -1,8 +1,8 @@  - NServiceBus.AcceptanceTests - NServiceBus Acceptance Tests + NServiceBus.AcceptanceTests.Sources + Source only package containing the NServiceBus acceptance test suite 4.0.0-alpha0 NServiceBus Ltd Udi Dahan, Andreas Ohlund, John Simons @@ -12,11 +12,11 @@ true Acceptance tests for nservicebus core functionality - Copyright 2010-2013 NServiceBus. All rights reserved + Copyright 2010-2014 NServiceBus. All rights reserved nservicebus servicebus msmq cqrs publish subscribe - + - \ No newline at end of file + diff --git a/packaging/nuget/nservicebus.autofac.nuspec b/packaging/nuget/nservicebus.autofac.nuspec index 0539356eedf..80cd1490a2d 100644 --- a/packaging/nuget/nservicebus.autofac.nuspec +++ b/packaging/nuget/nservicebus.autofac.nuspec @@ -12,7 +12,7 @@ true The Autofac Container for the nservicebus - Copyright 2010-2013 NServiceBus. All rights reserved + Copyright 2010-2014 NServiceBus. All rights reserved nservicebus servicebus msmq cqrs publish subscribe diff --git a/packaging/nuget/nservicebus.castlewindsor.nuspec b/packaging/nuget/nservicebus.castlewindsor.nuspec index 74c61578f9f..2b6d4314c88 100644 --- a/packaging/nuget/nservicebus.castlewindsor.nuspec +++ b/packaging/nuget/nservicebus.castlewindsor.nuspec @@ -12,7 +12,7 @@ true The CastleWindsor Container for the nservicebus - Copyright 2010-2013 NServiceBus. All rights reserved + Copyright 2010-2014 NServiceBus. All rights reserved nservicebus servicebus msmq cqrs publish subscribe diff --git a/packaging/nuget/nservicebus.distributor.msmq.nuspec b/packaging/nuget/nservicebus.distributor.msmq.nuspec index 8d37d1ca1a4..fe379bf0940 100644 --- a/packaging/nuget/nservicebus.distributor.msmq.nuspec +++ b/packaging/nuget/nservicebus.distributor.msmq.nuspec @@ -12,7 +12,7 @@ true Distributor for MSMQ for the nservicebus - Copyright 2010-2013 NServiceBus. All rights reserved + Copyright 2010-2014 NServiceBus. All rights reserved nservicebus servicebus msmq cqrs publish subscribe diff --git a/packaging/nuget/nservicebus.host.nuspec b/packaging/nuget/nservicebus.host.nuspec index de3e535e033..008c4ef4046 100644 --- a/packaging/nuget/nservicebus.host.nuspec +++ b/packaging/nuget/nservicebus.host.nuspec @@ -12,7 +12,7 @@ true The hosting template for the nservicebus, The most popular open-source service bus for .net - Copyright 2010-2013 NServiceBus. All rights reserved + Copyright 2010-2014 NServiceBus. All rights reserved nservicebus servicebus msmq cqrs publish subscribe diff --git a/packaging/nuget/nservicebus.host32.nuspec b/packaging/nuget/nservicebus.host32.nuspec index 82720bdf71a..fd9ddab8299 100644 --- a/packaging/nuget/nservicebus.host32.nuspec +++ b/packaging/nuget/nservicebus.host32.nuspec @@ -12,7 +12,7 @@ true The hosting template for the nservicebus, The most popular open-source service bus for .net - Copyright 2010-2013 NServiceBus. All rights reserved + Copyright 2010-2014 NServiceBus. All rights reserved nservicebus servicebus msmq cqrs publish subscribe diff --git a/packaging/nuget/nservicebus.interfaces.nuspec b/packaging/nuget/nservicebus.interfaces.nuspec index c3ad194c006..002ae67aa34 100644 --- a/packaging/nuget/nservicebus.interfaces.nuspec +++ b/packaging/nuget/nservicebus.interfaces.nuspec @@ -12,7 +12,7 @@ true The Interfaces for NServiceBus Implementation - Copyright 2010-2013 NServiceBus. All rights reserved + Copyright 2010-2014 NServiceBus. All rights reserved nservicebus servicebus msmq cqrs publish subscribe diff --git a/packaging/nuget/nservicebus.ninject.nuspec b/packaging/nuget/nservicebus.ninject.nuspec index 0c29c5dc09e..f6edc9355c5 100644 --- a/packaging/nuget/nservicebus.ninject.nuspec +++ b/packaging/nuget/nservicebus.ninject.nuspec @@ -12,7 +12,7 @@ true The Ninject Container for the nservicebus - Copyright 2010-2013 NServiceBus. All rights reserved + Copyright 2010-2014 NServiceBus. All rights reserved nservicebus servicebus msmq cqrs publish subscribe diff --git a/packaging/nuget/nservicebus.nuspec b/packaging/nuget/nservicebus.nuspec index 60fd33884e8..c4c31b1e519 100644 --- a/packaging/nuget/nservicebus.nuspec +++ b/packaging/nuget/nservicebus.nuspec @@ -12,7 +12,7 @@ true The most popular open-source service bus for .net - Copyright 2010-2013 NServiceBus. All rights reserved + Copyright 2010-2014 NServiceBus. All rights reserved nservicebus servicebus msmq cqrs publish subscribe diff --git a/packaging/nuget/nservicebus.spring.nuspec b/packaging/nuget/nservicebus.spring.nuspec index c305461e59b..bc4a53b1ebd 100644 --- a/packaging/nuget/nservicebus.spring.nuspec +++ b/packaging/nuget/nservicebus.spring.nuspec @@ -12,7 +12,7 @@ true The Spring Container for the nservicebus - Copyright 2010-2013 NServiceBus. All rights reserved + Copyright 2010-2014 NServiceBus. All rights reserved nservicebus servicebus msmq cqrs publish subscribe diff --git a/packaging/nuget/nservicebus.structuremap.nuspec b/packaging/nuget/nservicebus.structuremap.nuspec index 099ed3b7f50..06b0f08454b 100644 --- a/packaging/nuget/nservicebus.structuremap.nuspec +++ b/packaging/nuget/nservicebus.structuremap.nuspec @@ -12,7 +12,7 @@ true The StructureMap Container for the nservicebus - Copyright 2010-2013 NServiceBus. All rights reserved + Copyright 2010-2014 NServiceBus. All rights reserved nservicebus servicebus msmq cqrs publish subscribe diff --git a/packaging/nuget/nservicebus.testing.nuspec b/packaging/nuget/nservicebus.testing.nuspec index 60b2f968ed3..eb81c822c9f 100644 --- a/packaging/nuget/nservicebus.testing.nuspec +++ b/packaging/nuget/nservicebus.testing.nuspec @@ -12,7 +12,7 @@ true The testing for the nservicebus, The most popular open-source service bus for .net - Copyright 2010-2013 NServiceBus. All rights reserved + Copyright 2010-2014 NServiceBus. All rights reserved nservicebus servicebus msmq cqrs publish subscribe diff --git a/packaging/nuget/nservicebus.tools.nuspec b/packaging/nuget/nservicebus.tools.nuspec index 6947e49d142..517ec8169a0 100644 --- a/packaging/nuget/nservicebus.tools.nuspec +++ b/packaging/nuget/nservicebus.tools.nuspec @@ -12,7 +12,7 @@ true Return to source queue and licensing tools for uses with NServiceBus - Copyright 2010-2013 NServiceBus. All rights reserved + Copyright 2010-2014 NServiceBus. All rights reserved nservicebus servicebus msmq cqrs publish subscribe diff --git a/packaging/nuget/nservicebus.unity.nuspec b/packaging/nuget/nservicebus.unity.nuspec index cc1688af0ff..fcc019036e7 100644 --- a/packaging/nuget/nservicebus.unity.nuspec +++ b/packaging/nuget/nservicebus.unity.nuspec @@ -12,7 +12,7 @@ true The Unity Container for the nservicebus - Copyright 2010-2013 NServiceBus. All rights reserved + Copyright 2010-2014 NServiceBus. All rights reserved nservicebus servicebus msmq cqrs publish subscribe diff --git a/ripple.cmd b/ripple.cmd new file mode 100644 index 00000000000..74b6af73f06 --- /dev/null +++ b/ripple.cmd @@ -0,0 +1 @@ +buildsupport\ripple.exe %* \ No newline at end of file diff --git a/ripple.config b/ripple.config index 862dc5b5133..4e7928207c9 100644 --- a/ripple.config +++ b/ripple.config @@ -1,5 +1,5 @@ - + NServiceBus packaging/nuget src @@ -8,8 +8,8 @@ Current Current,NextMajor - - + + @@ -19,7 +19,7 @@ - + @@ -45,7 +45,7 @@ - + diff --git a/src/ConventionBasedHandlers/ConventionBasedHandler.cs b/src/ConventionBasedHandlers/ConventionBasedHandler.cs new file mode 100644 index 00000000000..9c346ee8bd8 --- /dev/null +++ b/src/ConventionBasedHandlers/ConventionBasedHandler.cs @@ -0,0 +1,14 @@ +namespace ConventionBasedHandlers +{ + using System; + using ConventionBasedMessages; + using NServiceBus; + + public class ConventionBasedHandler : IHandleMessages + { + public void Handle(MyMessage message) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/src/ConventionBasedHandlers/ConventionBasedHandlers.csproj b/src/ConventionBasedHandlers/ConventionBasedHandlers.csproj new file mode 100644 index 00000000000..7bffd676d7b --- /dev/null +++ b/src/ConventionBasedHandlers/ConventionBasedHandlers.csproj @@ -0,0 +1,56 @@ + + + + Debug + AnyCPU + {2311CBF3-5381-4151-B2D0-EE14A89F870B} + Library + Properties + ConventionBasedHandlers + ConventionBasedHandlers + v4.0 + 512 + true + ..\NServiceBus.snk + ..\ + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\lib\ConventionBasedMessages.dll + + + + + + + + + + + + + + + {73867D40-8CBB-48E9-BFFA-12BBDD48A341} + NServiceBus + + + + \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTesting/EndpointConfigurationBuilder.cs b/src/NServiceBus.AcceptanceTesting/EndpointConfigurationBuilder.cs index bdf80f07bba..6ef6158a244 100644 --- a/src/NServiceBus.AcceptanceTesting/EndpointConfigurationBuilder.cs +++ b/src/NServiceBus.AcceptanceTesting/EndpointConfigurationBuilder.cs @@ -2,7 +2,6 @@ { using System; using System.Collections.Generic; - using System.Threading; using Support; public class EndpointConfigurationBuilder : IEndpointConfigurationFactory @@ -83,39 +82,7 @@ EndpointConfiguration IEndpointConfigurationFactory.Get() return CreateScenario(); } - public class SubscriptionsSpy : IAuthorizeSubscriptions - { - private readonly ManualResetEvent manualResetEvent = new ManualResetEvent(false); - private int subscriptionsReceived; - - public int NumberOfSubscriptionsToWaitFor { get; set; } - - public bool AuthorizeSubscribe(string messageType, string clientEndpoint, - IDictionary headers) - { - if (Interlocked.Increment(ref subscriptionsReceived) >= NumberOfSubscriptionsToWaitFor) - { - manualResetEvent.Set(); - } - - return true; - } - - public bool AuthorizeUnsubscribe(string messageType, string clientEndpoint, - IDictionary headers) - { - return true; - } - - public void Wait() - { - if(!manualResetEvent.WaitOne(TimeSpan.FromSeconds(20))) - throw new Exception("No subscription message was received"); - - } - } - - + readonly EndpointConfiguration configuration = new EndpointConfiguration(); public EndpointConfigurationBuilder WithConfig(Action action) diff --git a/src/NServiceBus.AcceptanceTesting/NServiceBus.AcceptanceTesting.csproj b/src/NServiceBus.AcceptanceTesting/NServiceBus.AcceptanceTesting.csproj index 45fb80013af..91064ee4c76 100644 --- a/src/NServiceBus.AcceptanceTesting/NServiceBus.AcceptanceTesting.csproj +++ b/src/NServiceBus.AcceptanceTesting/NServiceBus.AcceptanceTesting.csproj @@ -11,6 +11,7 @@ NServiceBus.AcceptanceTesting v4.0 512 + ..\ true @@ -68,9 +69,9 @@ {dd48b2d0-e996-412d-9157-821ed8b17a9d} NServiceBus.Core - + {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus diff --git a/src/NServiceBus.AcceptanceTesting/Properties/AssemblyInfo.cs b/src/NServiceBus.AcceptanceTesting/Properties/AssemblyInfo.cs index 2e0ade7493d..26a9f8f1187 100644 --- a/src/NServiceBus.AcceptanceTesting/Properties/AssemblyInfo.cs +++ b/src/NServiceBus.AcceptanceTesting/Properties/AssemblyInfo.cs @@ -2,4 +2,4 @@ [assembly: AssemblyTitle("NServiceBus.AcceptanceTesting")] [assembly: AssemblyProduct("NServiceBus.AcceptanceTesting")] -[assembly: AssemblyCopyright("Copyright 2010-2013 NServiceBus. All rights reserved")] +[assembly: AssemblyCopyright("Copyright 2010-2014 NServiceBus. All rights reserved")] diff --git a/src/NServiceBus.AcceptanceTesting/Scenario.cs b/src/NServiceBus.AcceptanceTesting/Scenario.cs index 482cb3c977c..6d95b61fd46 100644 --- a/src/NServiceBus.AcceptanceTesting/Scenario.cs +++ b/src/NServiceBus.AcceptanceTesting/Scenario.cs @@ -43,12 +43,12 @@ public IScenarioWithEndpointBehavior WithEndpoint() where T : Endpo return WithEndpoint(b => { }); } - public IScenarioWithEndpointBehavior WithEndpoint(Action> defineBehaviour) where T : EndpointConfigurationBuilder + public IScenarioWithEndpointBehavior WithEndpoint(Action> defineBehavior) where T : EndpointConfigurationBuilder { var builder = new EndpointBehaviorBuilder(typeof (T)); - defineBehaviour(builder); + defineBehavior(builder); behaviours.Add(builder.Build()); diff --git a/src/NServiceBus.AcceptanceTesting/Support/ScenarioConfigSource.cs b/src/NServiceBus.AcceptanceTesting/Support/ScenarioConfigSource.cs index d15c56f4f6e..051586635a8 100644 --- a/src/NServiceBus.AcceptanceTesting/Support/ScenarioConfigSource.cs +++ b/src/NServiceBus.AcceptanceTesting/Support/ScenarioConfigSource.cs @@ -21,15 +21,20 @@ public ScenarioConfigSource(EndpointConfiguration configuration, IDictionary(b => b.Given((bus, c) => bus.Defer(TimeSpan.FromSeconds(3), new MyMessage()))) + .Done(c => c.WasCalled) + .Run(); + + Assert.IsTrue(context.WasCalled); + } + + public class Context : ScenarioContext + { + public bool WasCalled { get; set; } + } + + public class Endpoint : EndpointConfigurationBuilder + { + public Endpoint() + { + EndpointSetup(); + } + public class MyMessageHandler : IHandleMessages + { + public Context Context { get; set; } + + public IBus Bus { get; set; } + + public void Handle(MyMessage message) + { + Context.WasCalled = true; + } + } + } + + [Serializable] + public class MyMessage : IMessage + { + } + } +} diff --git a/src/NServiceBus.AcceptanceTests/BasicMessaging/When_sending_a_message_to_another_endpoint.cs b/src/NServiceBus.AcceptanceTests/BasicMessaging/When_sending_a_message_to_another_endpoint.cs index beee319dbd7..b4eb710510a 100644 --- a/src/NServiceBus.AcceptanceTests/BasicMessaging/When_sending_a_message_to_another_endpoint.cs +++ b/src/NServiceBus.AcceptanceTests/BasicMessaging/When_sending_a_message_to_another_endpoint.cs @@ -31,9 +31,7 @@ public void Should_receive_the_message() { Assert.True(c.WasCalled, "The message handler should be called"); Assert.AreEqual(1, c.TimesCalled, "The message handler should only be invoked once"); - Assert.AreEqual(Environment.MachineName, c.ReceivedHeaders[Headers.OriginatingMachine], "The sender should attach the machine name as a header"); Assert.True(c.ReceivedHeaders[Headers.OriginatingEndpoint].Contains("Sender"), "The sender should attach its endpoint name as a header"); - Assert.AreEqual(Environment.MachineName, c.ReceivedHeaders[Headers.ProcessingMachine], "The receiver should attach the machine name as a header"); Assert.True(c.ReceivedHeaders[Headers.ProcessingEndpoint].Contains("Receiver"), "The receiver should attach its endpoint name as a header"); Assert.AreEqual("StaticHeaderValue",c.ReceivedHeaders["MyStaticHeader"], "Static headers should be attached to outgoing messages"); Assert.AreEqual("MyHeaderValue", c.MyHeader, "Static headers should be attached to outgoing messages"); diff --git a/src/NServiceBus.AcceptanceTests/BasicMessaging/When_using_a_message_with_TimeToBeReceived_has_expired.cs b/src/NServiceBus.AcceptanceTests/BasicMessaging/When_using_a_message_with_TimeToBeReceived_has_expired.cs new file mode 100644 index 00000000000..a2ffe5b215d --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/BasicMessaging/When_using_a_message_with_TimeToBeReceived_has_expired.cs @@ -0,0 +1,62 @@ +namespace NServiceBus.AcceptanceTests.BasicMessaging +{ + using System; + using System.Threading; + using EndpointTemplates; + using AcceptanceTesting; + using NUnit.Framework; + + public class When_using_a_message_with_TimeToBeReceived_has_expired : NServiceBusAcceptanceTest + { + [Test] + public void Message_should_not_be_received() + { + var context = new Context(); + + var timeToWaitFor = DateTime.Now.AddSeconds(10); + Scenario.Define(context) + .WithEndpoint(b => b.Given((bus, c) => bus.SendLocal(new MyMessage()))) + .Done(c => DateTime.Now > timeToWaitFor ) + .Run(); + Assert.IsFalse(context.WasCalled); + } + + public class Context : ScenarioContext + { + public bool WasCalled { get; set; } + } + + public class Endpoint : EndpointConfigurationBuilder + { + public Endpoint() + { + EndpointSetup(); + } + public class MyMessageHandler : IHandleMessages + { + static bool hasSkipped; + public Context Context { get; set; } + + public IBus Bus { get; set; } + + public void Handle(MyMessage message) + { + if (!hasSkipped) + { + hasSkipped = true; + Thread.Sleep(TimeSpan.FromSeconds(2)); + Bus.HandleCurrentMessageLater(); + return; + } + Context.WasCalled = true; + } + } + } + + [Serializable] + [TimeToBeReceived("00:00:01")] + public class MyMessage : IMessage + { + } + } +} diff --git a/src/NServiceBus.AcceptanceTests/BasicMessaging/When_using_a_message_with_TimeToBeReceived_has_not_expired.cs b/src/NServiceBus.AcceptanceTests/BasicMessaging/When_using_a_message_with_TimeToBeReceived_has_not_expired.cs new file mode 100644 index 00000000000..a516e51daa8 --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/BasicMessaging/When_using_a_message_with_TimeToBeReceived_has_not_expired.cs @@ -0,0 +1,53 @@ +namespace NServiceBus.AcceptanceTests.BasicMessaging +{ + using System; + using EndpointTemplates; + using AcceptanceTesting; + using NUnit.Framework; + + public class When_using_a_message_with_TimeToBeReceived_has_not_expired : NServiceBusAcceptanceTest + { + [Test] + public void Message_should_be_received() + { + var context = new Context(); + + Scenario.Define(context) + .WithEndpoint(b => b.Given((bus, c) => bus.SendLocal(new MyMessage()))) + .Done(c => c.WasCalled) + .Run(); + + Assert.IsTrue(context.WasCalled); + } + + public class Context : ScenarioContext + { + public bool WasCalled { get; set; } + } + + public class Endpoint : EndpointConfigurationBuilder + { + public Endpoint() + { + EndpointSetup(); + } + public class MyMessageHandler : IHandleMessages + { + public Context Context { get; set; } + + public IBus Bus { get; set; } + + public void Handle(MyMessage message) + { + Context.WasCalled = true; + } + } + } + + [Serializable] + [TimeToBeReceived("00:00:10")] + public class MyMessage : IMessage + { + } + } +} diff --git a/src/NServiceBus.AcceptanceTests/BusStartStop/When_bus_start_raises_an_inmemory_message.cs b/src/NServiceBus.AcceptanceTests/BusStartStop/When_bus_start_raises_an_inmemory_message.cs new file mode 100644 index 00000000000..2a54bba8871 --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/BusStartStop/When_bus_start_raises_an_inmemory_message.cs @@ -0,0 +1,68 @@ +namespace NServiceBus.AcceptanceTests.BusStartStop +{ + using System; + using EndpointTemplates; + using AcceptanceTesting; + using NUnit.Framework; + using ScenarioDescriptors; + + public class When_bus_start_raises_an_inmemory_message : NServiceBusAcceptanceTest + { + [Test] + public void Should_not_throw() + { + var context = new Context(); + + Scenario.Define(context) + .WithEndpoint() + .Done(c => c.GotMessage) + .Repeat(r => r.For()) + .Run(); + } + + public class Context : ScenarioContext + { + public bool GotMessage; + } + + public class Endpoint : EndpointConfigurationBuilder + { + public Endpoint() + { + EndpointSetup(); + } + + class MessageHandler : IHandleMessages + { + public Context Context { get; set; } + + public void Handle(Message message) + { + Context.GotMessage = true; + } + } + } + + public class Foo : IWantToRunWhenBusStartsAndStops + { + public IBus Bus { get; set; } + + public void Start() + { + Bus.InMemory.Raise(new Message()); + } + + public void Stop() + { + } + } + + [Serializable] + public class Message : IMessage + { + } + + } + + +} \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/Distributor/When_using_master.cs b/src/NServiceBus.AcceptanceTests/Distributor/When_using_master.cs deleted file mode 100644 index a8b0bec71eb..00000000000 --- a/src/NServiceBus.AcceptanceTests/Distributor/When_using_master.cs +++ /dev/null @@ -1,99 +0,0 @@ -namespace NServiceBus.AcceptanceTests.Distributor -{ - using System; - using System.Threading; - using Config; - using EndpointTemplates; - using AcceptanceTesting; - using NUnit.Framework; - - public class When_using_master : NServiceBusAcceptanceTest - { - [Test] - public void Master_and_workers_should_receive_messages() - { - var context = new Context(); - - Scenario.Define(context) - .WithEndpoint(e => e.Given(bus => - { - bus.Send(new MyMessage()); - bus.Send(new MyMessage()); - })) - .WithEndpoint() - .WithEndpoint() - .Done(c => c.MasterGotMessage && c.Worker1GotMessage) - .Run(); - - Assert.IsTrue(context.MasterGotMessage); - Assert.IsTrue(context.Worker1GotMessage); - } - - class Context : ScenarioContext - { - public bool MasterGotMessage { get; set; } - public bool Worker1GotMessage { get; set; } - } - - class Sender : EndpointConfigurationBuilder - { - public Sender() - { - EndpointSetup() - .AddMapping(typeof(MasterEndpoint)); - } - } - - class MasterEndpoint : EndpointConfigurationBuilder - { - public MasterEndpoint() - { - EndpointSetup(c => c.AsMSMQMasterNode()).WithConfig(c => - { - c.MaximumConcurrencyLevel = 1; - }); - - } - - public class Handler : IHandleMessages - { - public Context Context { get; set; } - - public void Handle(MyMessage message) - { - Context.MasterGotMessage = true; - Thread.Sleep(3000); - } - } - } - - class Worker1Endpoint : EndpointConfigurationBuilder - { - public Worker1Endpoint() - { - EndpointSetup(c => c.EnlistWithMSMQDistributor()).WithConfig(c => - { - c.MaximumConcurrencyLevel = 1; - }) - .WithConfig(c=> c.Node = "localhost") - .WithConfig(c=> c.DistributorDataAddress = "distributor.masterendpoint.msmq"); - } - - public class Handler : IHandleMessages - { - public Context Context { get; set; } - - public void Handle(MyMessage message) - { - Context.Worker1GotMessage = true; - } - } - } - - [Serializable] - public class MyMessage : ICommand - { - - } - } -} \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/EndpointTemplates/BusExtensions.cs b/src/NServiceBus.AcceptanceTests/EndpointTemplates/BusExtensions.cs deleted file mode 100644 index 6c087c00955..00000000000 --- a/src/NServiceBus.AcceptanceTests/EndpointTemplates/BusExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace NServiceBus.AcceptanceTests.EndpointTemplates -{ - using AcceptanceTesting; - - public static class BusExtensions - { - public static void EnsureSubscriptionMessagesHaveArrived(this IBus bus) - { - Configure.Instance.Builder.Build() - .Wait(); - } - } -} \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/EndpointTemplates/ConfigureExtensions.cs b/src/NServiceBus.AcceptanceTests/EndpointTemplates/ConfigureExtensions.cs index ab17ea5b663..959d31edeb4 100644 --- a/src/NServiceBus.AcceptanceTests/EndpointTemplates/ConfigureExtensions.cs +++ b/src/NServiceBus.AcceptanceTests/EndpointTemplates/ConfigureExtensions.cs @@ -2,7 +2,6 @@ { using System; using System.Collections.Generic; - using AcceptanceTesting; using ObjectBuilder.Common; using ObjectBuilder.Common.Config; using ScenarioDescriptors; @@ -27,14 +26,6 @@ public static string GetOrNull(this IDictionary dictionary, stri return dictionary[key]; } - public static Configure DefineHowManySubscriptionMessagesToWaitFor(this Configure config, int numberOfSubscriptionsToWaitFor) - { - config.Configurer.ConfigureProperty( - spy => spy.NumberOfSubscriptionsToWaitFor, numberOfSubscriptionsToWaitFor); - - return config; - } - public static Configure DefineTransport(this Configure config, IDictionary settings) { if (!settings.ContainsKey("Transport")) diff --git a/src/NServiceBus.AcceptanceTests/Gateway/When_doing_request_return.cs b/src/NServiceBus.AcceptanceTests/Gateway/When_doing_request_return.cs index 17dabcf0dc7..25480cbaa1d 100644 --- a/src/NServiceBus.AcceptanceTests/Gateway/When_doing_request_return.cs +++ b/src/NServiceBus.AcceptanceTests/Gateway/When_doing_request_return.cs @@ -36,6 +36,7 @@ public SiteA() { EndpointSetup(c => c.RunGateway() .UseInMemoryGatewayPersister()) + .AllowExceptions() .WithConfig(c => { c.Sites = new SiteCollection @@ -66,6 +67,7 @@ public class SiteB : EndpointConfigurationBuilder public SiteB() { EndpointSetup(c => c.RunGateway().UseInMemoryGatewayPersister()) + .AllowExceptions() .WithConfig(c => { c.Channels = new ChannelCollection diff --git a/src/NServiceBus.AcceptanceTests/Gateway/When_sending_a_message_via_the_gateway.cs b/src/NServiceBus.AcceptanceTests/Gateway/When_sending_a_message_via_the_gateway.cs index 4e29a79b246..0d5302f69a7 100644 --- a/src/NServiceBus.AcceptanceTests/Gateway/When_sending_a_message_via_the_gateway.cs +++ b/src/NServiceBus.AcceptanceTests/Gateway/When_sending_a_message_via_the_gateway.cs @@ -81,7 +81,11 @@ public class Headquarters : EndpointConfigurationBuilder { public Headquarters() { - EndpointSetup(c => c.RunGateway().UseInMemoryGatewayPersister()) + EndpointSetup(c => + { + c.RunGateway().UseInMemoryGatewayPersister(); + Configure.Serialization.Xml(); + }) .IncludeType() .AllowExceptions() .WithConfig(c => diff --git a/src/NServiceBus.AcceptanceTests/HostInformation/When_a_message_is_received.cs b/src/NServiceBus.AcceptanceTests/HostInformation/When_a_message_is_received.cs new file mode 100644 index 00000000000..17658cbbac5 --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/HostInformation/When_a_message_is_received.cs @@ -0,0 +1,74 @@ +namespace NServiceBus.AcceptanceTests.HostInformation +{ + using System; + using Config; + using EndpointTemplates; + using AcceptanceTesting; + using NUnit.Framework; + using Unicast; + + public class When_a_message_is_received : NServiceBusAcceptanceTest + { + static Guid hostId = new Guid("39365055-daf2-439e-b84d-acbef8fd803d"); + const string displayName = "FooBar"; + const string displayInstanceIdentifier = "FooBar is great!"; + + [Test] + public void Host_information_should_be_available_in_headers() + { + var context = new Context(); + + Scenario.Define(context) + .WithEndpoint(e => e.Given(b => b.SendLocal(new MyMessage()))) + .Done(c => c.HostId != Guid.Empty) + .Run(); + + Assert.AreEqual(hostId, context.HostId); + Assert.AreEqual(displayName, context.HostDisplayName); + } + + public class Context : ScenarioContext + { + public Guid HostId { get; set; } + public string HostDisplayName { get; set; } + } + + [Serializable] + public class MyMessage : ICommand + { + } + + public class MyMessageHandler : IHandleMessages + { + public Context Context { get; set; } + + public void Handle(MyMessage message) + { + Context.HostId = new Guid(message.GetHeader(Headers.HostId)); + Context.HostDisplayName = message.GetHeader(Headers.HostDisplayName); + } + } + + public class MyEndpoint : EndpointConfigurationBuilder + { + public MyEndpoint() + { + EndpointSetup(); + } + } + + class OverrideHostInformation : IWantToRunWhenConfigurationIsComplete + { + public UnicastBus UnicastBus { get; set; } + + public void Run() + { +#pragma warning disable 618 + var hostInformation = new Hosting.HostInformation(hostId, displayName, displayInstanceIdentifier); +#pragma warning restore 618 + + UnicastBus.HostInformation = hostInformation; + } + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/InMemory/When_calling_DoNotContinueDispatchingCurrentMessageToHandlers_from_inmemory.cs b/src/NServiceBus.AcceptanceTests/InMemory/When_calling_DoNotContinueDispatchingCurrentMessageToHandlers_from_inmemory.cs index 357a94f06de..1be685dd16f 100644 --- a/src/NServiceBus.AcceptanceTests/InMemory/When_calling_DoNotContinueDispatchingCurrentMessageToHandlers_from_inmemory.cs +++ b/src/NServiceBus.AcceptanceTests/InMemory/When_calling_DoNotContinueDispatchingCurrentMessageToHandlers_from_inmemory.cs @@ -3,6 +3,7 @@ using System; using AcceptanceTesting; using EndpointTemplates; + using Features; using NUnit.Framework; public class When_calling_DoNotContinueDispatchingCurrentMessageToHandlers_from_inmemory : NServiceBusAcceptanceTest @@ -45,7 +46,7 @@ public class MyEndpoint : EndpointConfigurationBuilder { public MyEndpoint() { - EndpointSetup(); + EndpointSetup(c => Configure.Features.Disable()); } class EnsureOrdering : ISpecifyMessageHandlerOrdering diff --git a/src/NServiceBus.AcceptanceTests/InMemory/When_raising_an_in_memory_event.cs b/src/NServiceBus.AcceptanceTests/InMemory/When_raising_an_in_memory_event.cs index a31ca184e2a..e8fad151dc7 100644 --- a/src/NServiceBus.AcceptanceTests/InMemory/When_raising_an_in_memory_event.cs +++ b/src/NServiceBus.AcceptanceTests/InMemory/When_raising_an_in_memory_event.cs @@ -3,6 +3,7 @@ using System; using EndpointTemplates; using AcceptanceTesting; + using Features; using NUnit.Framework; public class When_raising_an_in_memory_event : NServiceBusAcceptanceTest @@ -32,7 +33,7 @@ public class InMemoryEndpoint : EndpointConfigurationBuilder { public InMemoryEndpoint() { - EndpointSetup(); + EndpointSetup(c => Configure.Features.Disable()); } public class CommandHandler : IHandleMessages diff --git a/src/NServiceBus.AcceptanceTests/InMemory/When_raising_an_in_memory_event_from_a_non_handler.cs b/src/NServiceBus.AcceptanceTests/InMemory/When_raising_an_in_memory_event_from_a_non_handler.cs index 566ab6a2e57..1e514ea0297 100644 --- a/src/NServiceBus.AcceptanceTests/InMemory/When_raising_an_in_memory_event_from_a_non_handler.cs +++ b/src/NServiceBus.AcceptanceTests/InMemory/When_raising_an_in_memory_event_from_a_non_handler.cs @@ -3,6 +3,7 @@ using System; using EndpointTemplates; using AcceptanceTesting; + using Features; using NUnit.Framework; public class When_raising_an_in_memory_event_from_a_non_handler : NServiceBusAcceptanceTest @@ -30,7 +31,7 @@ public class InMemoryEndpoint : EndpointConfigurationBuilder { public InMemoryEndpoint() { - EndpointSetup(); + EndpointSetup(c => Configure.Features.Disable()); } public class StartUpRunner : IWantToRunWhenBusStartsAndStops diff --git a/src/NServiceBus.AcceptanceTests/InMemory/When_raising_an_in_memory_event_transport_mutators_should_not_be_called.cs b/src/NServiceBus.AcceptanceTests/InMemory/When_raising_an_in_memory_event_transport_mutators_should_not_be_called.cs index 657ad2b0a4b..d095da74e87 100644 --- a/src/NServiceBus.AcceptanceTests/InMemory/When_raising_an_in_memory_event_transport_mutators_should_not_be_called.cs +++ b/src/NServiceBus.AcceptanceTests/InMemory/When_raising_an_in_memory_event_transport_mutators_should_not_be_called.cs @@ -3,6 +3,7 @@ using System; using EndpointTemplates; using AcceptanceTesting; + using Features; using MessageMutator; using NUnit.Framework; @@ -51,7 +52,7 @@ public class InMemoryEndpoint : EndpointConfigurationBuilder { public InMemoryEndpoint() { - EndpointSetup(); + EndpointSetup(c => Configure.Features.Disable()); } } diff --git a/src/NServiceBus.AcceptanceTests/MessageMutators/When_defining_outoing_message_mutators.cs b/src/NServiceBus.AcceptanceTests/MessageMutators/When_defining_outoing_message_mutators.cs new file mode 100644 index 00000000000..40cabaa7f42 --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/MessageMutators/When_defining_outoing_message_mutators.cs @@ -0,0 +1,95 @@ +namespace NServiceBus.AcceptanceTests.Sagas +{ + using System; + using EndpointTemplates; + using AcceptanceTesting; + using MessageMutator; + using NUnit.Framework; + + public class When_defining_outoing_message_mutators : NServiceBusAcceptanceTest + { + [Test] + public void Should_be_applied_to_outgoing_messages() + { + var context = new Context(); + + Scenario.Define(context) + .WithEndpoint(b => b.Given(bus => bus.SendLocal(new MessageToBeMutated()))) + .Done(c => c.MessageProcessed) + .Run(); + + Assert.True(context.TransportMutatorCalled); + Assert.True(context.MessageMutatorCalled); + } + + public class Context : ScenarioContext + { + public bool MessageProcessed { get; set; } + public bool TransportMutatorCalled { get; set; } + public bool MessageMutatorCalled { get; set; } + } + + public class OutgoingMutatatorEndpoint : EndpointConfigurationBuilder + { + public OutgoingMutatatorEndpoint() + { + EndpointSetup(); + } + + + class MyTransportMessageMutator:IMutateOutgoingTransportMessages,INeedInitialization + { + public void MutateOutgoing(object[] messages, TransportMessage transportMessage) + { + transportMessage.Headers["TransportMutatorCalled"] = true.ToString(); + } + + public void Init() + { + Configure.Component(DependencyLifecycle.InstancePerCall); + } + } + + class MyMessageMutator : IMutateOutgoingMessages, INeedInitialization + { + + + public object MutateOutgoing(object message) + { + Headers.SetMessageHeader(message,"MessageMutatorCalled","true"); + + return message; + } + + public void Init() + { + Configure.Component(DependencyLifecycle.InstancePerCall); + } + + } + + class MessageToBeMutatedHandler : IHandleMessages + { + public Context Context { get; set; } + + public IBus Bus { get; set; } + + + public void Handle(MessageToBeMutated message) + { + Context.TransportMutatorCalled = Bus.CurrentMessageContext.Headers.ContainsKey("TransportMutatorCalled"); + Context.MessageMutatorCalled = Bus.CurrentMessageContext.Headers.ContainsKey("MessageMutatorCalled"); + + Context.MessageProcessed = true; + + } + } + + } + + [Serializable] + public class MessageToBeMutated : ICommand + { + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj b/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj index 8942b01652a..dc3276c7b1c 100644 --- a/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj +++ b/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj @@ -11,6 +11,7 @@ NServiceBus.AcceptanceTests v4.0 512 + ..\ true @@ -99,6 +100,13 @@ + + + + + + + @@ -110,9 +118,7 @@ - - @@ -126,14 +132,11 @@ - - - - + - + @@ -211,9 +214,9 @@ {dd48b2d0-e996-412d-9157-821ed8b17a9d} NServiceBus.Core - + {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus {758357f6-cd31-4337-80c4-ba377fc257af} diff --git a/src/NServiceBus.AcceptanceTests/NServiceBusAcceptanceTest.cs b/src/NServiceBus.AcceptanceTests/NServiceBusAcceptanceTest.cs index 1288d83d0fa..60fbe360e24 100644 --- a/src/NServiceBus.AcceptanceTests/NServiceBusAcceptanceTest.cs +++ b/src/NServiceBus.AcceptanceTests/NServiceBusAcceptanceTest.cs @@ -6,8 +6,9 @@ namespace NServiceBus.AcceptanceTests /// /// Base class for all the NSB test that sets up our conventions /// - [TestFixture] - public abstract class NServiceBusAcceptanceTest + [TestFixture] +// ReSharper disable once PartialTypeWithSinglePart + public abstract partial class NServiceBusAcceptanceTest { [SetUp] public void SetUp() @@ -16,7 +17,8 @@ public void SetUp() { var baseNs = typeof (NServiceBusAcceptanceTest).Namespace; var testName = GetType().Name; - return t.FullName.Replace(baseNs + ".", "").Replace(testName + "+", ""); + return t.FullName.Replace(baseNs + ".", "").Replace(testName + "+", "") + + "." + System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(testName).Replace("_", ""); }; Conventions.DefaultRunDescriptor = () => ScenarioDescriptors.Transports.Default; diff --git a/src/NServiceBus.AcceptanceTests/Performance/NServiceBusPerformanceTest.cs b/src/NServiceBus.AcceptanceTests/Performance/NServiceBusPerformanceTest.cs deleted file mode 100644 index af1284e1407..00000000000 --- a/src/NServiceBus.AcceptanceTests/Performance/NServiceBusPerformanceTest.cs +++ /dev/null @@ -1,79 +0,0 @@ -namespace NServiceBus.AcceptanceTests.Performance -{ - using System; - using System.Diagnostics; - using System.IO; - using System.Linq; - using AcceptanceTesting; - using AcceptanceTesting.Support; - - public abstract class NServiceBusPerformanceTest : NServiceBusAcceptanceTest - { - protected static int NumberOfTestMessages - { - get - { - int nr; - - if (!int.TryParse(Environment.GetEnvironmentVariable("NServiceBus.MaxMessagesForPerformanceTests"), out nr)) - { - return 3000; - } - - return nr; - } - } - - protected static int MaxConcurrencyLevel - { - get - { - int nr; - - if (!int.TryParse(Environment.GetEnvironmentVariable("NServiceBus.MaxConcurrencyLevel"), out nr)) - { - return 15; - } - - return nr; - } - } - - protected static void DisplayTestResults(RunSummary summary) - { - var caller = - new StackTrace().GetFrames() - .First(f => typeof(NServiceBusPerformanceTest).IsAssignableFrom(f.GetMethod().DeclaringType.BaseType)); - - var testCategory = - caller.GetMethod() - .DeclaringType.Namespace.Replace(typeof(NServiceBusPerformanceTest).Namespace + ".", ""); - var testCase = caller.GetMethod().Name; - - var c = (PerformanceTestContext)summary.RunDescriptor.ScenarioContext; - - var messagesPerSecondsProcessed = c.NumberOfTestMessages/ - (c.LastMessageProcessedAt - c.FirstMessageProcessedAt).TotalSeconds; - - Console.Out.WriteLine("Results: {0} messages, {1} msg/s", c.NumberOfTestMessages, - messagesPerSecondsProcessed); - - using (var file = new StreamWriter(".\\PerformanceTestResults.txt", true)) - { - file.WriteLine(string.Join(";", summary.RunDescriptor.Key, testCategory, testCase, - c.NumberOfTestMessages, messagesPerSecondsProcessed)); - } - - Console.Out.WriteLine("##teamcity[buildStatisticValue key='{0}' value='{1:0}']", - summary.RunDescriptor.Key + "." + testCategory + "." + testCase, messagesPerSecondsProcessed); - } - } - - public class PerformanceTestContext : ScenarioContext - { - public DateTime FirstMessageProcessedAt { get; set; } - - public DateTime LastMessageProcessedAt { get; set; } - public int NumberOfTestMessages; - } -} \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/Performance/Receive/Receive_performance.cs b/src/NServiceBus.AcceptanceTests/Performance/Receive/Receive_performance.cs deleted file mode 100644 index feb0096f984..00000000000 --- a/src/NServiceBus.AcceptanceTests/Performance/Receive/Receive_performance.cs +++ /dev/null @@ -1,132 +0,0 @@ -namespace NServiceBus.AcceptanceTests.Performance.Receive -{ - using System; - using System.Threading; - using System.Threading.Tasks; - using AcceptanceTesting; - using AcceptanceTesting.Support; - using Config; - using EndpointTemplates; - using NUnit.Framework; - using ScenarioDescriptors; - - public class Receive_performance : NServiceBusPerformanceTest - { - [Test] - public void With_dtc_enabled() - { - Scenario.Define(() => new Context { NumberOfTestMessages = NumberOfTestMessages }) - .WithEndpoint(SendTestMessages) - .Done(c => c.Complete) - .Repeat(r => r.For(Transports.Default)) - .Report(DisplayTestResults) - .MaxTestParallelism(1) - .Run(); - } - - [Test] - public void With_dtc_suppressed() - { - - Scenario.Define(() => new Context { NumberOfTestMessages = NumberOfTestMessages }) - .WithEndpoint(b => - { - b.CustomConfig(c => Configure.Transactions.Advanced(a => a.DisableDistributedTransactions())); - SendTestMessages(b); - }) - .Done(c => c.Complete) - .Repeat(r => r.For(Transports.Default)) - .Report(DisplayTestResults) - .MaxTestParallelism(1) - .Run(); - } - - [Test] - public void With_no_transactions() - { - - Scenario.Define(() => new Context { NumberOfTestMessages = NumberOfTestMessages }) - .WithEndpoint(b => - { - b.CustomConfig(c => Configure.Transactions.Disable()); - SendTestMessages(b); - }) - .Done(c => c.Complete) - .Repeat(r => r.For(Transports.Default)) - .Report(DisplayTestResults) - .MaxTestParallelism(1) - .Run(); - } - - [Test] - public void With_ambient_tx_suppressed() - { - - Scenario.Define(() => new Context { NumberOfTestMessages = NumberOfTestMessages }) - .WithEndpoint(b => - { - b.CustomConfig(c => Configure.Transactions.Advanced(a => a.DoNotWrapHandlersExecutionInATransactionScope())); - SendTestMessages(b); - }) - .Done(c => c.Complete) - .Repeat(r => r.For(Transports.Default)) - .Report(DisplayTestResults) - .MaxTestParallelism(1) - .Run(); - } - - - public class Context : PerformanceTestContext - { - - - public bool Complete { get; set; } - } - - public class ReceiveEndpoint : EndpointConfigurationBuilder - { - public ReceiveEndpoint() - { - EndpointSetup() - .WithConfig(c => c.MaximumConcurrencyLevel = MaxConcurrencyLevel); - } - - public class MyMessageHandler : IHandleMessages - { - public Context Context { get; set; } - - static int numberOfMessagesProcessed; - - - public void Handle(MyMessage messageThatIsEnlisted) - { - var current = Interlocked.Increment(ref numberOfMessagesProcessed); - - if (current == 1) - { - Context.FirstMessageProcessedAt = DateTime.UtcNow; - } - - if (current == Context.NumberOfTestMessages) - { - Context.LastMessageProcessedAt = DateTime.UtcNow; - Context.Complete = true; - } - - } - } - } - - [Serializable] - public class MyMessage : ICommand - { - } - - - - protected static void SendTestMessages(EndpointBehaviorBuilder b) - { - b.Given((bus, context) => Parallel.For(0, context.NumberOfTestMessages, (s, c) => bus.SendLocal(new MyMessage()))); - } - } -} \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/Performance/RequestResponse/Request_response_performance.cs b/src/NServiceBus.AcceptanceTests/Performance/RequestResponse/Request_response_performance.cs deleted file mode 100644 index d3c94d58639..00000000000 --- a/src/NServiceBus.AcceptanceTests/Performance/RequestResponse/Request_response_performance.cs +++ /dev/null @@ -1,155 +0,0 @@ -namespace NServiceBus.AcceptanceTests.Performance.RequestResponse -{ - using System; - using System.Threading; - using System.Threading.Tasks; - using AcceptanceTesting; - using Config; - using EndpointTemplates; - using AcceptanceTesting.Support; - using NUnit.Framework; - using ScenarioDescriptors; - - public class Request_response_performance : NServiceBusPerformanceTest - { - [Test] - public void With_dtc_enabled() - { - Scenario.Define(() => new Context { NumberOfTestMessages = NumberOfTestMessages }) - .WithEndpoint(b => SendMessages(b)) - .WithEndpoint() - .Done(c => c.Complete) - .Repeat(r => r.For(Transports.Default)) - .Report(DisplayTestResults) - .MaxTestParallelism(1) - .Run(); - } - - [Test] - public void With_dtc_supressed() - { - Scenario.Define(() => new Context { NumberOfTestMessages = NumberOfTestMessages }) - .WithEndpoint(b => - { - b.CustomConfig(c => Configure.Transactions.Advanced(a => a.DisableDistributedTransactions())); - SendMessages(b); - }) - .WithEndpoint(b => b.CustomConfig(c => Configure.Transactions.Advanced(a => a.DisableDistributedTransactions()))) - .Done(c => c.Complete) - .Repeat(r => r.For(Transports.Default)) - .Report(DisplayTestResults) - .MaxTestParallelism(1) - .Run(); - } - - [Test] - public void With_no_transactions() - { - Scenario.Define(() => new Context { NumberOfTestMessages = NumberOfTestMessages }) - .WithEndpoint(b => - { - b.CustomConfig(c => Configure.Transactions.Disable()); - SendMessages(b); - }) - .WithEndpoint(b => b.CustomConfig(c => Configure.Transactions.Disable())) - .Done(c => c.Complete) - .Repeat(r => r.For(Transports.Default)) - .Report(DisplayTestResults) - .MaxTestParallelism(1) - .Run(); - } - - [Test] - public void With_ambient_tx_suppressed() - { - Scenario.Define(() => new Context { NumberOfTestMessages = NumberOfTestMessages }) - .WithEndpoint(b => - { - b.CustomConfig(c => Configure.Transactions.Advanced(a => a.DoNotWrapHandlersExecutionInATransactionScope())); - SendMessages(b); - }) - .WithEndpoint(b => b.CustomConfig(c => Configure.Transactions.Advanced(a => a.DoNotWrapHandlersExecutionInATransactionScope()))) - .Done(c => c.Complete) - .Repeat(r => r.For(Transports.Default)) - .Report(DisplayTestResults) - .MaxTestParallelism(1) - .Run(); - } - - private static EndpointBehaviorBuilder SendMessages(EndpointBehaviorBuilder b) - { - return b.Given((bus, context) => Parallel.For(0, context.NumberOfTestMessages, (s, c) => bus.Send(new MyMessage()))); - } - - public class Context : PerformanceTestContext - { - public bool Complete { get; set; } - } - - public class ClientEndpoint : EndpointConfigurationBuilder - { - public ClientEndpoint() - { - EndpointSetup() - .WithConfig(c => c.MaximumConcurrencyLevel = MaxConcurrencyLevel) - .AddMapping(typeof(ServerEndpoint)); - } - - public class MyMessageHandler : IHandleMessages - { - public Context Context { get; set; } - - static int numberOfMessagesProcessed; - - - public void Handle(MyResponse messageThatIsEnlisted) - { - var current = Interlocked.Increment(ref numberOfMessagesProcessed); - - if (current == 1) - { - Context.FirstMessageProcessedAt = DateTime.UtcNow; - } - - if (current == Context.NumberOfTestMessages) - { - Context.LastMessageProcessedAt = DateTime.UtcNow; - Context.Complete = true; - } - - } - } - } - - public class ServerEndpoint : EndpointConfigurationBuilder - { - public ServerEndpoint() - { - EndpointSetup() - .WithConfig(c => c.MaximumConcurrencyLevel = MaxConcurrencyLevel); - } - - public class MyMessageHandler : IHandleMessages - { - public Context Context { get; set; } - - public IBus Bus { get; set; } - - public void Handle(MyMessage message) - { - Bus.Reply(new MyResponse()); - } - } - } - - [Serializable] - public class MyMessage : ICommand - { - } - - [Serializable] - public class MyResponse : IMessage - { - } - } -} \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/Performance/Sagas/Saga_performance.cs b/src/NServiceBus.AcceptanceTests/Performance/Sagas/Saga_performance.cs deleted file mode 100644 index e41741615c8..00000000000 --- a/src/NServiceBus.AcceptanceTests/Performance/Sagas/Saga_performance.cs +++ /dev/null @@ -1,127 +0,0 @@ -namespace NServiceBus.AcceptanceTests.Performance.Sagas -{ - using System; - using System.Threading; - using System.Threading.Tasks; - using AcceptanceTesting; - using AcceptanceTesting.Support; - using Config; - using EndpointTemplates; - using NUnit.Framework; - using Saga; - using ScenarioDescriptors; - - public class Saga_performance : NServiceBusPerformanceTest - { - [Test, Ignore("Fails in build server! Not reliable")] - public void With_dtc_enabled() - { - Scenario.Define(() => new Context { NumberOfTestMessages = NumberOfTestMessages }) - .WithEndpoint(SendTestMessages) - .Done(c => c.Complete) - .Repeat(r => r.For(SagaPersisters.Default)) - .Report(DisplayTestResults) - .MaxTestParallelism(1) - .Run(); - } - - [Test, Ignore("Fails in build server! Not reliable")] - public void With_dtc_supressed() - { - Scenario.Define(() => new Context { NumberOfTestMessages = NumberOfTestMessages }) - .WithEndpoint(b => - { - b.CustomConfig(c => Configure.Transactions.Advanced(a => a.DisableDistributedTransactions())); - SendTestMessages(b); - }) - .Done(c => c.Complete) - .Repeat(r => r.For(SagaPersisters.Default)) - .Report(DisplayTestResults) - .MaxTestParallelism(1) - .Run(); - } - - public class Context : PerformanceTestContext - { - - public bool Complete { get; set; } - } - - public class SagaEndpoint : EndpointConfigurationBuilder - { - public SagaEndpoint() - { - EndpointSetup() - .WithConfig(c => c.MaximumConcurrencyLevel = MaxConcurrencyLevel); - } - - public class MySaga : Saga, IAmStartedByMessages - { - public Context Context { get; set; } - - static int numberOfMessagesProcessed; - - - public void Handle(MyMessage message) - { - Data.SomeId = message.SomeId; - - var current = Interlocked.Increment(ref numberOfMessagesProcessed); - - if (current == 1) - { - Context.FirstMessageProcessedAt = DateTime.UtcNow; - } - - if (current == Context.NumberOfTestMessages) - { - Context.LastMessageProcessedAt = DateTime.UtcNow; - Context.Complete = true; - } - - } - - public override void ConfigureHowToFindSaga() - { - ConfigureMapping(m => m.SomeId) - .ToSaga(s => s.SomeId); - - } - - - public class MySagaData : IContainSagaData - { - public virtual Guid Id { get; set; } - public virtual string Originator { get; set; } - public virtual string OriginalMessageId { get; set; } - - [Unique] - public virtual Guid SomeId { get; set; } - } - - } - - - } - - [Serializable] - public class MyMessage : ICommand - { - public Guid SomeId { get; set; } - } - - - - protected static void SendTestMessages(EndpointBehaviorBuilder b) - { - b.Given((bus, context) => Parallel.For(0, context.NumberOfTestMessages, (s, c) => bus.SendLocal(new MyMessage - { - SomeId = Guid.NewGuid() - }))); - } - } - - - - -} \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/PipelineExtension/FilteringWhatGetsAudited.cs b/src/NServiceBus.AcceptanceTests/PipelineExtension/FilteringWhatGetsAudited.cs new file mode 100644 index 00000000000..bc69c067e6f --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/PipelineExtension/FilteringWhatGetsAudited.cs @@ -0,0 +1,138 @@ + +namespace NServiceBus.AcceptanceTests.PipelineExtension +{ + using System; + using AcceptanceTesting; + using EndpointTemplates; + using NServiceBus.Audit; + using NUnit.Framework; + using Pipeline; + using Pipeline.Contexts; + + /// + /// This is a demo on how pipeline overrides can be used to control which messages that gets audited by NServiceBus + /// + public class FilteringWhatGetsAudited : NServiceBusAcceptanceTest + { + [Test] + public void RunDemo() + { + var context = new Context(); + Scenario.Define(context) + .WithEndpoint(b => b.Given(bus => bus.SendLocal(new MessageToBeAudited()))) + .WithEndpoint() + .Done(c => c.IsMessageHandlingComplete) + .Run(); + + Assert.IsFalse(context.MessageAudited); + } + + + public class UserEndpoint : EndpointConfigurationBuilder + { + + public UserEndpoint() + { + EndpointSetup() + .AuditTo(); + + } + + class MessageToBeAuditedHandler : IHandleMessages + { + public Context MyContext { get; set; } + + public void Handle(MessageToBeAudited message) + { + MyContext.IsMessageHandlingComplete = true; + } + } + +#pragma warning disable 618 + class MyFilteringAuditBehavior : IBehavior, + IBehavior + { + public MessageAuditer MessageAuditer { get; set; } + + public void Invoke(ReceivePhysicalMessageContext context, Action next) + { + var auditResult = new AuditFilterResult(); + context.Set(auditResult); + next(); + + //note: and rule operating on the raw TransportMessage can be applied here if needed. + // Access to the message is through: context.PhysicalMessage. Eg: context.PhysicalMessage.Headers.ContainsKey("NServiceBus.ControlMessage") + if (auditResult.DoNotAuditMessage) + { + return; + } + MessageAuditer.ForwardMessageToAuditQueue(context.PhysicalMessage); + } + + public void Invoke(ReceiveLogicalMessageContext context, Action next) + { + //filter out messages of type MessageToBeAudited + if (context.LogicalMessage.MessageType == typeof(MessageToBeAudited)) + { + context.Get().DoNotAuditMessage = true; + } + } + + class AuditFilterResult + { + public bool DoNotAuditMessage { get; set; } + } + + + //here we inject our behavior + class AuditFilteringOverride : PipelineOverride + { + public override void Override(BehaviorList behaviorList) + { + //we replace the default audit behavior with out own + behaviorList.Replace(); + } + + public override void Override(BehaviorList behaviorList) + { + //and also hook into to logical receive pipeline to make filtering on message types easier + behaviorList.Add(); + } + } + +#pragma warning restore 618 + } + } + + public class AuditSpy : EndpointConfigurationBuilder + { + + public AuditSpy() + { + EndpointSetup(); + } + + class AuditMessageHandler : IHandleMessages + { + public Context MyContext { get; set; } + + public void Handle(MessageToBeAudited message) + { + MyContext.MessageAudited = true; + } + } + } + + public class Context : ScenarioContext + { + public bool IsMessageHandlingComplete { get; set; } + public bool MessageAudited { get; set; } + } + + + [Serializable] + public class MessageToBeAudited : IMessage + { + } + } +} diff --git a/src/NServiceBus.AcceptanceTests/PipelineExtension/SkipDeserialization.cs b/src/NServiceBus.AcceptanceTests/PipelineExtension/SkipDeserialization.cs new file mode 100644 index 00000000000..cc88227d11e --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/PipelineExtension/SkipDeserialization.cs @@ -0,0 +1,81 @@ +namespace NServiceBus.AcceptanceTests.PipelineExtension +{ + using System; + using AcceptanceTesting; + using EndpointTemplates; + using NUnit.Framework; + using Pipeline; + using Pipeline.Contexts; + using Unicast.Messages; + + //This is a demo on how the pipeline overrides can be used to create endpoints that doesn't deserialize incoming messages and there by + // allows the user to handle the raw transport message. This replaces the old feature on the UnicastBus where SkipDeserialization could be set to tru + public class SkipDeserialization : NServiceBusAcceptanceTest + { + [Test] + public void RunDemo() + { + Scenario.Define() + .WithEndpoint( + b => b.Given(bus => bus.SendLocal(new SomeMessage()))) + .Done(c => c.GotTheRawMessage) + .Run(); + } + + public class NonSerializingEndpoint : EndpointConfigurationBuilder + { + public NonSerializingEndpoint() + { + EndpointSetup(); + } + + +#pragma warning disable 618 + //first we override the default "extraction" behavior + class MyOverride : PipelineOverride + { + public override void Override(BehaviorList behaviorList) + { + behaviorList.Replace(); + } + } + + //and then we handle the physical message our self + class MyRawMessageHandler:IBehavior + { + public Context Context { get; set; } + + public void Invoke(ReceivePhysicalMessageContext context, Action next) + { + var transportMessage = context.PhysicalMessage; + + Assert.True(transportMessage.Headers[Headers.EnclosedMessageTypes].Contains(typeof(SomeMessage).Name)); + + Context.GotTheRawMessage = true; + } + } +#pragma warning restore 618 + + class ThisHandlerWontGetInvoked:IHandleMessages + { + public void Handle(SomeMessage message) + { + Assert.Fail(); + } + } + } + + public class Context : ScenarioContext + { + public bool GotTheRawMessage { get; set; } + } + + [Serializable] + public class SomeMessage : ICommand + { + + } + } + + +} diff --git a/src/NServiceBus.AcceptanceTests/PubSub/PubSubAcceptanceTest.cs b/src/NServiceBus.AcceptanceTests/PubSub/Subscriptions.cs similarity index 100% rename from src/NServiceBus.AcceptanceTests/PubSub/PubSubAcceptanceTest.cs rename to src/NServiceBus.AcceptanceTests/PubSub/Subscriptions.cs diff --git a/src/NServiceBus.AcceptanceTests/PubSub/When_multi_subscribing_to_a_polymorphic_event.cs b/src/NServiceBus.AcceptanceTests/PubSub/When_multi_subscribing_to_a_polymorphic_event.cs index 4388dc3c58d..9b4ad61a509 100644 --- a/src/NServiceBus.AcceptanceTests/PubSub/When_multi_subscribing_to_a_polymorphic_event.cs +++ b/src/NServiceBus.AcceptanceTests/PubSub/When_multi_subscribing_to_a_polymorphic_event.cs @@ -44,6 +44,12 @@ public void Both_events_should_be_delivered() { bus.Subscribe(); bus.Subscribe(); + + if (!Feature.IsEnabled()) + { + context.SubscribedToIMyEvent = true; + context.SubscribedToMyEvent2 = true; + } })) .Done(c => c.SubscriberGotIMyEvent && c.SubscriberGotMyEvent2) .Run(); diff --git a/src/NServiceBus.AcceptanceTests/PubSub/When_publishing_an_event.cs b/src/NServiceBus.AcceptanceTests/PubSub/When_publishing_an_event.cs index 16810b500a6..c3f5dec98df 100644 --- a/src/NServiceBus.AcceptanceTests/PubSub/When_publishing_an_event.cs +++ b/src/NServiceBus.AcceptanceTests/PubSub/When_publishing_an_event.cs @@ -34,13 +34,13 @@ public void Issue_1851() })) .Done(c => c.Subscriber3GotTheEvent) - .Repeat(r => r.For(Transports.Msmq)) + .Repeat(r => r.For(Transports.Default)) .Should(c => Assert.True(c.Subscriber3GotTheEvent)) .Run(); } [Test] - public void Should_be_delivered_to_allsubscribers() + public void Should_be_delivered_to_all_subscribers() { Scenario.Define() .WithEndpoint(b => @@ -69,7 +69,7 @@ public void Should_be_delivered_to_allsubscribers() context.Subscriber2Subscribed = true; })) .Done(c => c.Subscriber1GotTheEvent && c.Subscriber2GotTheEvent) - .Repeat(r => r.For(Transports.Msmq)) + .Repeat(r => r.For(Transports.Default)) .Should(c => { Assert.True(c.Subscriber1GotTheEvent); diff --git a/src/NServiceBus.AcceptanceTests/PubSub/When_publishing_an_event_with_only_local_messagehandlers.cs b/src/NServiceBus.AcceptanceTests/PubSub/When_publishing_an_event_with_only_local_messagehandlers.cs index 1f180174501..76c0123d800 100644 --- a/src/NServiceBus.AcceptanceTests/PubSub/When_publishing_an_event_with_only_local_messagehandlers.cs +++ b/src/NServiceBus.AcceptanceTests/PubSub/When_publishing_an_event_with_only_local_messagehandlers.cs @@ -93,6 +93,14 @@ public void Handle(IEvent message) Context.CatchAllHandlerGotTheMessage = true; } } + + class DummyHandler : IHandleMessages //explicit handler for the event is needed + { + public Context Context { get; set; } + public void Handle(EventHandledByLocalEndpoint message) + { + } + } } [Serializable] public class EventHandledByLocalEndpoint : IEvent diff --git a/src/NServiceBus.AcceptanceTests/PubSub/When_publishing_an_event_with_the_subscriber_scaled_out.cs b/src/NServiceBus.AcceptanceTests/PubSub/When_publishing_an_event_with_the_subscriber_scaled_out.cs index 78c55651540..cd37cda4055 100644 --- a/src/NServiceBus.AcceptanceTests/PubSub/When_publishing_an_event_with_the_subscriber_scaled_out.cs +++ b/src/NServiceBus.AcceptanceTests/PubSub/When_publishing_an_event_with_the_subscriber_scaled_out.cs @@ -49,7 +49,7 @@ public void Should_only_publish_one_event() context.NumberOfSubcriptionsReceived++; })) .Done(c => c.SubcribersOfTheEvent != null) - .Repeat(r => r.For(Transports.SqlServer) + .Repeat(r => r.For(Transports.Msmq) .For(SubscriptionStorages.Msmq)) .Should(c => { diff --git a/src/NServiceBus.AcceptanceTests/Retries/When_doing_flr_with_default_settings.cs b/src/NServiceBus.AcceptanceTests/Retries/When_doing_flr_with_default_settings.cs index 88da51aa771..d899fc02bbd 100644 --- a/src/NServiceBus.AcceptanceTests/Retries/When_doing_flr_with_default_settings.cs +++ b/src/NServiceBus.AcceptanceTests/Retries/When_doing_flr_with_default_settings.cs @@ -10,45 +10,47 @@ public class When_doing_flr_with_default_settings : NServiceBusAcceptanceTest { + public static Func X = () => 5; + [Test] - public void Should_do_5_retries_by_default_with_dtc_on() + public void Should_do_X_retries_by_default_with_dtc_on() { - Scenario.Define() - .WithEndpoint(b => b.Given(bus => bus.SendLocal(new MessageToBeRetried()))) - .Done(c => c.HandedOverToSlr || c.NumberOfTimesInvoked > 5) + Scenario.Define(() => new Context { Id = Guid.NewGuid() }) + .WithEndpoint(b => b.Given((bus, context) => bus.SendLocal(new MessageToBeRetried{ Id = context.Id }))) + .Done(c => c.HandedOverToSlr || c.NumberOfTimesInvoked > X()) .Repeat(r => r.For()) - .Should(c => Assert.AreEqual(5, c.NumberOfTimesInvoked, "The FLR should by default retry 5 times")) + .Should(c => Assert.AreEqual(X(), c.NumberOfTimesInvoked, string.Format("The FLR should by default retry {0} times", X()))) .Run(); } [Test] - public void Should_do_5_retries_by_default_with_native_transactions() + public void Should_do_X_retries_by_default_with_native_transactions() { - Scenario.Define() + Scenario.Define(() => new Context { Id = Guid.NewGuid() }) .WithEndpoint(b => { b.CustomConfig(c => Configure.Transactions.Advanced(a => a.DisableDistributedTransactions())); - b.Given(bus => bus.SendLocal(new MessageToBeRetried())); + b.Given((bus, context) => bus.SendLocal(new MessageToBeRetried { Id = context.Id })); }) - .Done(c => c.HandedOverToSlr || c.NumberOfTimesInvoked > 5) + .Done(c => c.HandedOverToSlr || c.NumberOfTimesInvoked > X()) .Repeat(r => r.For(Transports.Default)) - .Should(c => Assert.AreEqual(5, c.NumberOfTimesInvoked, "The FLR should by default retry 5 times")) - .Run(); + .Should(c => Assert.AreEqual(X(), c.NumberOfTimesInvoked, string.Format("The FLR should by default retry {0} times", X()))) + .Run(TimeSpan.FromMinutes(X())); } [Test] public void Should_not_do_any_retries_if_transactions_are_off() { - Scenario.Define() + Scenario.Define(() => new Context { Id = Guid.NewGuid() }) .WithEndpoint(b => { b.CustomConfig(c => Configure.Transactions.Disable()); b.Given((bus, context) => { - bus.SendLocal(new MessageToBeRetried()); - bus.SendLocal(new MessageToBeRetried { SecondMessage = true }); + bus.SendLocal(new MessageToBeRetried { Id = context.Id }); + bus.SendLocal(new MessageToBeRetried { Id = context.Id, SecondMessage = true }); }); }) .Done(c => c.SecondMessageReceived || c.NumberOfTimesInvoked > 1) @@ -60,6 +62,8 @@ public void Should_not_do_any_retries_if_transactions_are_off() public class Context : ScenarioContext { + public Guid Id { get; set; } + public int NumberOfTimesInvoked { get; set; } public bool HandedOverToSlr { get; set; } @@ -103,6 +107,8 @@ class MessageToBeRetriedHandler : IHandleMessages public void Handle(MessageToBeRetried message) { + if (message.Id != Context.Id) return; // messages from previous test runs must be ignored + if (message.SecondMessage) { Context.SecondMessageReceived = true; @@ -119,6 +125,8 @@ public void Handle(MessageToBeRetried message) [Serializable] public class MessageToBeRetried : IMessage { + public Guid Id { get; set; } + public bool SecondMessage { get; set; } } } diff --git a/src/NServiceBus.AcceptanceTests/Retries/When_message_fails_with_retries_set_to_0.cs b/src/NServiceBus.AcceptanceTests/Retries/When_message_fails_with_retries_set_to_0.cs index 68f0c2d2d3c..5441bb94c58 100644 --- a/src/NServiceBus.AcceptanceTests/Retries/When_message_fails_with_retries_set_to_0.cs +++ b/src/NServiceBus.AcceptanceTests/Retries/When_message_fails_with_retries_set_to_0.cs @@ -11,7 +11,7 @@ public class When_message_fails_with_retries_set_to_0 : NServiceBusAcceptanceTest { [Test] - public void Should_not_retry_the_message() + public void Should_not_retry_the_message_using_flr() { var context = new Context(); @@ -21,7 +21,6 @@ public void Should_not_retry_the_message() .Run(); Assert.AreEqual(1, context.NumberOfTimesInvoked,"No FLR should be in use if MaxRetries is set to 0"); - Assert.AreEqual(Environment.MachineName, context.HeadersOfTheFailedMessage[Headers.ProcessingMachine], "The receiver should attach the machine name as a header"); Assert.True(context.HeadersOfTheFailedMessage[Headers.ProcessingEndpoint].Contains("RetryEndpoint"), "The receiver should attach its endpoint name as a header"); } diff --git a/src/NServiceBus.AcceptanceTests/Retries/When_messages_fails_flr.cs b/src/NServiceBus.AcceptanceTests/Retries/When_messages_fails_flr.cs index 9d47f6e5b92..587df1e1ff0 100644 --- a/src/NServiceBus.AcceptanceTests/Retries/When_messages_fails_flr.cs +++ b/src/NServiceBus.AcceptanceTests/Retries/When_messages_fails_flr.cs @@ -14,8 +14,8 @@ public class When_messages_fails_flr : NServiceBusAcceptanceTest [Test] public void Should_be_moved_to_slr() { - Scenario.Define() - .WithEndpoint(b => b.Given(bus => bus.SendLocal(new MessageToBeRetried()))) + Scenario.Define(() => new Context { Id = Guid.NewGuid() }) + .WithEndpoint(b => b.Given((bus, context) => bus.SendLocal(new MessageToBeRetried { Id = context.Id }))) .Done(c => c.NumberOfTimesInvoked >= 2) .Repeat(r => r.For(Transports.Default)) .Should(context => @@ -28,6 +28,8 @@ public void Should_be_moved_to_slr() public class Context : ScenarioContext { + public Guid Id { get; set; } + public int NumberOfTimesInvoked { get; set; } public DateTime TimeOfFirstAttempt { get; set; } @@ -62,6 +64,8 @@ class MessageToBeRetriedHandler:IHandleMessages public void Handle(MessageToBeRetried message) { + if (message.Id != Context.Id) return; // ignore messages from previous test runs + Context.NumberOfTimesInvoked++; if (Context.NumberOfTimesInvoked == 1) @@ -82,6 +86,7 @@ public void Handle(MessageToBeRetried message) [Serializable] public class MessageToBeRetried : IMessage { + public Guid Id { get; set; } } } diff --git a/src/NServiceBus.AcceptanceTests/Sagas/Issue_1819.cs b/src/NServiceBus.AcceptanceTests/Sagas/Issue_1819.cs index 5547c8c651c..fc4a344bc49 100644 --- a/src/NServiceBus.AcceptanceTests/Sagas/Issue_1819.cs +++ b/src/NServiceBus.AcceptanceTests/Sagas/Issue_1819.cs @@ -11,10 +11,10 @@ public class Issue_1819 : NServiceBusAcceptanceTest [Test] public void Run() { - var context = new Context(); + var context = new Context { Id = Guid.NewGuid() }; Scenario.Define(context) - .WithEndpoint(b => b.Given(bus => bus.SendLocal(new StartSaga1()))) + .WithEndpoint(b => b.Given((bus, c) => bus.SendLocal(new StartSaga1 { ContextId = c.Id }))) .Done(c => (c.Saga1TimeoutFired && c.Saga2TimeoutFired) || c.SagaNotFound) .Run(TimeSpan.FromSeconds(20)); @@ -25,6 +25,7 @@ public void Run() public class Context : ScenarioContext { + public Guid Id { get; set; } public bool Saga1TimeoutFired { get; set; } public bool Saga2TimeoutFired { get; set; } public bool SagaNotFound { get; set; } @@ -43,18 +44,23 @@ public class Saga1 : Saga, IAmStartedByMessages, IH public void Handle(StartSaga1 message) { - RequestTimeout(TimeSpan.FromSeconds(5)); - RequestTimeout(new DateTime(2011, 10, 14, 23, 08, 0, DateTimeKind.Local)); + if (message.ContextId != Context.Id) return; + + RequestTimeout(TimeSpan.FromSeconds(5), new Saga1Timeout { ContextId = Context.Id }); + RequestTimeout(new DateTime(2011, 10, 14, 23, 08, 0, DateTimeKind.Local), new Saga2Timeout { ContextId = Context.Id }); } public void Timeout(Saga1Timeout state) { MarkAsComplete(); + + if (state.ContextId != Context.Id) return; Context.Saga1TimeoutFired = true; } public void Timeout(Saga2Timeout state) { + if (state.ContextId != Context.Id) return; Context.Saga2TimeoutFired = true; } @@ -69,6 +75,8 @@ public class SagaNotFound : IHandleSagaNotFound public void Handle(object message) { + if (((dynamic)message).ContextId != Context.Id) return; + Context.SagaNotFound = true; } } @@ -81,7 +89,7 @@ public void Handle(object message) } } - public class Foo: ISpecifyMessageHandlerOrdering + public class Foo : ISpecifyMessageHandlerOrdering { public void SpecifyOrder(Order order) { @@ -93,15 +101,18 @@ public void SpecifyOrder(Order order) [Serializable] public class StartSaga1 : ICommand { + public Guid ContextId { get; set; } } public class Saga1Timeout { + public Guid ContextId { get; set; } } public class Saga2Timeout { + public Guid ContextId { get; set; } } } } \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/Sagas/When_a_saga_is_started_by_an_event_published_by_another_saga.cs b/src/NServiceBus.AcceptanceTests/Sagas/When_a_saga_is_started_by_an_event_published_by_another_saga.cs index c3f1ec8b622..262aa2c7665 100644 --- a/src/NServiceBus.AcceptanceTests/Sagas/When_a_saga_is_started_by_an_event_published_by_another_saga.cs +++ b/src/NServiceBus.AcceptanceTests/Sagas/When_a_saga_is_started_by_an_event_published_by_another_saga.cs @@ -31,7 +31,13 @@ public void Should_start_the_saga_and_request_a_timeout() bus.SendLocal(new StartSaga {DataId = Guid.NewGuid()})) ) .WithEndpoint( - b => b.Given((bus, context) => bus.Subscribe())) + b => b.Given((bus, context) => + { + bus.Subscribe(); + + if (!Feature.IsEnabled()) + context.IsEventSubscriptionReceived = true; + })) .Done(c => c.DidSaga1Complete && c.DidSaga2Complete) .Repeat(r => r.For(Transports.Default)) @@ -48,6 +54,7 @@ public class Context : ScenarioContext [Test] + [Explicit] public void Should_start_the_saga_when_set_up_to_start_for_the_base_event() { Scenario.Define() @@ -66,11 +73,17 @@ public void Should_start_the_saga_when_set_up_to_start_for_the_base_event() bus.Publish(m=> { m.DataId = Guid.NewGuid(); })) ) .WithEndpoint( - b => b.Given((bus, context) => bus.Subscribe())) + b => b.Given((bus, context) => + { + bus.Subscribe(); + + if (!Feature.IsEnabled()) + context.IsEventSubscriptionReceived = true; + })) .Done(c => c.DidSagaComplete) .Repeat(r => r.For(Transports.Default)) .Should(c => Assert.True(c.DidSagaComplete)) - .Run(); + .Run(TimeSpan.FromMinutes(3)); } public class SagaContext : ScenarioContext diff --git a/src/NServiceBus.AcceptanceTests/Sagas/When_two_sagas_subscribe_to_the_same_event.cs b/src/NServiceBus.AcceptanceTests/Sagas/When_two_sagas_subscribe_to_the_same_event.cs index 0a601f42ce0..ea19ed4ef8b 100644 --- a/src/NServiceBus.AcceptanceTests/Sagas/When_two_sagas_subscribe_to_the_same_event.cs +++ b/src/NServiceBus.AcceptanceTests/Sagas/When_two_sagas_subscribe_to_the_same_event.cs @@ -5,6 +5,7 @@ namespace NServiceBus.AcceptanceTests.Sagas using EndpointTemplates; using AcceptanceTesting; using NUnit.Framework; + using PubSub; using Saga; using ScenarioDescriptors; @@ -15,7 +16,19 @@ public class When_two_sagas_subscribe_to_the_same_event : NServiceBusAcceptanceT public void Should_invoke_all_handlers_on_all_sagas() { Scenario.Define() - .WithEndpoint(b => b.Given(bus => bus.SendLocal(new StartSaga2 { DataId = Guid.NewGuid() }))) + .WithEndpoint(b => + b.Given((bus, context) => Subscriptions.OnEndpointSubscribed(s => + { + if (s.SubscriberReturnAddress.Queue.Contains("Saga1")) + { + context.Subscribed = true; + } + })) + .When(c => true, bus => bus.SendLocal(new StartSaga2 + { + DataId = Guid.NewGuid() + })) + ) .WithEndpoint() .Done(c => c.DidSaga1EventHandlerGetInvoked && c.DidSaga2EventHandlerGetInvoked) .Repeat(r => r.For(Transports.Default)) @@ -28,6 +41,7 @@ public void Should_invoke_all_handlers_on_all_sagas() public class Context : ScenarioContext { + public bool Subscribed { get; set; } public bool DidSaga1EventHandlerGetInvoked { get; set; } public bool DidSaga2EventHandlerGetInvoked { get; set; } } @@ -69,7 +83,7 @@ public void Handle(GroupPendingEvent message) Data.DataId = message.DataId; Console.Out.WriteLine("Saga1 received GroupPendingEvent for DataId: {0}", message.DataId); Context.DidSaga1EventHandlerGetInvoked = true; - Bus.SendLocal(new CompleteSaga1Start { DataId = message.DataId }); + Bus.SendLocal(new CompleteSaga1Now { DataId = message.DataId }); } public void Handle(CompleteSaga1Now message) @@ -142,11 +156,6 @@ public class StartSaga2 : ICommand public Guid DataId { get; set; } } - public class CompleteSaga1Start : ICommand - { - public Guid DataId { get; set; } - } - public class CompleteSaga1Now : ICommand { public Guid DataId { get; set; } diff --git a/src/NServiceBus.AcceptanceTests/Sagas/When_using_a_received_message_for_timeout.cs b/src/NServiceBus.AcceptanceTests/Sagas/When_using_a_received_message_for_timeout.cs index e1ad8879e73..6441990b652 100644 --- a/src/NServiceBus.AcceptanceTests/Sagas/When_using_a_received_message_for_timeout.cs +++ b/src/NServiceBus.AcceptanceTests/Sagas/When_using_a_received_message_for_timeout.cs @@ -3,7 +3,9 @@ using System; using EndpointTemplates; using AcceptanceTesting; + using Features; using NUnit.Framework; + using PubSub; using Saga; using ScenarioDescriptors; @@ -14,16 +16,27 @@ public void Timeout_should_be_received_after_expiration() { Scenario.Define(() => new Context {Id = Guid.NewGuid()}) .WithEndpoint(b => + { + b.Given((bus, context) => { - b.Given((bus, context) => bus.SendLocal(new StartSagaMessage {SomeId = context.Id})); - - b.When(context => context.StartSagaMessageReceived, - (bus, context) => - { - bus.EnsureSubscriptionMessagesHaveArrived(); - bus.Publish(new SomeEvent {SomeId = context.Id}); - }); - }) + if (!Feature.IsEnabled()) + { + bus.SendLocal(new StartSagaMessage { SomeId = context.Id }); + } + else + { + Subscriptions.OnEndpointSubscribed(s => bus.SendLocal(new StartSagaMessage { SomeId = context.Id })); + } + + }); + + b.When(context => context.StartSagaMessageReceived, + (bus, context) => + { + bus.Publish(new SomeEvent { SomeId = context.Id }); + }); + + }) .Done(c => c.TimeoutReceived) .Repeat(r => r.For(Transports.Default)) .Run(); @@ -45,7 +58,6 @@ public class SagaEndpoint : EndpointConfigurationBuilder public SagaEndpoint() { EndpointSetup(c => c.RavenSagaPersister() - .DefineHowManySubscriptionMessagesToWaitFor(1) .UnicastBus()) .AddMapping(typeof (SagaEndpoint)); } diff --git a/src/NServiceBus.AcceptanceTests/Sagas/When_using_containSagaData.cs b/src/NServiceBus.AcceptanceTests/Sagas/When_using_containSagaData.cs index 50e794d1001..13c836fbcf3 100644 --- a/src/NServiceBus.AcceptanceTests/Sagas/When_using_containSagaData.cs +++ b/src/NServiceBus.AcceptanceTests/Sagas/When_using_containSagaData.cs @@ -17,7 +17,7 @@ public void Should_handle_timeouts_properly() .WithEndpoint( b => b.Given(bus => bus.SendLocal(new StartSaga {DataId = Guid.NewGuid()}))) .Done(c => c.DidAllSagaInstancesReceiveTimeouts) - .Repeat(r => r.For(Transports.SqlServer)) + .Repeat(r => r.For(Transports.Default)) .Should(c => { Assert.True(c.DidAllSagaInstancesReceiveTimeouts); diff --git a/src/NServiceBus.AcceptanceTests/ScenarioDescriptors/AllTransports.cs b/src/NServiceBus.AcceptanceTests/ScenarioDescriptors/AllTransports.cs index 5eaa1753423..9ea9b012b05 100644 --- a/src/NServiceBus.AcceptanceTests/ScenarioDescriptors/AllTransports.cs +++ b/src/NServiceBus.AcceptanceTests/ScenarioDescriptors/AllTransports.cs @@ -6,6 +6,7 @@ using System.Reflection; using AcceptanceTesting.Support; using Hosting.Helpers; + using NServiceBus.Transports; public class AllTransports : ScenarioDescriptor { @@ -37,8 +38,12 @@ static IEnumerable ActiveTransports public class AllDtcTransports : AllTransports { public AllDtcTransports() - { - Remove(Transports.RabbitMQ); + { + AllTransportsFilter.Run(t => t.HasSupportForDistributedTransactions.HasValue + && !t.HasSupportForDistributedTransactions.Value, Remove); + + // todo set HasSupportForDistributedTransactions to false on Rabbit MQ + AllTransportsFilter.Run(t => t.GetType().Name.Contains("RabbitMQ"), Remove); } } @@ -46,7 +51,7 @@ public class AllBrokerTransports : AllTransports { public AllBrokerTransports() { - Remove(Transports.Msmq); + AllTransportsFilter.Run(t => !t.HasNativePubSubSupport, Remove); } } @@ -54,8 +59,7 @@ public class AllTransportsWithCentralizedPubSubSupport : AllTransports { public AllTransportsWithCentralizedPubSubSupport() { - Remove(Transports.Msmq); - Remove(Transports.SqlServer); + AllTransportsFilter.Run(t => !t.HasSupportForCentralizedPubSub, Remove); } } @@ -63,8 +67,7 @@ public class AllTransportsWithMessageDrivenPubSub : AllTransports { public AllTransportsWithMessageDrivenPubSub() { - Remove(Transports.ActiveMQ); - Remove(Transports.RabbitMQ); + AllTransportsFilter.Run(t => t.HasNativePubSubSupport, Remove); } } @@ -105,4 +108,24 @@ static IEnumerable AvailableAssemblies static List assemblies; } + + public static class AllTransportsFilter + { + public static void Run(Func condition, Func remove) + { + foreach (var rundescriptor in Transports.AllAvailable) + { + var transportAssemblyQualifiedName = rundescriptor.Settings["Transport"]; + var type = Type.GetType(transportAssemblyQualifiedName); + if (type != null) + { + var transport = Activator.CreateInstance(type) as TransportDefinition; + if (condition(transport)) + { + remove(rundescriptor); + } + } + } + } + } } \ No newline at end of file diff --git a/src/NServiceBus.AcceptanceTests/Transactions/When_sending_a_message_from_a_non_transactional_endpoint_with_a_ambient_transaction_enabled.cs b/src/NServiceBus.AcceptanceTests/Transactions/When_sending_a_message_from_a_non_transactional_endpoint_with_a_ambient_transaction_enabled.cs index 7068ed85d6b..1b7ad97cfd8 100644 --- a/src/NServiceBus.AcceptanceTests/Transactions/When_sending_a_message_from_a_non_transactional_endpoint_with_a_ambient_transaction_enabled.cs +++ b/src/NServiceBus.AcceptanceTests/Transactions/When_sending_a_message_from_a_non_transactional_endpoint_with_a_ambient_transaction_enabled.cs @@ -16,7 +16,7 @@ public void Should_not_roll_the_message_back_to_the_queue_in_case_of_failure() Scenario.Define() .WithEndpoint(b => b.Given(bus => bus.SendLocal(new MyMessage()))) .Done(c => c.TestComplete) - .Repeat(r => r.For(Transports.Default)) //broken for active mq + .Repeat(r => r.For()) .Should(c => { Assert.False(c.MessageEnlistedInTheAmbientTxReceived, "The enlisted bus.Send should not commit"); diff --git a/src/NServiceBus.AcceptanceTests/Transactions/When_sending_messages_within_an_ambient_transaction.cs b/src/NServiceBus.AcceptanceTests/Transactions/When_sending_messages_within_an_ambient_transaction.cs index 0a27cd3e6aa..11e6a0fde53 100644 --- a/src/NServiceBus.AcceptanceTests/Transactions/When_sending_messages_within_an_ambient_transaction.cs +++ b/src/NServiceBus.AcceptanceTests/Transactions/When_sending_messages_within_an_ambient_transaction.cs @@ -34,7 +34,6 @@ public void Should_not_deliver_them_until_the_commit_phase() .Should(c => { Assert.AreEqual(1, c.SequenceNumberOfFirstMessage,"The transport should preserve the order in which the transactional messages are delivered to the queuing system"); - Assert.True(c.NonTransactionalHandlerCalledFirst,"The non transactional handler should be called first"); } ) .Run(); diff --git a/src/NServiceBus.Core.Tests.x86/NServiceBus.Core.x86.Tests.csproj b/src/NServiceBus.Core.Tests.x86/NServiceBus.Core.x86.Tests.csproj index 90949b8fe89..8ecdeb2c4ff 100644 --- a/src/NServiceBus.Core.Tests.x86/NServiceBus.Core.x86.Tests.csproj +++ b/src/NServiceBus.Core.Tests.x86/NServiceBus.Core.x86.Tests.csproj @@ -11,6 +11,7 @@ NServiceBus.Core.Tests.x32 v4.0 512 + ..\ true diff --git a/src/NServiceBus.Core.Tests/Config/When_using_convention_based_messages.cs b/src/NServiceBus.Core.Tests/Config/When_using_convention_based_messages.cs index 82c76741d0d..8b9744a0bfe 100644 --- a/src/NServiceBus.Core.Tests/Config/When_using_convention_based_messages.cs +++ b/src/NServiceBus.Core.Tests/Config/When_using_convention_based_messages.cs @@ -1,7 +1,5 @@ namespace NServiceBus.Core.Tests.Config { - using System.Linq; - using ConventionBasedHandlers; using NUnit.Framework; [TestFixture] @@ -11,13 +9,13 @@ public class When_using_convention_based_messages [Explicit("//TODO: re-enable when we make message scanning lazy #1617")] public void Should_include_messages_of_a_handler() { - Configure.With(new[] { typeof(ConventionBasedHandler) }); + //Configure.With(new[] { typeof(ConventionBasedHandler) }); - var typesToScan = Configure.TypesToScan; + //var typesToScan = Configure.TypesToScan; - var foundType = typesToScan.FirstOrDefault(type => type.FullName == "ConventionBasedMessages.MyMessage"); + //var foundType = typesToScan.FirstOrDefault(type => type.FullName == "ConventionBasedMessages.MyMessage"); - Assert.NotNull(foundType); + //Assert.NotNull(foundType); } } } \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/DataBus/InMemoryDataBus.cs b/src/NServiceBus.Core.Tests/DataBus/InMemoryDataBus.cs deleted file mode 100644 index b4f15c26323..00000000000 --- a/src/NServiceBus.Core.Tests/DataBus/InMemoryDataBus.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace NServiceBus.Core.Tests.DataBus -{ - using System; - using System.Collections.Generic; - using System.IO; - using NServiceBus.DataBus; - - public class InMemoryDataBus : IDataBus - { - private readonly IDictionary storage = new Dictionary(); - - public Stream Get(string key) - { - lock (storage) - return new MemoryStream(storage[key]); - } - - public string Put(Stream stream, TimeSpan timeToBeReceived) - { - var key = Guid.NewGuid().ToString(); - - var data = new byte[stream.Length]; - stream.Read(data, 0, (int) stream.Length); - - lock (storage) - storage.Add(key, data); - return key; - } - - public void Start() - { - //no-op - } - } -} \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/DataBus/When_applying_the_databus_message_mutator_to_incoming_messages.cs b/src/NServiceBus.Core.Tests/DataBus/When_applying_the_databus_message_mutator_to_incoming_messages.cs index 9a9ecad91f7..94c60ea0bba 100644 --- a/src/NServiceBus.Core.Tests/DataBus/When_applying_the_databus_message_mutator_to_incoming_messages.cs +++ b/src/NServiceBus.Core.Tests/DataBus/When_applying_the_databus_message_mutator_to_incoming_messages.cs @@ -4,8 +4,8 @@ namespace NServiceBus.Core.Tests.DataBus using System.Collections.Generic; using System.IO; using System.Runtime.Serialization.Formatters.Binary; + using NServiceBus.Pipeline.Contexts; using NUnit.Framework; - using Pipeline.Contexts; using Rhino.Mocks; using Unicast.Messages; diff --git a/src/NServiceBus.Core.Tests/DataBus/When_applying_the_databus_message_mutator_to_null_properties.cs b/src/NServiceBus.Core.Tests/DataBus/When_applying_the_databus_message_mutator_to_null_properties.cs index fba928c2d0c..f9400877e53 100644 --- a/src/NServiceBus.Core.Tests/DataBus/When_applying_the_databus_message_mutator_to_null_properties.cs +++ b/src/NServiceBus.Core.Tests/DataBus/When_applying_the_databus_message_mutator_to_null_properties.cs @@ -4,8 +4,8 @@ namespace NServiceBus.Core.Tests.DataBus using System.Collections.Generic; using System.IO; using System.Runtime.Serialization.Formatters.Binary; + using NServiceBus.Pipeline.Contexts; using NUnit.Framework; - using Pipeline.Contexts; using Unicast; using Unicast.Messages; diff --git a/src/NServiceBus.Core.Tests/DataBus/When_applying_the_databus_message_mutator_to_outgoing_messages.cs b/src/NServiceBus.Core.Tests/DataBus/When_applying_the_databus_message_mutator_to_outgoing_messages.cs index 231e8691755..41c5be8c230 100644 --- a/src/NServiceBus.Core.Tests/DataBus/When_applying_the_databus_message_mutator_to_outgoing_messages.cs +++ b/src/NServiceBus.Core.Tests/DataBus/When_applying_the_databus_message_mutator_to_outgoing_messages.cs @@ -3,8 +3,8 @@ namespace NServiceBus.Core.Tests.DataBus using System; using System.Collections.Generic; using System.IO; + using NServiceBus.Pipeline.Contexts; using NUnit.Framework; - using Pipeline.Contexts; using Rhino.Mocks; using Unicast; using Unicast.Messages; diff --git a/src/NServiceBus.Core.Tests/DataBus/When_nservicebus_is_initalizing.cs b/src/NServiceBus.Core.Tests/DataBus/When_nservicebus_is_initalizing.cs index 74ffbf8e7bf..9471e98c37a 100644 --- a/src/NServiceBus.Core.Tests/DataBus/When_nservicebus_is_initalizing.cs +++ b/src/NServiceBus.Core.Tests/DataBus/When_nservicebus_is_initalizing.cs @@ -4,6 +4,7 @@ namespace NServiceBus.Core.Tests.DataBus using System.IO; using NServiceBus.DataBus; using NServiceBus.DataBus.Config; + using NServiceBus.DataBus.InMemory; using NUnit.Framework; [TestFixture] diff --git a/src/NServiceBus.Core.Tests/Encryption/WireEncryptedStringSpecs.cs b/src/NServiceBus.Core.Tests/Encryption/WireEncryptedStringSpecs.cs index fe419c16e96..1a9919c1440 100644 --- a/src/NServiceBus.Core.Tests/Encryption/WireEncryptedStringSpecs.cs +++ b/src/NServiceBus.Core.Tests/Encryption/WireEncryptedStringSpecs.cs @@ -350,8 +350,8 @@ public class WireEncryptedStringContext { protected EncryptionMessageMutator mutator; - public const string EncryptedBase64Value = "encrypted value"; - public const string MySecretMessage = "A secret"; + protected string EncryptedBase64Value = "encrypted value"; + protected string MySecretMessage = "A secret"; [SetUp] public void BaseSetUp() diff --git a/src/NServiceBus.Core.Tests/FuncBuilder.cs b/src/NServiceBus.Core.Tests/FuncBuilder.cs index 551406cf37b..4be4b7ecbf6 100644 --- a/src/NServiceBus.Core.Tests/FuncBuilder.cs +++ b/src/NServiceBus.Core.Tests/FuncBuilder.cs @@ -47,7 +47,7 @@ public object Build(Type typeToBuild) } } - object result = null; + object result; if (fn != null) { diff --git a/src/NServiceBus.Core.Tests/Gateway/InMemoryDataBus.cs b/src/NServiceBus.Core.Tests/Gateway/InMemoryDataBus.cs deleted file mode 100644 index 6a6c99b7c8a..00000000000 --- a/src/NServiceBus.Core.Tests/Gateway/InMemoryDataBus.cs +++ /dev/null @@ -1,68 +0,0 @@ -namespace NServiceBus.Gateway.Tests -{ - using System; - using System.Collections.Generic; - using System.IO; - using DataBus; - - /// - /// In memory implementation of . - /// - public class InMemoryDataBus : IDataBus - { - private readonly IDictionary storage = new Dictionary(); - - /// - /// Gets a data item from the bus. - /// - /// The key to look for. - /// The data . - public Stream Get(string key) - { - lock (storage) - return new MemoryStream(storage[key].Data); - } - - /// - /// Adds a data item to the bus and returns the assigned key. - /// - /// A create containing the data to be sent on the databus. - /// The time to be received specified on the message type. TimeSpan.MaxValue is the default. - public string Put(Stream stream, TimeSpan timeToBeReceived) - { - var key = Guid.NewGuid().ToString(); - - var data = new byte[stream.Length]; - stream.Read(data, 0, (int) stream.Length); - - lock (storage) - storage.Add(key, new Entry - { - Data = data, - ExpireAt = DateTime.Now + timeToBeReceived - }); - return key; - } - - /// - /// Called when the bus starts up to allow the data bus to active background tasks. - /// - public void Start() - { - //no-op - } - - //used for test purposes - public Entry Peek(string key) - { - lock (storage) - return storage[key]; - } - - public class Entry - { - public byte[] Data; - public DateTime ExpireAt; - } - } -} \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/Gateway/Receiving/ChannelReceiverHeaderReaderTests.cs b/src/NServiceBus.Core.Tests/Gateway/Receiving/ChannelReceiverHeaderReaderTests.cs new file mode 100644 index 00000000000..5d1ec164f44 --- /dev/null +++ b/src/NServiceBus.Core.Tests/Gateway/Receiving/ChannelReceiverHeaderReaderTests.cs @@ -0,0 +1,67 @@ +namespace NServiceBus.Core.Tests +{ + using System.Collections.Generic; + using Gateway.Channels.Http; + using Gateway.HeaderManagement; + using Gateway.Receiving; + using NUnit.Framework; + + [TestFixture] + public class ChannelReceiverHeaderReaderTests + { + + [Test] + public void Missing_CallTypeHeader_throws_ChannelException() + { + Assert.Throws(() => ChannelReceiverHeaderReader.ReadCallType(new Dictionary())); + } + + [Test] + public void EmptyString_CallTypeHeader_throws_ChannelException() + { + Assert.Throws(() => ChannelReceiverHeaderReader.ReadCallType(new Dictionary + { + {GatewayHeaders.CallTypeHeader, ""}, + })); + } + + [Test] + public void Invalid_CallTypeHeader_throws_ChannelException() + { + Assert.Throws(() => ChannelReceiverHeaderReader.ReadCallType(new Dictionary + { + {GatewayHeaders.CallTypeHeader, "badValue"}, + })); + } + + [Test] + public void EmptyString_ClientId_throws_ChannelException() + { + Assert.Throws(() => ChannelReceiverHeaderReader.ReadClientId(new Dictionary + { + {GatewayHeaders.ClientIdHeader, ""}, + })); + } + + [Test] + public void Missing_ClientId_throws_ChannelException() + { + Assert.Throws(() => ChannelReceiverHeaderReader.ReadClientId(new Dictionary())); + } + + [Test] + public void Missing_MD5_throws_ChannelException() + { + Assert.Throws(() => ChannelReceiverHeaderReader.ReadMd5(new Dictionary())); + } + + [Test] + public void Empty_MD5_throws_ChannelException() + { + Assert.Throws(() => ChannelReceiverHeaderReader.ReadMd5( new Dictionary + { + {HttpHeaders.ContentMd5Key, ""}, + })); + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/Gateway/Receiving/HasherTests.cs b/src/NServiceBus.Core.Tests/Gateway/Receiving/HasherTests.cs new file mode 100644 index 00000000000..89f7ef67dfd --- /dev/null +++ b/src/NServiceBus.Core.Tests/Gateway/Receiving/HasherTests.cs @@ -0,0 +1,24 @@ +namespace NServiceBus.Core.Tests +{ + using Gateway.Receiving; + using Gateway.Utils; + using NUnit.Framework; + + [TestFixture] + public class HasherTests + { + + [Test] + public void Valid_Md5_can_be_verified() + { + Hasher.Verify("myData".ConvertToStream(), Hasher.Hash("myData".ConvertToStream())); + } + + [Test] + public void Invalid_hash_throws_ChannelException() + { + Assert.Throws(() => Hasher.Verify("myData".ConvertToStream(), "invalidHash")); + } + + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/GitFlowVersionTests.cs b/src/NServiceBus.Core.Tests/GitFlowVersionTests.cs new file mode 100644 index 00000000000..221cf1eba13 --- /dev/null +++ b/src/NServiceBus.Core.Tests/GitFlowVersionTests.cs @@ -0,0 +1,18 @@ +namespace NServiceBus +{ + using System; + using NUnit.Framework; + + [TestFixture] + public class GitFlowVersionTests + { + [Test] + public void Verify_has_a_version_and_can_be_parsed() + { + Assert.IsNotNullOrEmpty(GitFlowVersion.MajorMinor); + Version.Parse(GitFlowVersion.MajorMinor); + Assert.IsNotNullOrEmpty(GitFlowVersion.MajorMinorPatch); + Version.Parse(GitFlowVersion.MajorMinorPatch); + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/Licensing/NServiceBusVersionTests.cs b/src/NServiceBus.Core.Tests/Licensing/NServiceBusVersionTests.cs deleted file mode 100644 index f7e50811efa..00000000000 --- a/src/NServiceBus.Core.Tests/Licensing/NServiceBusVersionTests.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace NServiceBus.Core.Tests.Licensing -{ - using System; - using NServiceBus.Licensing; - using NUnit.Framework; - - [TestFixture] - public class NServiceBusVersionTests - { - - [Test] - public void Verify_has_a_version_and_can_be_parsed() - { - Assert.IsNotNullOrEmpty(NServiceBusVersion.MajorAndMinor); - Version version; - Assert.IsTrue(Version.TryParse(NServiceBusVersion.MajorAndMinor, out version)); - } - } -} \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/Licensing/TrialLicenseReaderTests.cs b/src/NServiceBus.Core.Tests/Licensing/TrialLicenseReaderTests.cs index 025590e1b2f..b59d8ae1b0a 100644 --- a/src/NServiceBus.Core.Tests/Licensing/TrialLicenseReaderTests.cs +++ b/src/NServiceBus.Core.Tests/Licensing/TrialLicenseReaderTests.cs @@ -12,7 +12,7 @@ public class TrialLicenseReaderTests [Test] public void When_no_sub_key_exists_one_is_created() { - var subKeyPath = String.Format(@"SOFTWARE\NServiceBus\{0}", NServiceBusVersion.MajorAndMinor); + var subKeyPath = String.Format(@"SOFTWARE\NServiceBus\{0}", GitFlowVersion.MajorMinor); Registry.CurrentUser.DeleteSubKey(subKeyPath,false); var expirationFromRegistry = TrialLicenseReader.GetTrialExpirationFromRegistry(); @@ -23,7 +23,7 @@ public void When_no_sub_key_exists_one_is_created() [Test] public void When_sub_key_exists_one_is_created_the_value_is_read_from_it() { - var subKeyPath = String.Format(@"SOFTWARE\NServiceBus\{0}", NServiceBusVersion.MajorAndMinor); + var subKeyPath = String.Format(@"SOFTWARE\NServiceBus\{0}", GitFlowVersion.MajorMinor); //once to create key TrialLicenseReader.GetTrialExpirationFromRegistry(); //again to read from to create key diff --git a/src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj b/src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj index 7afc366799e..807e51de2bc 100644 --- a/src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj +++ b/src/NServiceBus.Core.Tests/NServiceBus.Core.Tests.csproj @@ -13,6 +13,7 @@ 512 true ..\NServiceBus.snk + ..\ true @@ -44,10 +45,6 @@ ..\packages\RavenDB.Database\lib\net40\AWSSDK.dll - - False - ..\..\lib\ConventionBasedHandlers.dll - ..\packages\RavenDB.Database\lib\net40\Esent.Interop.dll @@ -132,10 +129,15 @@ + + + + + + - @@ -144,7 +146,6 @@ - @@ -174,7 +175,6 @@ - @@ -186,7 +186,6 @@ - @@ -219,6 +218,7 @@ + @@ -264,6 +264,7 @@ + @@ -315,7 +316,7 @@ {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus diff --git a/src/NServiceBus.Core.Tests/NServiceBusVersionTests.cs b/src/NServiceBus.Core.Tests/NServiceBusVersionTests.cs new file mode 100644 index 00000000000..158dcc13af3 --- /dev/null +++ b/src/NServiceBus.Core.Tests/NServiceBusVersionTests.cs @@ -0,0 +1,14 @@ +namespace NServiceBus +{ + using NUnit.Framework; + + [TestFixture] + public class NServiceBusVersionTests + { + [Test] + public void Verify_has_a_version_and_can_be_parsed() + { + Assert.IsNotNullOrEmpty(NServiceBusVersion.Version); + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/EqualityExtensions.cs b/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/EqualityExtensions.cs deleted file mode 100644 index 2ef581dc377..00000000000 --- a/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/EqualityExtensions.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace NServiceBus.Core.Tests.Persistence.RavenDB.SagaPersister -{ - using System; - - public static class EqualityExtensions - { - public static bool EqualTo(this T item, object obj, Func equals) - { - if (!(obj is T)) return false; - - var x = (T)obj; - - if (item != null && x == null) return false; - - if (item == null && x != null) return false; - - if (item == null && x == null) return true; - - return equals(item, x); - } - } -} \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/TestSaga.cs b/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/TestSaga.cs index 85e6a923e19..da1514d2e8b 100644 --- a/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/TestSaga.cs +++ b/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/TestSaga.cs @@ -8,53 +8,25 @@ namespace NServiceBus.Core.Tests.Persistence.RavenDB.SagaPersister [JsonObject(IsReference = true)] public class TestSaga : IContainSagaData { - public virtual Guid Id { get; set; } - - public virtual string Originator { get; set; } - - public virtual string OriginalMessageId { get; set; } - - public virtual RelatedClass RelatedClass { get; set; } - - public virtual IList OrderLines { get; set; } - - public virtual StatusEnum Status { get; set; } - - public virtual DateTime DateTimeProperty { get; set; } - - public virtual TestComponent TestComponent { get; set; } - - public virtual PolymorphicPropertyBase PolymorphicRelatedProperty { get; set; } - - public override bool Equals(object obj) - { - return this.EqualTo(obj, (x, y) => x.Id == y.Id); - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } + public Guid Id { get; set; } + public string Originator { get; set; } + public string OriginalMessageId { get; set; } + public RelatedClass RelatedClass { get; set; } + public IList OrderLines { get; set; } + public StatusEnum Status { get; set; } + public DateTime DateTimeProperty { get; set; } + public TestComponent TestComponent { get; set; } + public PolymorphicPropertyBase PolymorphicRelatedProperty { get; set; } } public class PolymorphicProperty : PolymorphicPropertyBase { - public virtual int SomeInt { get; set; } - - public override bool Equals(object obj) - { - return this.EqualTo(obj, (x, y) => x.Id == y.Id && x.SomeInt == y.SomeInt); - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } + public int SomeInt { get; set; } } public class PolymorphicPropertyBase { - public virtual Guid Id { get; set; } + public Guid Id { get; set; } } public enum StatusEnum @@ -66,32 +38,17 @@ public class TestComponent { public string Property { get; set; } public string AnotherProperty { get; set; } - - public override bool Equals(object obj) - { - return this.EqualTo(obj, (x, y) => - x.Property == y.Property && - x.AnotherProperty == y.AnotherProperty); - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } } public class OrderLine { - public virtual Guid Id { get; set; } - - public virtual Guid ProductId { get; set; } - + public Guid Id { get; set; } + public Guid ProductId { get; set; } } public class RelatedClass { - public virtual Guid Id { get; set; } - - public virtual TestSaga ParentSaga { get; set; } + public Guid Id { get; set; } + public TestSaga ParentSaga { get; set; } } } \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/When_persisting_a_saga_entity_with_a_concrete_class_property.cs b/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/When_persisting_a_saga_entity_with_a_concrete_class_property.cs index da0d5ee484d..c2e800f0d57 100644 --- a/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/When_persisting_a_saga_entity_with_a_concrete_class_property.cs +++ b/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/When_persisting_a_saga_entity_with_a_concrete_class_property.cs @@ -12,7 +12,7 @@ public override void SetupEntity(TestSaga saga) [Test] public void Public_setters_and_getters_of_concrete_classes_should_be_persisted() { - Assert.AreEqual(entity.TestComponent, savedEntity.TestComponent); + Assert.AreEqual(entity.TestComponent.Property, savedEntity.TestComponent.Property); } } } \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/When_persisting_a_saga_entity_with_inherited_property.cs b/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/When_persisting_a_saga_entity_with_inherited_property.cs index 5da3ae90698..dbbf873a3b8 100644 --- a/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/When_persisting_a_saga_entity_with_inherited_property.cs +++ b/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/When_persisting_a_saga_entity_with_inherited_property.cs @@ -12,7 +12,9 @@ public override void SetupEntity(TestSaga saga) [Test] public void Inherited_property_classes_should_be_persisted() { - Assert.AreEqual(entity.PolymorphicRelatedProperty, savedEntity.PolymorphicRelatedProperty); + var polymorphicRelatedProperty = (PolymorphicProperty)savedEntity.PolymorphicRelatedProperty; + var polymorphicProperty = (PolymorphicProperty)entity.PolymorphicRelatedProperty; + Assert.AreEqual(polymorphicProperty.SomeInt, polymorphicRelatedProperty.SomeInt); } } } \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/When_persisting_a_saga_entity_with_related_entities.cs b/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/When_persisting_a_saga_entity_with_related_entities.cs index 09afbb01ce9..1b870de464f 100644 --- a/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/When_persisting_a_saga_entity_with_related_entities.cs +++ b/src/NServiceBus.Core.Tests/Persistence/RavenDB/SagaPersister/When_persisting_a_saga_entity_with_related_entities.cs @@ -12,7 +12,7 @@ public override void SetupEntity(TestSaga saga) [Test] public void Related_entities_should_also_be_persisted() { - Assert.AreEqual(entity, savedEntity.RelatedClass.ParentSaga); + Assert.AreEqual(entity.Id, savedEntity.RelatedClass.ParentSaga.Id); } [Test] diff --git a/src/NServiceBus.Core.Tests/Pipeline/BehaviorConventions.cs b/src/NServiceBus.Core.Tests/Pipeline/BehaviorConventions.cs new file mode 100644 index 00000000000..aff441ba135 --- /dev/null +++ b/src/NServiceBus.Core.Tests/Pipeline/BehaviorConventions.cs @@ -0,0 +1,31 @@ +namespace NServiceBus.Core.Tests.Pipeline +{ + using System; + using System.ComponentModel; + using System.Linq; + using NServiceBus.Pipeline; + using NUnit.Framework; + + [TestFixture] + public class BehaviorConventions + { + [Test] + public void Verify() + { + var allBehaviors = typeof(IBehavior<>).Assembly.GetTypes() + .Where(x => x.GetInterfaces().Any(y => y.Name.Contains("IBehavior"))); + foreach (var behavior in allBehaviors) + { + Assert.IsTrue(behavior.IsPublic, behavior + " should be public"); + var customAttributes = behavior.GetCustomAttributes(typeof(ObsoleteAttribute),false); + Assert.IsNotEmpty(customAttributes, behavior + " should be marked with an ObsoleteAttribute"); + var obsoleteAttribute = (ObsoleteAttribute)customAttributes.First(); + Assert.AreEqual("This is a prototype API. May change in minor version releases.", obsoleteAttribute.Message, behavior + " should be marked with an ObsoleteAttribute"); + var editorAttributes = behavior.GetCustomAttributes(typeof(EditorBrowsableAttribute), false); + Assert.IsNotEmpty(editorAttributes, behavior + " should be marked with an EditorBrowsableAttribute"); + var editorBrowsableAttribute = (EditorBrowsableAttribute)editorAttributes.First(); + Assert.AreEqual(EditorBrowsableState.Never, editorBrowsableAttribute.State, behavior + " should be marked with an EditorBrowsableAttribute"); + } + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/Pipeline/BehaviorListTests.cs b/src/NServiceBus.Core.Tests/Pipeline/BehaviorListTests.cs new file mode 100644 index 00000000000..3d9235baee1 --- /dev/null +++ b/src/NServiceBus.Core.Tests/Pipeline/BehaviorListTests.cs @@ -0,0 +1,142 @@ +namespace NServiceBus.Core.Tests.Pipeline +{ + using System; + using System.Collections.Generic; + using System.Linq; + using NServiceBus.Pipeline; + using NUnit.Framework; + + [TestFixture] + public class BehaviorListTests + { + [Test] + public void Replace() + { + var behaviorList = new BehaviorList + { + InnerList = new List + { + typeof(Behavior1) + } + }; + behaviorList.Replace(); + Assert.AreEqual(1, behaviorList.InnerList.Count); + Assert.AreEqual(typeof(Behavior2), behaviorList.InnerList.First()); + } + + [Test] + public void Add() + { + var behaviorList = new BehaviorList + { + InnerList = new List + { + typeof(Behavior1) + } + }; + behaviorList.Add(); + Assert.AreEqual(2, behaviorList.InnerList.Count); + Assert.AreEqual(typeof(Behavior2), behaviorList.InnerList[1]); + } + + [Test] + public void InsertAfter() + { + var behaviorList = new BehaviorList + { + InnerList = new List + { + typeof(Behavior1), + typeof(Behavior2), + } + }; + behaviorList.InsertAfter(); + Assert.AreEqual(3, behaviorList.InnerList.Count); + Assert.AreEqual(typeof(Behavior3), behaviorList.InnerList[1]); + } + + [Test] + public void When_InsertAfter_and_target_does_not_exists_should_throw() + { + var behaviorList = new BehaviorList(); + var exception = Assert.Throws(behaviorList.InsertAfter); + Assert.AreEqual("Could not InsertAfter since 'Behavior1' does not exist.", exception.Message); + } + + [Test] + public void Remove() + { + var behaviorList = new BehaviorList + { + InnerList = new List + { + typeof(Behavior1), + typeof(Behavior2), + } + }; + Assert.IsTrue(behaviorList.Remove()); + Assert.AreEqual(1, behaviorList.InnerList.Count); + Assert.AreEqual(typeof(Behavior1), behaviorList.InnerList[0]); + } + + [Test] + public void When_replacing_and_target_does_not_exists_should_throw() + { + var behaviorList = new BehaviorList(); + var exception = Assert.Throws(behaviorList.Replace); + Assert.AreEqual("Could not replace since 'Behavior1' does not exist.", exception.Message); + } + + [Test] + public void InsertBefore() + { + var behaviorList = new BehaviorList + { + InnerList = new List + { + typeof(Behavior1), + typeof(Behavior2), + } + }; + behaviorList.InsertBefore(); + Assert.AreEqual(3, behaviorList.InnerList.Count); + Assert.AreEqual(typeof(Behavior3), behaviorList.InnerList[1]); + } + + [Test] + public void When_InsertBefore_and_target_does_not_exists_should_throw() + { + var behaviorList = new BehaviorList(); + var exception = Assert.Throws(behaviorList.InsertBefore); + Assert.AreEqual("Could not InsertBefore since 'Behavior1' does not exist.", exception.Message); + } + + class Behavior1 : IBehavior + { + public void Invoke(FakeContext context, Action next) + { + } + } + + class Behavior2 : IBehavior + { + public void Invoke(FakeContext context, Action next) + { + } + } + + class Behavior3 : IBehavior + { + public void Invoke(FakeContext context, Action next) + { + } + } + + class FakeContext : BehaviorContext + { + public FakeContext(BehaviorContext parentContext) : base(parentContext) + { + } + } + } +} diff --git a/src/NServiceBus.Core.Tests/StringStreamExtensions.cs b/src/NServiceBus.Core.Tests/StringStreamExtensions.cs new file mode 100644 index 00000000000..d78b10268ed --- /dev/null +++ b/src/NServiceBus.Core.Tests/StringStreamExtensions.cs @@ -0,0 +1,23 @@ +namespace NServiceBus.Core.Tests +{ + using System.IO; + + public static class StringStreamExtensions + { + public static Stream ConvertToStream(this string s) + { + var stream = new MemoryStream(); + var writer = new StreamWriter(stream); + writer.Write(s); + writer.Flush(); + stream.Position = 0; + return stream; + } + public static string ConvertToString(this Stream stream) + { + stream.Position = 0; + var sr = new StreamReader(stream); + return sr.ReadToEnd(); + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/Transport/When_specifying_a_queu_name_for_msmq_with_total_length_including_machine_name_and_private_identifier_exceeding_114_characters.cs b/src/NServiceBus.Core.Tests/Transport/When_specifying_a_queu_name_for_msmq_with_total_length_including_machine_name_and_private_identifier_exceeding_114_characters.cs new file mode 100644 index 00000000000..3105d2b198b --- /dev/null +++ b/src/NServiceBus.Core.Tests/Transport/When_specifying_a_queu_name_for_msmq_with_total_length_including_machine_name_and_private_identifier_exceeding_114_characters.cs @@ -0,0 +1,25 @@ +namespace NServiceBus.Core.Tests.Transport +{ + using System; + using NUnit.Framework; + using Transports.Msmq; + + [TestFixture] + public class When_specifying_a_queu_name_for_msmq_with_total_length_including_machine_name_and_private_identifier_exceeding_114_characters + { + [Test] + public void Should_be_replaced_by_a_deterministic_guid () + { + var address = Address.Parse("WhenSpecifyingAQueuNameWithTotalLengthIncludingMachineNameAndPrivateIdentifierExceeding114Chars@MyMachine"); + + var path = MsmqQueueCreator.GetFullPathWithoutPrefix(address); + var queueName = path.Replace(@"MyMachine\private$\", ""); + + var secondPath = MsmqQueueCreator.GetFullPathWithoutPrefix(address); + + Guid isAGuid; + Assert.IsTrue(Guid.TryParse(queueName, out isAGuid)); + Assert.AreEqual(path, secondPath); + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core.Tests/Unicast/Contexts/using_the_unicastbus.cs b/src/NServiceBus.Core.Tests/Unicast/Contexts/using_the_unicastbus.cs index e616cc88d03..d9f5455939b 100644 --- a/src/NServiceBus.Core.Tests/Unicast/Contexts/using_the_unicastbus.cs +++ b/src/NServiceBus.Core.Tests/Unicast/Contexts/using_the_unicastbus.cs @@ -45,7 +45,7 @@ public class using_a_configured_unicastBus protected FakeTransport Transport; protected XmlMessageSerializer MessageSerializer; protected FuncBuilder FuncBuilder; - protected Address MasterNodeAddress; + public static Address MasterNodeAddress; protected EstimatedTimeToSLABreachCalculator SLABreachCalculator = new EstimatedTimeToSLABreachCalculator(); protected MessageMetadataRegistry MessageMetadataRegistry; protected MessageDrivenSubscriptionManager subscriptionManager; @@ -55,7 +55,14 @@ public class using_a_configured_unicastBus protected MessageHandlerRegistry handlerRegistry; protected TransportDefinition transportDefinition; - PipelineFactory pipelineFactory; + PipelineExecutor pipelineFactory; + + static using_a_configured_unicastBus() + { + var localAddress = "endpointA"; + MasterNodeAddress = new Address(localAddress, "MasterNode"); + Address.InitializeLocalAddress(localAddress); + } [SetUp] public void SetUp() @@ -71,8 +78,6 @@ public void SetUp() Transport = new FakeTransport(); FuncBuilder = new FuncBuilder(); Configure.GetEndpointNameAction = () => "TestEndpoint"; - const string localAddress = "endpointA"; - MasterNodeAddress = new Address(localAddress, "MasterNode"); subscriptionPredicatesEvaluator = new SubscriptionPredicatesEvaluator(); router = new StaticMessageRouter(KnownMessageTypes()); handlerRegistry = new MessageHandlerRegistry(); @@ -81,13 +86,6 @@ public void SetUp() DefaultToNonPersistentMessages = false }; - try - { - Address.InitializeLocalAddress(localAddress); - } - catch // intentional - { - } MessageSerializer = new XmlMessageSerializer(MessageMapper); //ExtensionMethods.GetStaticOutgoingHeadersAction = () => MessageHeaderManager.staticHeaders; @@ -102,7 +100,8 @@ public void SetUp() SubscriptionStorage = subscriptionStorage }; - pipelineFactory = new PipelineFactory { RootBuilder = FuncBuilder }; + var pipelineBuilder = new PipelineBuilder(FuncBuilder); + pipelineFactory = new PipelineExecutor(FuncBuilder , pipelineBuilder); FuncBuilder.Register(() => MessageSerializer); FuncBuilder.Register(() => messageSender); @@ -134,7 +133,8 @@ public void SetUp() }); FuncBuilder.Register(() => new CreatePhysicalMessageBehavior()); - FuncBuilder.Register(() => pipelineFactory); + FuncBuilder.Register(() => pipelineBuilder); + FuncBuilder.Register(() => pipelineFactory); FuncBuilder.Register(() => transportDefinition); @@ -144,13 +144,13 @@ public void SetUp() SubscriptionStorage = subscriptionStorage }; - var deferer = new TimeoutManagerDeferrer + var deferrer = new TimeoutManagerDeferrer { MessageSender = messageSender, TimeoutManagerAddress = MasterNodeAddress.SubScope("Timeouts") }; - FuncBuilder.Register(() => deferer); + FuncBuilder.Register(() => deferrer); FuncBuilder.Register(() => messagePublisher); unicastBus = new UnicastBus @@ -289,6 +289,8 @@ public class using_the_unicastBus : using_a_configured_unicastBus protected Exception ResultingException; + protected TransportMessage AuditedMessage; + protected void ReceiveMessage(TransportMessage transportMessage) { try @@ -303,6 +305,8 @@ protected void ReceiveMessage(TransportMessage transportMessage) ExtensionMethods.SetHeaderAction = (o, s, v) => { transportMessage.Headers[s] = v; }; Transport.FakeMessageBeingProcessed(transportMessage); + + AuditedMessage = transportMessage; } catch (Exception ex) { diff --git a/src/NServiceBus.Core.Tests/Unicast/DeferedMessages.cs b/src/NServiceBus.Core.Tests/Unicast/DeferedMessages.cs index 47b10fda4d7..b08eea5651f 100644 --- a/src/NServiceBus.Core.Tests/Unicast/DeferedMessages.cs +++ b/src/NServiceBus.Core.Tests/Unicast/DeferedMessages.cs @@ -56,7 +56,7 @@ public void Should_set_the_expiry_header_to_a_absolute_utc_time() } [TestFixture] - public class When_shortcutting_defered_messages_that_already_has_expired : using_the_unicastBus + public class When_short_cutting_deferred_messages_that_already_has_expired : using_the_unicastBus { [Test] public void Should_use_utc_when_comparing() @@ -66,7 +66,7 @@ public void Should_use_utc_when_comparing() bus.Defer(time, new DeferredMessage()); - //no expiry header should be there since this message will be trated as a send local + //no expiry header should be there since this message will be treated as a send local VerifyThatMessageWasSentWithHeaders(h => !h.ContainsKey(TimeoutManagerHeaders.Expire)); } } diff --git a/src/NServiceBus.Core.Tests/Unicast/Sagas.cs b/src/NServiceBus.Core.Tests/Unicast/Sagas.cs index 1d8aaea81bf..d263c21952e 100644 --- a/src/NServiceBus.Core.Tests/Unicast/Sagas.cs +++ b/src/NServiceBus.Core.Tests/Unicast/Sagas.cs @@ -88,6 +88,27 @@ public void Should_find_existing_instance_by_property() } + [Test] + public void Should_enrich_the_audit_data_with_the_saga_type_and_id() + { + var sagaId = Guid.NewGuid(); + var correlationId = Guid.NewGuid(); + + RegisterSaga(new MySagaData { Id = sagaId, PropertyThatCorrelatesToMessage = correlationId }); + + ReceiveMessage(new MessageThatHitsExistingSaga { PropertyThatCorrelatesToSaga = correlationId }); + + var sagaAuditTrail = AuditedMessage.Headers[Headers.InvokedSagas]; + + var sagas = sagaAuditTrail.Split(';'); + + var sagaInfo = sagas.Single(); + + Assert.AreEqual(typeof(MySaga).FullName,sagaInfo.Split(':').First()); + Assert.AreEqual(sagaId.ToString(), sagaInfo.Split(':').Last()); + } + + class MySaga : Saga, IHandleMessages { public void Handle(MessageThatHitsExistingSaga message) @@ -425,5 +446,46 @@ class MessageSentFromSaga : IMessage{ } } + + [TestFixture] + public class When_using_in_memory_raise_from_non_message_handlers : with_sagas + { + [Test] + public void Should_start_the_saga() + { + RegisterMessageType(); + RegisterSaga(); + + bus.InMemory.Raise(new MessageToProcess()); + + var sagaData = (MySagaData)persister.CurrentSagaEntities.First().Value.SagaEntity; + + messageSender.AssertWasCalled(x => + x.Send(Arg.Matches(m => + m.Headers[Headers.OriginatingSagaId] == sagaData.Id.ToString() && //id of the current saga + //todo: should we really us the AssemblyQualifiedName here? (what if users move sagas btw assemblies + m.Headers[Headers.OriginatingSagaType] == typeof(MySaga).AssemblyQualifiedName + ), Arg
.Is.Anything)); + } + + + class MySaga : Saga, IAmStartedByMessages + { + public void Handle(MessageToProcess message) + { + Bus.Send(new MessageSentFromSaga()); + } + } + + class MySagaData : ContainSagaData + { + } + + class MessageToProcess : IMessage { } + + class MessageSentFromSaga : IMessage { } + + } + } diff --git a/src/NServiceBus.Core.Tests/Unicast/Sending.cs b/src/NServiceBus.Core.Tests/Unicast/Sending.cs index 527bb8abffc..69429ba680e 100644 --- a/src/NServiceBus.Core.Tests/Unicast/Sending.cs +++ b/src/NServiceBus.Core.Tests/Unicast/Sending.cs @@ -80,8 +80,8 @@ public void The_content_type_should_be_set() RegisterMessageType(); bus.Send(new TestMessage()); - - messageSender.AssertWasCalled(x => x.Send(Arg.Matches(m => + + messageSender.AssertWasCalled(x => x.Send(Arg.Matches(m => m.Headers[Headers.ContentType] == "text/xml" && m.Headers["MyStaticHeader"] == "StaticHeaderValue"), Arg
.Is.Anything)); } @@ -119,7 +119,7 @@ public void Should_not_override_a_conversation_id_specified_by_the_user() RegisterMessageType(); - bus.Send(m=>m.SetHeader(Headers.ConversationId,"my order id")); + bus.Send(m => m.SetHeader(Headers.ConversationId, "my order id")); messageSender.AssertWasCalled(x => x.Send(Arg.Matches(m => m.Headers[Headers.ConversationId] == "my order id"), Arg
.Is.Anything)); } @@ -171,8 +171,8 @@ public void Should_throw_if_messages_contain_different_configured_addresses() var secondAddress = Address.Parse("second"); RegisterMessageType(firstAddress); RegisterMessageType(secondAddress); - - Assert.Throws(()=> bus.Send(new NonPersistentMessage(), new PersistentMessage())); + + Assert.Throws(() => bus.Send(new NonPersistentMessage(), new PersistentMessage())); } @@ -230,7 +230,7 @@ public void Should_specify_the_message_to_be_recoverable() [TestFixture] public class When_raising_an_in_memory_message : using_the_unicastBus { - [Test,Ignore("Not supported for now")] + [Test] public void Should_invoke_registered_message_handlers() { RegisterMessageType(); @@ -248,6 +248,7 @@ public void Should_invoke_registered_message_handlers() Assert.True(TestMessageHandler2.Called); } + public class TestMessageHandler1 : IHandleMessages { public static bool Called; @@ -282,23 +283,23 @@ public void Should_invoke_registered_message_handlers() receivedMessage.Headers["HeaderOnPhysicalMessage"] = "SomeValue"; RegisterMessageType(); - + RegisterMessageHandlerType(); RegisterMessageHandlerType(); ReceiveMessage(receivedMessage); - + Assert.True(RaisedMessageHandler.Called); } - class StartMessage:IMessage + class StartMessage : IMessage { - + } class RaisedMessage { - + } class StartHandler : IHandleMessages @@ -320,7 +321,7 @@ class RaisedMessageHandler : IHandleMessages public void Handle(RaisedMessage message) { - Assert.AreEqual("MyHeaderValue",Headers.GetMessageHeader(message, "MyHeader")); + Assert.AreEqual("MyHeaderValue", Headers.GetMessageHeader(message, "MyHeader")); Assert.AreEqual("SomeValue", Headers.GetMessageHeader(message, "HeaderOnPhysicalMessage")); @@ -353,9 +354,9 @@ public void The_saga_id_header_should_point_to_the_saga_we_are_replying_to() AssertSendWithHeaders(headers => headers[Headers.SagaId] == sagaId.ToString() && headers[Headers.SagaType] == sagaType); } - void AssertSendWithHeaders(Func,bool> condition) + void AssertSendWithHeaders(Func, bool> condition) { - messageSender.AssertWasCalled(x =>x.Send(Arg.Matches(m =>condition(m.Headers)), Arg
.Is.Anything)); + messageSender.AssertWasCalled(x => x.Send(Arg.Matches(m => condition(m.Headers)), Arg
.Is.Anything)); } diff --git a/src/NServiceBus.Core/Audit/Audit.cs b/src/NServiceBus.Core/Audit/Audit.cs index e05b0eb92eb..1b0d5eb4b95 100644 --- a/src/NServiceBus.Core/Audit/Audit.cs +++ b/src/NServiceBus.Core/Audit/Audit.cs @@ -3,7 +3,7 @@ using System; using System.Diagnostics; using Config; - using log4net; + using Logging; using NServiceBus.Audit; using Utils; diff --git a/src/NServiceBus.Core/Audit/AuditBehavior.cs b/src/NServiceBus.Core/Audit/AuditBehavior.cs index a86ed0c6d8f..758be299814 100644 --- a/src/NServiceBus.Core/Audit/AuditBehavior.cs +++ b/src/NServiceBus.Core/Audit/AuditBehavior.cs @@ -1,10 +1,14 @@ namespace NServiceBus.Audit { using System; + using System.ComponentModel; using Pipeline; using Pipeline.Contexts; - class AuditBehavior : IBehavior + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class AuditBehavior : IBehavior { public MessageAuditer MessageAuditer { get; set; } diff --git a/src/NServiceBus.Core/CircuitBreakers/CircuitBreaker.cs b/src/NServiceBus.Core/CircuitBreakers/CircuitBreaker.cs index 1b0e7c2f03e..bd83114fb40 100644 --- a/src/NServiceBus.Core/CircuitBreakers/CircuitBreaker.cs +++ b/src/NServiceBus.Core/CircuitBreakers/CircuitBreaker.cs @@ -11,7 +11,7 @@ public class CircuitBreaker : IDisposable readonly int threshold; int firedTimes; // ReSharper disable once NotAccessedField.Local - readonly Timer timer; + Timer timer; int failureCount; /// diff --git a/src/NServiceBus.Core/CircuitBreakers/RepeatedFailuresOverTimeCircuitBreaker.cs b/src/NServiceBus.Core/CircuitBreakers/RepeatedFailuresOverTimeCircuitBreaker.cs index 5bfc523528a..5d3d53eed88 100644 --- a/src/NServiceBus.Core/CircuitBreakers/RepeatedFailuresOverTimeCircuitBreaker.cs +++ b/src/NServiceBus.Core/CircuitBreakers/RepeatedFailuresOverTimeCircuitBreaker.cs @@ -72,8 +72,8 @@ void CircuitBreakerTriggered(object state) readonly TimeSpan delayAfterFailure; readonly string name; - readonly TimeSpan timeToWaitBeforeTriggering; - readonly Timer timer; + TimeSpan timeToWaitBeforeTriggering; + Timer timer; readonly Action triggerAction; long failureCount; Exception lastException; diff --git a/src/NServiceBus.Core/Config/Conventions/SystemMessageConventions.cs b/src/NServiceBus.Core/Config/Conventions/SystemMessageConventions.cs index 56f743e45ae..1569134e97f 100644 --- a/src/NServiceBus.Core/Config/Conventions/SystemMessageConventions.cs +++ b/src/NServiceBus.Core/Config/Conventions/SystemMessageConventions.cs @@ -5,12 +5,12 @@ namespace NServiceBus.Config.Conventions /// /// Define system message convention /// + [ObsoleteEx(RemoveInVersion = "5.0", TreatAsErrorFromVersion = "4.0")] public static class SystemMessageConventions { /// /// Add system messages convention /// - [ObsoleteEx(Message = "Moved to NServiceBus namespace.", RemoveInVersion = "5.0", TreatAsErrorFromVersion = "4.0")] public static Configure AddSystemMessagesAs(this Configure config, Func definesMessageType) { MessageConventionExtensions.AddSystemMessagesConventions(definesMessageType); @@ -26,6 +26,7 @@ namespace NServiceBus /// /// Define system message convention /// + [ObsoleteEx(RemoveInVersion = "5.0", TreatAsErrorFromVersion = "4.0")] public static class SystemMessageConventions { /// diff --git a/src/NServiceBus.Hosting.Windows/Profiles/Handlers/WindowsInstallerRunner.cs b/src/NServiceBus.Core/Config/WindowsInstallerRunner.cs similarity index 73% rename from src/NServiceBus.Hosting.Windows/Profiles/Handlers/WindowsInstallerRunner.cs rename to src/NServiceBus.Core/Config/WindowsInstallerRunner.cs index 8dab2ed6fc8..53583905519 100644 --- a/src/NServiceBus.Hosting.Windows/Profiles/Handlers/WindowsInstallerRunner.cs +++ b/src/NServiceBus.Core/Config/WindowsInstallerRunner.cs @@ -1,33 +1,38 @@ -namespace NServiceBus.Hosting.Windows.Profiles.Handlers +namespace NServiceBus.Config { using System.Diagnostics; - using Config; /// /// Responsible for running the installers if necessary /// public class WindowsInstallerRunner : IWantToRunWhenConfigurationIsComplete { + static WindowsInstallerRunner() + { + RunInstallers = Debugger.IsAttached; + } + /// /// True if installers should be invoked /// public static bool RunInstallers { get; set; } - internal static string RunAs { get; set; } + public static string RunAs { get; set; } /// /// Runs the installers if necessary. /// public void Run() { - if (Debugger.IsAttached) - RunInstallers = true; - - if (!RunInstallers) + if (!RunInstallers) + { return; - + } + if (RunInstallers) + { Installer.RunOtherInstallers = true; + } Configure.Instance.ForInstallationOn(RunAs).Install(); } diff --git a/src/NServiceBus.Core/DataBus/DataBusReceiveBehavior.cs b/src/NServiceBus.Core/DataBus/DataBusReceiveBehavior.cs index 366cd53b881..11a91d85d22 100644 --- a/src/NServiceBus.Core/DataBus/DataBusReceiveBehavior.cs +++ b/src/NServiceBus.Core/DataBus/DataBusReceiveBehavior.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; + using System.ComponentModel; using System.Linq; using System.Reflection; using System.Transactions; @@ -10,7 +11,10 @@ using Pipeline; using Pipeline.Contexts; - class DataBusReceiveBehavior : IBehavior + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class DataBusReceiveBehavior : IBehavior { public IDataBus DataBus { get; set; } diff --git a/src/NServiceBus.Core/DataBus/DataBusSendBehavior.cs b/src/NServiceBus.Core/DataBus/DataBusSendBehavior.cs index 36ffcb9f2b5..68341259a42 100644 --- a/src/NServiceBus.Core/DataBus/DataBusSendBehavior.cs +++ b/src/NServiceBus.Core/DataBus/DataBusSendBehavior.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; + using System.ComponentModel; using System.IO; using System.Linq; using System.Reflection; @@ -11,7 +12,9 @@ using Pipeline; using Pipeline.Contexts; - class DataBusSendBehavior : IBehavior + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class DataBusSendBehavior : IBehavior { public IDataBus DataBus { get; set; } diff --git a/src/NServiceBus.Core/Distributor/DistributorReadyMessageProcessor.cs b/src/NServiceBus.Core/Distributor/DistributorReadyMessageProcessor.cs index 91bac99c739..8551a18e474 100644 --- a/src/NServiceBus.Core/Distributor/DistributorReadyMessageProcessor.cs +++ b/src/NServiceBus.Core/Distributor/DistributorReadyMessageProcessor.cs @@ -98,9 +98,10 @@ private void HandleControlMessage(TransportMessage controlMessage) Logger.InfoFormat("Worker {0} has started up, clearing previous reported capacity", replyToAddress); } - if (controlMessage.Headers.ContainsKey(Headers.WorkerCapacityAvailable)) + string workerCapacityAvailable; + if (controlMessage.Headers.TryGetValue(Headers.WorkerCapacityAvailable, out workerCapacityAvailable)) { - var capacity = int.Parse(controlMessage.Headers[Headers.WorkerCapacityAvailable]); + var capacity = int.Parse(workerCapacityAvailable); WorkerAvailabilityManager.WorkerAvailable(replyToAddress, capacity); diff --git a/src/NServiceBus.Core/Encryption/EncryptionMessageMutator.cs b/src/NServiceBus.Core/Encryption/EncryptionMessageMutator.cs index c4c22d585dc..75fc0341688 100644 --- a/src/NServiceBus.Core/Encryption/EncryptionMessageMutator.cs +++ b/src/NServiceBus.Core/Encryption/EncryptionMessageMutator.cs @@ -244,14 +244,15 @@ static IEnumerable GetFieldsAndProperties(object target) var messageType = target.GetType(); - if (!cache.ContainsKey(messageType)) + IEnumerable members; + if (!cache.TryGetValue(messageType, out members)) { - cache[messageType] = messageType.GetMembers(BindingFlags.Public | BindingFlags.Instance) + cache[messageType] = members = messageType.GetMembers(BindingFlags.Public | BindingFlags.Instance) .Where(m => m is FieldInfo || m is PropertyInfo) .ToList(); } - return cache[messageType]; + return members; } HashSet visitedMembers = new HashSet(); diff --git a/src/NServiceBus.Core/Features/Feature.cs b/src/NServiceBus.Core/Features/Feature.cs index 39eddc05bd6..c64ac0faf29 100644 --- a/src/NServiceBus.Core/Features/Feature.cs +++ b/src/NServiceBus.Core/Features/Feature.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using Settings; + using Utils; /// /// Used to control the various features supported by the framework. @@ -154,6 +155,20 @@ public static IEnumerable ByCategory(FeatureCategory category) return result; } + public string Version + { + get + { + return FileVersionRetriever.GetFileVersion(GetType()); + } + } + + public override string ToString() + { + + return string.Format("{0} [{1}]",Name, Version); + } + protected bool Equals(Feature other) { return string.Equals(name, other.name); diff --git a/src/NServiceBus.Core/Features/Support/FeatureInitializer.cs b/src/NServiceBus.Core/Features/Support/FeatureInitializer.cs index 3ed58e5209d..acdfa822a91 100644 --- a/src/NServiceBus.Core/Features/Support/FeatureInitializer.cs +++ b/src/NServiceBus.Core/Features/Support/FeatureInitializer.cs @@ -47,20 +47,20 @@ static void InitializeFeatures() if (feature.Category != FeatureCategory.None) { - statusText.AppendLine(string.Format("{0} - Controlled by category {1}", feature.Name, + statusText.AppendLine(string.Format("{0} - Controlled by category {1}", feature, feature.Category.Name)); return; } if (!Feature.IsEnabled(t)) { - statusText.AppendLine(string.Format("{0} - Disabled", feature.Name)); + statusText.AppendLine(string.Format("{0} - Disabled", feature)); return; } feature.Initialize(); - statusText.AppendLine(string.Format("{0} - Enabled", feature.Name)); + statusText.AppendLine(string.Format("{0} - Enabled", feature)); }); Logger.InfoFormat("Features: \n{0}", statusText); diff --git a/src/NServiceBus.Core/Gateway/Channels/DataReceivedOnChannelArgs.cs b/src/NServiceBus.Core/Gateway/Channels/DataReceivedOnChannelArgs.cs new file mode 100644 index 00000000000..63968d1d34f --- /dev/null +++ b/src/NServiceBus.Core/Gateway/Channels/DataReceivedOnChannelArgs.cs @@ -0,0 +1,13 @@ +namespace NServiceBus.Gateway.Channels +{ + using System; + using System.Collections.Generic; + using System.IO; + + public class DataReceivedOnChannelArgs : EventArgs + { + public IDictionary Headers { get; set; } + + public Stream Data { get; set; } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core/Gateway/Channels/Http/HttpChannelSender.cs b/src/NServiceBus.Core/Gateway/Channels/Http/HttpChannelSender.cs index 1250796efa9..869509e79a1 100644 --- a/src/NServiceBus.Core/Gateway/Channels/Http/HttpChannelSender.cs +++ b/src/NServiceBus.Core/Gateway/Channels/Http/HttpChannelSender.cs @@ -46,9 +46,9 @@ static WebHeaderCollection Encode(IDictionary headers) { var webHeaders = new WebHeaderCollection(); - foreach (var header in headers.Keys) + foreach (var pair in headers) { - webHeaders.Add(HttpUtility.UrlEncode(header), HttpUtility.UrlEncode(headers[header])); + webHeaders.Add(HttpUtility.UrlEncode(pair.Key), HttpUtility.UrlEncode(pair.Value)); } return webHeaders; diff --git a/src/NServiceBus.Core/Gateway/Channels/IChannelReceiver.cs b/src/NServiceBus.Core/Gateway/Channels/IChannelReceiver.cs index af909ec1b97..7441c817be6 100644 --- a/src/NServiceBus.Core/Gateway/Channels/IChannelReceiver.cs +++ b/src/NServiceBus.Core/Gateway/Channels/IChannelReceiver.cs @@ -1,8 +1,6 @@ namespace NServiceBus.Gateway.Channels { using System; - using System.Collections.Generic; - using System.IO; public interface IChannelReceiver : IDisposable { @@ -10,11 +8,4 @@ public interface IChannelReceiver : IDisposable void Start(string address, int numberOfWorkerThreads); } - - public class DataReceivedOnChannelArgs : EventArgs - { - public IDictionary Headers { get; set; } - - public Stream Data { get; set; } - } } \ No newline at end of file diff --git a/src/NServiceBus.Core/Gateway/GatewayExtensions.cs b/src/NServiceBus.Core/Gateway/GatewayExtensions.cs index 5181276c466..e9e17cfc913 100644 --- a/src/NServiceBus.Core/Gateway/GatewayExtensions.cs +++ b/src/NServiceBus.Core/Gateway/GatewayExtensions.cs @@ -20,9 +20,10 @@ public static bool IsLegacyGatewayMessage(this TransportMessage message) var legacyMode = true; // Gateway v3 would never have sent this header - if (message.Headers.ContainsKey(GatewayHeaders.LegacyMode)) + string legacyModeString; + if (message.Headers.TryGetValue(GatewayHeaders.LegacyMode, out legacyModeString)) { - bool.TryParse(message.Headers[GatewayHeaders.LegacyMode], out legacyMode); + bool.TryParse(legacyModeString, out legacyMode); } return legacyMode; diff --git a/src/NServiceBus.Core/Gateway/GatewayTransaction.cs b/src/NServiceBus.Core/Gateway/GatewayTransaction.cs new file mode 100644 index 00000000000..10ba9d0d53b --- /dev/null +++ b/src/NServiceBus.Core/Gateway/GatewayTransaction.cs @@ -0,0 +1,36 @@ +namespace NServiceBus.Gateway +{ + using System; + using System.Transactions; + using Config; + + internal static class GatewayTransaction + { + private static readonly GatewayConfig Config; + + static GatewayTransaction() + { + Config = Configure.GetConfigSection(); + } + + internal static TimeSpan Timeout(TimeSpan defaultTimeout) + { + if (Config != null && Config.TransactionTimeout > defaultTimeout) + { + return Config.TransactionTimeout; + } + + return defaultTimeout; + } + + internal static TransactionScope Scope() + { + return new TransactionScope(TransactionScopeOption.RequiresNew, + new TransactionOptions + { + IsolationLevel = IsolationLevel.ReadCommitted, + Timeout = Timeout(TimeSpan.FromSeconds(30)), + }); + } + } +} diff --git a/src/NServiceBus.Core/Gateway/HeaderManagement/DataBusHeaderManager.cs b/src/NServiceBus.Core/Gateway/HeaderManagement/DataBusHeaderManager.cs index 338865989b7..f540c25e0a2 100644 --- a/src/NServiceBus.Core/Gateway/HeaderManagement/DataBusHeaderManager.cs +++ b/src/NServiceBus.Core/Gateway/HeaderManagement/DataBusHeaderManager.cs @@ -34,20 +34,19 @@ public IDictionary Reassemble(string clientId, IDictionary collection; if (!headers.TryGetValue(clientId, out collection)) { - throw new ChannelException(412, - string.Format("Expected {0} databus properties. None were received. Please resubmit.", - expectedDatabusProperties.Count)); + var message = string.Format("Expected {0} databus properties. None were received. Please resubmit.",expectedDatabusProperties.Count); + throw new ChannelException(412,message); } foreach (var propertyHeader in expectedDatabusProperties) { - if (!collection.ContainsKey(propertyHeader.Key)) + string propertyValue; + if (!collection.TryGetValue(propertyHeader.Key, out propertyValue)) { - throw new ChannelException(412, - string.Format("Databus property {0} was never received. Please resubmit.", - propertyHeader.Key)); + var message = string.Format("Databus property {0} was never received. Please resubmit.",propertyHeader.Key); + throw new ChannelException(412,message); } - input[propertyHeader.Key] = collection[propertyHeader.Key]; + input[propertyHeader.Key] = propertyValue; } headers.Remove(clientId); @@ -55,7 +54,7 @@ public IDictionary Reassemble(string clientId, IDictionary> headers + readonly IDictionary> headers = new Dictionary>(); } } \ No newline at end of file diff --git a/src/NServiceBus.Core/Gateway/HeaderManagement/GatewayHeaderManager.cs b/src/NServiceBus.Core/Gateway/HeaderManagement/GatewayHeaderManager.cs index 3c6b7a4079a..54d5a1cef99 100644 --- a/src/NServiceBus.Core/Gateway/HeaderManagement/GatewayHeaderManager.cs +++ b/src/NServiceBus.Core/Gateway/HeaderManagement/GatewayHeaderManager.cs @@ -9,23 +9,22 @@ public void MutateIncoming(TransportMessage transportMessage) { returnInfo = null; - if (!transportMessage.Headers.ContainsKey(Headers.HttpFrom) && - !transportMessage.Headers.ContainsKey(Headers.OriginatingSite)) + var headers = transportMessage.Headers; + if (!headers.ContainsKey(Headers.HttpFrom) && + !headers.ContainsKey(Headers.OriginatingSite)) { return; } + string originatingSite; + headers.TryGetValue(Headers.OriginatingSite, out originatingSite); + string httpFrom; + headers.TryGetValue(Headers.HttpFrom, out httpFrom); returnInfo = new HttpReturnInfo { //we preserve the httpFrom to be backwards compatible with NServiceBus 2.X - HttpFrom = - transportMessage.Headers.ContainsKey(Headers.HttpFrom) - ? transportMessage.Headers[Headers.HttpFrom] - : null, - OriginatingSite = - transportMessage.Headers.ContainsKey(Headers.OriginatingSite) - ? transportMessage.Headers[Headers.OriginatingSite] - : null, + HttpFrom = httpFrom, + OriginatingSite = originatingSite, ReplyToAddress = transportMessage.ReplyToAddress, LegacyMode = transportMessage.IsLegacyGatewayMessage() }; diff --git a/src/NServiceBus.Core/Gateway/HeaderManagement/HeaderMapper.cs b/src/NServiceBus.Core/Gateway/HeaderManagement/HeaderMapper.cs index ef1161d69c4..c80725aa4ab 100644 --- a/src/NServiceBus.Core/Gateway/HeaderManagement/HeaderMapper.cs +++ b/src/NServiceBus.Core/Gateway/HeaderManagement/HeaderMapper.cs @@ -47,11 +47,11 @@ static Dictionary ExtractHeaders(IDictionary fro { var result = new Dictionary(); - foreach (var header in from.Keys) + foreach (var pair in from) { - if (header.Contains(NServiceBus + Headers.HeaderName)) + if (pair.Key.Contains(NServiceBus + Headers.HeaderName)) { - result.Add(header.Replace(NServiceBus + Headers.HeaderName + ".", String.Empty), from[header]); + result.Add(pair.Key.Replace(NServiceBus + Headers.HeaderName + ".", String.Empty), pair.Value); } } @@ -72,9 +72,10 @@ public static void Map(TransportMessage from, IDictionary to) SetBackwardsCompatibilityHeaders(to); - if (from.Headers.ContainsKey(ReplyToAddress)) + string replyToAddress; + if (from.Headers.TryGetValue(ReplyToAddress, out replyToAddress)) { - to[Headers.RouteTo] = from.Headers[ReplyToAddress]; + to[Headers.RouteTo] = replyToAddress; } from.Headers.ToList() diff --git a/src/NServiceBus.Core/Gateway/Persistence/Sql/SqlPersistence.cs b/src/NServiceBus.Core/Gateway/Persistence/Sql/SqlPersistence.cs index 7e00603ca6b..95144997637 100644 --- a/src/NServiceBus.Core/Gateway/Persistence/Sql/SqlPersistence.cs +++ b/src/NServiceBus.Core/Gateway/Persistence/Sql/SqlPersistence.cs @@ -125,11 +125,10 @@ public void UpdateHeader(string clientId, string headerKey, string newValue) public int DeleteDeliveredMessages(DateTime until) { - int result; - using (var cn = new SqlConnection(ConnectionString)) { cn.Open(); + int result; using (var tx = cn.BeginTransaction()) { var command = cn.CreateCommand(); diff --git a/src/NServiceBus.Core/Gateway/Receiving/ChannelReceiverHeaderReader.cs b/src/NServiceBus.Core/Gateway/Receiving/ChannelReceiverHeaderReader.cs new file mode 100644 index 00000000000..b3191711b21 --- /dev/null +++ b/src/NServiceBus.Core/Gateway/Receiving/ChannelReceiverHeaderReader.cs @@ -0,0 +1,105 @@ +namespace NServiceBus.Gateway.Receiving +{ + using System; + using System.Collections.Generic; + using Channels; + using Channels.Http; + using HeaderManagement; + using Sending; + + static class ChannelReceiverHeaderReader + { + + internal static CallInfo GetCallInfo(DataReceivedOnChannelArgs receivedData) + { + return new CallInfo + { + ClientId = ReadClientId(receivedData.Headers), + TimeToBeReceived = ReadTimeToBeReceived(receivedData.Headers), + Type = ReadCallType(receivedData.Headers), + Headers = receivedData.Headers, + Data = receivedData.Data, + AutoAck = ReadAutoAck(receivedData.Headers), + Md5 = ReadMd5(receivedData.Headers) + }; + } + + static bool ReadAutoAck(IDictionary headers) + { + string autoAckString; + if (headers.TryGetValue(GatewayHeaders.AutoAck, out autoAckString)) + { + bool autoAck; + if (bool.TryParse(autoAckString, out autoAck)) + { + return autoAck; + } + var message = string.Format("Invalid AutoAck header '{0}'. Found '{1}'", GatewayHeaders.AutoAck, autoAckString); + throw new ChannelException(400, message); + } + return false; + } + static TimeSpan ReadTimeToBeReceived(IDictionary headers) + { + string timeToBeReceivedString; + if (headers.TryGetValue("NServiceBus.TimeToBeReceived", out timeToBeReceivedString)) + { + TimeSpan timeToBeReceived; + if (TimeSpan.TryParse(timeToBeReceivedString, out timeToBeReceived)) + { + return timeToBeReceived; + } + } + return TimeSpan.FromHours(1); + } + + internal static string ReadMd5(IDictionary headers) + { + string md5; + headers.TryGetValue(HttpHeaders.ContentMd5Key, out md5); + + if (string.IsNullOrWhiteSpace(md5)) + { + throw new ChannelException(400, "Required header '" + HttpHeaders.ContentMd5Key + "' missing."); + } + return md5; + } + internal static string ReadDataBus(this CallInfo callInfo) + { + string dataBus; + callInfo.Headers.TryGetValue(GatewayHeaders.DatabusKey, out dataBus); + + if (string.IsNullOrWhiteSpace(dataBus)) + { + throw new ChannelException(400, "Required header '" + GatewayHeaders.DatabusKey + "' missing."); + } + return dataBus; + } + + internal static string ReadClientId(IDictionary headers) + { + string clientIdString; + headers.TryGetValue(GatewayHeaders.ClientIdHeader, out clientIdString); + if (string.IsNullOrWhiteSpace(clientIdString)) + { + throw new ChannelException(400, "Required header '" + GatewayHeaders.ClientIdHeader + "' missing."); + } + return clientIdString; + } + + internal static CallType ReadCallType(IDictionary headers) + { + string callTypeString; + CallType callType; + if (!headers.TryGetValue(GatewayHeaders.CallTypeHeader, out callTypeString)) + { + throw new ChannelException(400, "Required header '" + GatewayHeaders.CallTypeHeader + "' missing."); + } + if (!Enum.TryParse(callTypeString, out callType)) + { + throw new ChannelException(400, "Required header '" + GatewayHeaders.CallTypeHeader + "' missing."); + } + return callType; + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core/Gateway/Receiving/IdempotentChannelReceiver.cs b/src/NServiceBus.Core/Gateway/Receiving/IdempotentChannelReceiver.cs index 192cb750c2a..afeac8d06f7 100644 --- a/src/NServiceBus.Core/Gateway/Receiving/IdempotentChannelReceiver.cs +++ b/src/NServiceBus.Core/Gateway/Receiving/IdempotentChannelReceiver.cs @@ -2,9 +2,7 @@ namespace NServiceBus.Gateway.Receiving { using System; using System.Collections.Generic; - using System.Transactions; using Channels; - using Channels.Http; using DataBus; using HeaderManagement; using Logging; @@ -51,11 +49,12 @@ void DataReceivedOnChannel(object sender, DataReceivedOnChannelArgs e) { using (e.Data) { - var callInfo = GetCallInfo(e); + var callInfo = ChannelReceiverHeaderReader.GetCallInfo(e); + Hasher.Verify(callInfo.Data,callInfo.Md5); Logger.DebugFormat("Received message of type {0} for client id: {1}", callInfo.Type, callInfo.ClientId); - using (var scope = DefaultTransactionScope()) + using (var scope = GatewayTransaction.Scope()) { DispatchReceivedCallInfo(callInfo); scope.Complete(); @@ -79,60 +78,6 @@ internal void DispatchReceivedCallInfo(CallInfo callInfo) } } - static TransactionScope DefaultTransactionScope() - { - return new TransactionScope(TransactionScopeOption.Required, - new TransactionOptions - { - IsolationLevel = IsolationLevel.ReadCommitted, - Timeout = TimeSpan.FromSeconds(30) - }); - } - - CallInfo GetCallInfo(DataReceivedOnChannelArgs receivedData) - { - var headers = receivedData.Headers; - - var callType = headers[GatewayHeaders.CallTypeHeader]; - if (!Enum.IsDefined(typeof(CallType), callType)) - { - throw new ChannelException(400, "Required header '" + GatewayHeaders.CallTypeHeader + "' missing."); - } - - var type = (CallType) Enum.Parse(typeof(CallType), callType); - - var clientId = headers[GatewayHeaders.ClientIdHeader]; - if (clientId == null) - { - throw new ChannelException(400, "Required header '" + GatewayHeaders.ClientIdHeader + "' missing."); - } - - var md5 = headers[HttpHeaders.ContentMd5Key]; - - if (md5 == null) - { - throw new ChannelException(400, "Required header '" + HttpHeaders.ContentMd5Key + "' missing."); - } - - var hash = Hasher.Hash(receivedData.Data); - - if (receivedData.Data.Length > 0 && hash != md5) - { - throw new ChannelException(412, - "MD5 hash received does not match hash calculated on server. Consider resubmitting."); - } - - - return new CallInfo - { - ClientId = clientId, - Type = type, - Headers = headers, - Data = receivedData.Data, - AutoAck = headers.ContainsKey(GatewayHeaders.AutoAck) - }; - } - void HandleSubmit(CallInfo callInfo) { persister.InsertMessage(callInfo.ClientId, DateTime.UtcNow, callInfo.Data, callInfo.Headers); @@ -150,25 +95,14 @@ void HandleDatabusProperty(CallInfo callInfo) throw new InvalidOperationException("Databus transmission received without a databus configured"); } - TimeSpan timeToBeReceived; + var newDatabusKey = DataBus.Put(callInfo.Data, callInfo.TimeToBeReceived); - if (!TimeSpan.TryParse(callInfo.Headers["NServiceBus.TimeToBeReceived"], out timeToBeReceived)) - { - timeToBeReceived = TimeSpan.FromHours(1); - } - - string newDatabusKey; - - using (callInfo.Data) - { - newDatabusKey = DataBus.Put(callInfo.Data, timeToBeReceived); - } - - var specificDataBusHeaderToUpdate = callInfo.Headers[GatewayHeaders.DatabusKey]; + var specificDataBusHeaderToUpdate = callInfo.ReadDataBus(); persister.UpdateHeader(callInfo.ClientId, specificDataBusHeaderToUpdate, newDatabusKey); } + void HandleAck(CallInfo callInfo) { byte[] outMessage; @@ -188,7 +122,7 @@ void HandleAck(CallInfo callInfo) MessageReceived(this, new MessageReceivedOnChannelArgs {Message = msg}); } - static readonly ILog Logger = LogManager.GetLogger(typeof(IdempotentChannelReceiver)); + static ILog Logger = LogManager.GetLogger(typeof(IdempotentChannelReceiver)); IChannelFactory channelFactory; IPersistMessages persister; diff --git a/src/NServiceBus.Core/Gateway/Receiving/SingleCallChannelReceiver.cs b/src/NServiceBus.Core/Gateway/Receiving/SingleCallChannelReceiver.cs index e3b9ac7a06d..caa5e963798 100644 --- a/src/NServiceBus.Core/Gateway/Receiving/SingleCallChannelReceiver.cs +++ b/src/NServiceBus.Core/Gateway/Receiving/SingleCallChannelReceiver.cs @@ -2,13 +2,11 @@ { using System; using System.IO; - using System.Transactions; using Channels; - using Channels.Http; using DataBus; using Deduplication; using HeaderManagement; - using log4net; + using Logging; using Notifications; using Sending; using Utils; @@ -42,13 +40,15 @@ public void Dispose() public void DisposeManaged() { + if (receiver != null) + { + receiver.MessageReceived -= MessageReceivedOnOldChannel; + receiver.Dispose(); + } + if (channelReceiver != null) { channelReceiver.DataReceived -= DataReceivedOnChannel; - if (receiver != null) - { - receiver.MessageReceived -= MessageReceivedOnOldChannel; - } channelReceiver.Dispose(); } } @@ -62,11 +62,11 @@ void DataReceivedOnChannel(object sender, DataReceivedOnChannelArgs e) { using (e.Data) { - var callInfo = GetCallInfo(e); + var callInfo = ChannelReceiverHeaderReader.GetCallInfo(e); Logger.DebugFormat("Received message of type {0} for client id: {1}", callInfo.Type, callInfo.ClientId); - using (var scope = DefaultTransactionScope()) + using (var scope = GatewayTransaction.Scope()) { switch (callInfo.Type) { @@ -85,44 +85,6 @@ void DataReceivedOnChannel(object sender, DataReceivedOnChannelArgs e) } } - static TransactionScope DefaultTransactionScope() - { - return new TransactionScope(TransactionScopeOption.RequiresNew, - new TransactionOptions - { - IsolationLevel = IsolationLevel.ReadCommitted, - Timeout = TimeSpan.FromSeconds(30) - }); - } - - CallInfo GetCallInfo(DataReceivedOnChannelArgs receivedData) - { - var headers = receivedData.Headers; - - var callType = headers[GatewayHeaders.CallTypeHeader]; - if (!Enum.IsDefined(typeof(CallType), callType)) - { - throw new ChannelException(400, "Required header '" + GatewayHeaders.CallTypeHeader + "' missing."); - } - - var type = (CallType) Enum.Parse(typeof(CallType), callType); - - var clientId = headers[GatewayHeaders.ClientIdHeader]; - if (clientId == null) - { - throw new ChannelException(400, "Required header '" + GatewayHeaders.ClientIdHeader + "' missing."); - } - - return new CallInfo - { - ClientId = clientId, - Type = type, - Headers = headers, - Data = receivedData.Data, - AutoAck = headers.ContainsKey(GatewayHeaders.AutoAck) - }; - } - void HandleSubmit(CallInfo callInfo) { using (var stream = new MemoryStream()) @@ -130,7 +92,7 @@ void HandleSubmit(CallInfo callInfo) callInfo.Data.CopyTo(stream); stream.Position = 0; - CheckHashOfGatewayStream(stream, callInfo.Headers[HttpHeaders.ContentMd5Key]); + Hasher.Verify(stream, callInfo.Md5); var msg = HeaderMapper.Map(headerManager.Reassemble(callInfo.ClientId, callInfo.Headers)); msg.Body = new byte[stream.Length]; @@ -142,8 +104,7 @@ void HandleSubmit(CallInfo callInfo) } else { - Logger.InfoFormat("Message with id: {0} is already on the bus, dropping the request", - callInfo.ClientId); + Logger.InfoFormat("Message with id: {0} is already on the bus, dropping the request", callInfo.ClientId); } } } @@ -155,45 +116,26 @@ void HandleDatabusProperty(CallInfo callInfo) throw new InvalidOperationException("Databus transmission received without a configured databus"); } - TimeSpan timeToBeReceived; - if (!TimeSpan.TryParse(callInfo.Headers["NServiceBus.TimeToBeReceived"], out timeToBeReceived)) - { - timeToBeReceived = TimeSpan.FromHours(1); - } - - var newDatabusKey = DataBus.Put(callInfo.Data, timeToBeReceived); + + var newDatabusKey = DataBus.Put(callInfo.Data, callInfo.TimeToBeReceived); using (var databusStream = DataBus.Get(newDatabusKey)) { - CheckHashOfGatewayStream(databusStream, callInfo.Headers[HttpHeaders.ContentMd5Key]); + Hasher.Verify(databusStream, callInfo.Md5); } - var specificDataBusHeaderToUpdate = callInfo.Headers[GatewayHeaders.DatabusKey]; + var specificDataBusHeaderToUpdate = callInfo.ReadDataBus(); headerManager.InsertHeader(callInfo.ClientId, specificDataBusHeaderToUpdate, newDatabusKey); } - void CheckHashOfGatewayStream(Stream input, string md5Hash) - { - if (md5Hash == null) - { - throw new ChannelException(400, "Required header '" + HttpHeaders.ContentMd5Key + "' missing."); - } - - if (md5Hash != Hasher.Hash(input)) - { - throw new ChannelException(412, - "MD5 hash received does not match hash calculated on server. Please resubmit."); - } - } - - static readonly ILog Logger = LogManager.GetLogger("NServiceBus.Gateway"); + static ILog Logger = LogManager.GetLogger("NServiceBus.Gateway"); - readonly IChannelFactory channelFactory; - readonly IDeduplicateMessages deduplicator; - readonly DataBusHeaderManager headerManager; + IChannelFactory channelFactory; + IDeduplicateMessages deduplicator; + DataBusHeaderManager headerManager; - [ObsoleteEx(RemoveInVersion = "6.0", TreatAsErrorFromVersion = "5.0")] readonly IdempotentChannelReceiver - receiver; + [ObsoleteEx(RemoveInVersion = "6.0", TreatAsErrorFromVersion = "5.0")] + IdempotentChannelReceiver receiver; IChannelReceiver channelReceiver; } diff --git a/src/NServiceBus.Core/Gateway/Routing/Sites/ConfigurationBasedSiteRouter.cs b/src/NServiceBus.Core/Gateway/Routing/Sites/ConfigurationBasedSiteRouter.cs index 3d6e0b81117..f530d485719 100644 --- a/src/NServiceBus.Core/Gateway/Routing/Sites/ConfigurationBasedSiteRouter.cs +++ b/src/NServiceBus.Core/Gateway/Routing/Sites/ConfigurationBasedSiteRouter.cs @@ -16,15 +16,17 @@ public ConfigurationBasedSiteRouter() public IEnumerable GetDestinationSitesFor(TransportMessage messageToDispatch) { - if (messageToDispatch.Headers.ContainsKey(Headers.DestinationSites)) + string destinationSites; + if (messageToDispatch.Headers.TryGetValue(Headers.DestinationSites, out destinationSites)) { - var siteKeys = messageToDispatch.Headers[Headers.DestinationSites].Split(','); + var siteKeys = destinationSites.Split(','); foreach (var siteKey in siteKeys) { - if (sites.ContainsKey(siteKey)) + Site site; + if (sites.TryGetValue(siteKey, out site)) { - yield return sites[siteKey]; + yield return site; } } } diff --git a/src/NServiceBus.Core/Gateway/Routing/Sites/KeyPrefixConventionSiteRouter.cs b/src/NServiceBus.Core/Gateway/Routing/Sites/KeyPrefixConventionSiteRouter.cs index 0aa36100c8c..a9c6fce072e 100644 --- a/src/NServiceBus.Core/Gateway/Routing/Sites/KeyPrefixConventionSiteRouter.cs +++ b/src/NServiceBus.Core/Gateway/Routing/Sites/KeyPrefixConventionSiteRouter.cs @@ -7,10 +7,10 @@ public class KeyPrefixConventionSiteRouter : IRouteMessagesToSites { public IEnumerable GetDestinationSitesFor(TransportMessage messageToDispatch) { - if (messageToDispatch.Headers.ContainsKey(Headers.DestinationSites)) + string sites; + if (messageToDispatch.Headers.TryGetValue(Headers.DestinationSites, out sites)) { - var siteKeys = messageToDispatch.Headers[Headers.DestinationSites].Split(','); - + var siteKeys = sites.Split(','); foreach (var siteKey in siteKeys) { @@ -20,7 +20,11 @@ public IEnumerable GetDestinationSitesFor(TransportMessage messageToDispat { yield return new Site { - Channel = new Channel {Address = siteKey, Type = parts[0]}, + Channel = new Channel + { + Address = siteKey, + Type = parts[0] + }, Key = siteKey }; } diff --git a/src/NServiceBus.Core/Gateway/Routing/Sites/OriginatingSiteHeaderRouter.cs b/src/NServiceBus.Core/Gateway/Routing/Sites/OriginatingSiteHeaderRouter.cs index e9db935abba..a42e240087a 100644 --- a/src/NServiceBus.Core/Gateway/Routing/Sites/OriginatingSiteHeaderRouter.cs +++ b/src/NServiceBus.Core/Gateway/Routing/Sites/OriginatingSiteHeaderRouter.cs @@ -7,11 +7,12 @@ public class OriginatingSiteHeaderRouter : IRouteMessagesToSites { public IEnumerable GetDestinationSitesFor(TransportMessage messageToDispatch) { - if (messageToDispatch.Headers.ContainsKey(Headers.OriginatingSite)) + string originatingSite; + if (messageToDispatch.Headers.TryGetValue(Headers.OriginatingSite, out originatingSite)) { yield return new Site { - Channel = Channel.Parse(messageToDispatch.Headers[Headers.OriginatingSite]), + Channel = Channel.Parse(originatingSite), Key = "Default reply channel", LegacyMode = messageToDispatch.IsLegacyGatewayMessage() }; diff --git a/src/NServiceBus.Core/Gateway/Sending/CallInfo.cs b/src/NServiceBus.Core/Gateway/Sending/CallInfo.cs index 62194a61ad4..6593a300197 100644 --- a/src/NServiceBus.Core/Gateway/Sending/CallInfo.cs +++ b/src/NServiceBus.Core/Gateway/Sending/CallInfo.cs @@ -1,5 +1,6 @@ namespace NServiceBus.Gateway.Sending { + using System; using System.Collections.Generic; using System.IO; @@ -12,15 +13,8 @@ public class CallInfo [ObsoleteEx(RemoveInVersion = "6.0", TreatAsErrorFromVersion = "5.0")] public bool AutoAck { get; set; } - } - - public enum CallType - { - [ObsoleteEx(RemoveInVersion = "6.0", TreatAsErrorFromVersion = "5.0")] Submit, - [ObsoleteEx(RemoveInVersion = "6.0", TreatAsErrorFromVersion = "5.0")] Ack, - [ObsoleteEx(RemoveInVersion = "6.0", TreatAsErrorFromVersion = "5.0")] DatabusProperty, - SingleCallSubmit, - SingleCallDatabusProperty + public TimeSpan TimeToBeReceived { get; set; } + public string Md5 { get; set; } } } \ No newline at end of file diff --git a/src/NServiceBus.Core/Gateway/Sending/CallType.cs b/src/NServiceBus.Core/Gateway/Sending/CallType.cs new file mode 100644 index 00000000000..ff8274c50ad --- /dev/null +++ b/src/NServiceBus.Core/Gateway/Sending/CallType.cs @@ -0,0 +1,12 @@ +namespace NServiceBus.Gateway.Sending +{ + public enum CallType + { + [ObsoleteEx(RemoveInVersion = "6.0", TreatAsErrorFromVersion = "5.0")] Submit, + [ObsoleteEx(RemoveInVersion = "6.0", TreatAsErrorFromVersion = "5.0")] Ack, + [ObsoleteEx(RemoveInVersion = "6.0", TreatAsErrorFromVersion = "5.0")] DatabusProperty, + + SingleCallSubmit, + SingleCallDatabusProperty + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core/Gateway/Sending/GatewaySender.cs b/src/NServiceBus.Core/Gateway/Sending/GatewaySender.cs index b87707d1612..ec0239eb062 100644 --- a/src/NServiceBus.Core/Gateway/Sending/GatewaySender.cs +++ b/src/NServiceBus.Core/Gateway/Sending/GatewaySender.cs @@ -3,7 +3,6 @@ namespace NServiceBus.Gateway.Sending using System; using System.Collections.Generic; using System.Linq; - using Config; using Features; using HeaderManagement; using Notifications; @@ -71,11 +70,8 @@ public Action GetReceiverCustomization() { return transport => { - var configSection = Configure.ConfigurationSource.GetConfiguration(); - if (configSection != null && configSection.TransactionTimeout > transport.TransactionSettings.TransactionTimeout) - { - transport.TransactionSettings.TransactionTimeout = configSection.TransactionTimeout; - } + transport.TransactionSettings.TransactionTimeout = + GatewayTransaction.Timeout(transport.TransactionSettings.TransactionTimeout); }; } diff --git a/src/NServiceBus.Core/Gateway/Sending/IdempotentChannelForwarder.cs b/src/NServiceBus.Core/Gateway/Sending/IdempotentChannelForwarder.cs index 2ac550d45fc..5a58d202558 100644 --- a/src/NServiceBus.Core/Gateway/Sending/IdempotentChannelForwarder.cs +++ b/src/NServiceBus.Core/Gateway/Sending/IdempotentChannelForwarder.cs @@ -30,7 +30,9 @@ public void Forward(TransportMessage message, Site targetSite) var channelSender = channelFactory.GetSender(targetSite.Channel.Type); - using (var messagePayload = new MemoryStream(message.Body)) + var bodyToSend = message.Body ?? new byte[0]; + + using (var messagePayload = new MemoryStream(bodyToSend)) { Transmit(channelSender, targetSite, CallType.Submit, headers, messagePayload); } @@ -55,13 +57,11 @@ void Transmit(IChannelSender channelSender, Site targetSite, CallType callType, channelSender.Send(targetSite.Channel.Address, headers, data); } - void TransmitDataBusProperties(IChannelSender channelSender, Site targetSite, - IDictionary headers) + void TransmitDataBusProperties(IChannelSender channelSender, Site targetSite, IDictionary headers) { var headersToSend = new Dictionary(headers); - foreach ( - var headerKey in headers.Keys.Where(headerKey => headerKey.Contains(HeaderMapper.DATABUS_PREFIX))) + foreach (var headerKey in headers.Keys.Where(headerKey => headerKey.Contains(HeaderMapper.DATABUS_PREFIX))) { if (DataBus == null) { diff --git a/src/NServiceBus.Core/Gateway/Sending/SingleCallChannelForwarder.cs b/src/NServiceBus.Core/Gateway/Sending/SingleCallChannelForwarder.cs index 99572f1bd86..63660c63aa4 100644 --- a/src/NServiceBus.Core/Gateway/Sending/SingleCallChannelForwarder.cs +++ b/src/NServiceBus.Core/Gateway/Sending/SingleCallChannelForwarder.cs @@ -8,7 +8,7 @@ using Channels.Http; using DataBus; using HeaderManagement; - using log4net; + using Logging; using Routing; using Utils; diff --git a/src/NServiceBus.Core/Gateway/Utils/Hasher.cs b/src/NServiceBus.Core/Gateway/Utils/Hasher.cs index d95c511f46c..48247055e62 100644 --- a/src/NServiceBus.Core/Gateway/Utils/Hasher.cs +++ b/src/NServiceBus.Core/Gateway/Utils/Hasher.cs @@ -3,6 +3,7 @@ namespace NServiceBus.Gateway.Utils using System; using System.IO; using System.Security.Cryptography; + using Receiving; public class Hasher { @@ -15,5 +16,14 @@ public static string Hash(Stream stream) return Convert.ToBase64String(hash); } + + internal static void Verify(Stream input, string md5Hash) + { + + if (md5Hash != Hash(input)) + { + throw new ChannelException(412, "MD5 hash received does not match hash calculated on server. Please resubmit."); + } + } } } \ No newline at end of file diff --git a/src/NServiceBus.Core/GitFlowVersion.cs b/src/NServiceBus.Core/GitFlowVersion.cs new file mode 100644 index 00000000000..bcb3c026e07 --- /dev/null +++ b/src/NServiceBus.Core/GitFlowVersion.cs @@ -0,0 +1,20 @@ +namespace NServiceBus +{ + using System; + + static class GitFlowVersion + { + static GitFlowVersion() + { + var assembly = typeof(GitFlowVersion).Assembly; + var gitFlowVersionInformationType = assembly.GetType("NServiceBus.Core.GitFlowVersionInformation", true); + var fieldInfo = gitFlowVersionInformationType.GetField("AssemblyFileVersion"); + var assemblyFileVersion = Version.Parse((string)fieldInfo.GetValue(null)); + MajorMinor = assemblyFileVersion.ToString(2); + MajorMinorPatch = assemblyFileVersion.ToString(3); + } + + public static string MajorMinor; + public static string MajorMinorPatch; + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core/Hosting/HostInformation.cs b/src/NServiceBus.Core/Hosting/HostInformation.cs new file mode 100644 index 00000000000..4726971ec6f --- /dev/null +++ b/src/NServiceBus.Core/Hosting/HostInformation.cs @@ -0,0 +1,43 @@ +namespace NServiceBus.Hosting +{ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Diagnostics; + using Utils; + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class HostInformation + { + public static HostInformation CreateDefault() + { + var commandLine = Environment.CommandLine; + + var fullPathToStartingExe = commandLine.Split('"')[1]; + + var hostId = DeterministicGuid.Create(fullPathToStartingExe, Environment.MachineName); + + return new HostInformation(hostId, Environment.MachineName, String.Format("{0}", fullPathToStartingExe)); + } + + public HostInformation(Guid hostId, string displayName, string displayInstanceIdentifier) + { + HostId = hostId; + DisplayName = displayName; + DisplayInstanceIdentifier = displayInstanceIdentifier; + + Properties = new Dictionary + { + {"Machine", Environment.MachineName}, + {"ProcessID", Process.GetCurrentProcess().Id.ToString()}, + {"UserName", Environment.UserName}, + }; + } + + public Guid HostId { get; private set; } + public string DisplayName { get; private set; } + public string DisplayInstanceIdentifier { get; private set; } + public Dictionary Properties { get; private set; } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core/Impersonation/Windows/WindowsImpersonator.cs b/src/NServiceBus.Core/Impersonation/Windows/WindowsImpersonator.cs index 0389f37484d..83fbcc5a528 100644 --- a/src/NServiceBus.Core/Impersonation/Windows/WindowsImpersonator.cs +++ b/src/NServiceBus.Core/Impersonation/Windows/WindowsImpersonator.cs @@ -15,19 +15,18 @@ public class WindowsImpersonator : ExtractIncomingPrincipal { public IPrincipal GetPrincipal(TransportMessage message) { - if (!message.Headers.ContainsKey(Headers.WindowsIdentityName)) + string windowsIdentityName; + if (!message.Headers.TryGetValue(Headers.WindowsIdentityName, out windowsIdentityName)) { return null; } - var name = message.Headers[Headers.WindowsIdentityName]; - - if (name == null) + if (windowsIdentityName == null) { return null; } - return new GenericPrincipal(new GenericIdentity(name), new string[0]); + return new GenericPrincipal(new GenericIdentity(windowsIdentityName), new string[0]); } } } \ No newline at end of file diff --git a/src/NServiceBus.Core/Install.cs b/src/NServiceBus.Core/Install.cs index 893db303926..db99bba0d78 100644 --- a/src/NServiceBus.Core/Install.cs +++ b/src/NServiceBus.Core/Install.cs @@ -80,7 +80,8 @@ public Installer(IIdentity identity) /// public static bool RunOtherInstallers { private get; set; } - private static bool installedOthersInstallers; + // ReSharper disable once StaticFieldInGenericType + static bool installedOthersInstallers; /// /// Invokes installers for the given environment @@ -89,17 +90,21 @@ public void Install() { Configure.Instance.Initialize(); - if(RunOtherInstallers) + if (RunOtherInstallers) + { InstallOtherInstallers(); + } } /// /// Invokes only 'Something' - other than infrastructure, installers for the given environment. /// - private void InstallOtherInstallers() + void InstallOtherInstallers() { if (installedOthersInstallers) + { return; + } Configure.Instance.Builder.BuildAll().ToList() .ForEach(i=>i.Install(identity.Name)); diff --git a/src/NServiceBus.Core/Licensing/LicenseDeserializer.cs b/src/NServiceBus.Core/Licensing/LicenseDeserializer.cs index a95288ed05c..747020d7417 100644 --- a/src/NServiceBus.Core/Licensing/LicenseDeserializer.cs +++ b/src/NServiceBus.Core/Licensing/LicenseDeserializer.cs @@ -67,8 +67,8 @@ public static License Deserialize(string licenseText) return license; } - const int MaxWorkerNodes = int.MaxValue; - const int MaxThroughputPerSecond = 0; + internal const int MaxWorkerNodes = int.MaxValue; + internal const int MaxThroughputPerSecond = 0; const int MinNumberOfWorkerNodes = 2; const int MinMessagePerSecondThroughput = 1; } diff --git a/src/NServiceBus.Core/Licensing/LicenseExpiredForm.cs b/src/NServiceBus.Core/Licensing/LicenseExpiredForm.cs index 5ba945b9a5c..6fa567d147e 100644 --- a/src/NServiceBus.Core/Licensing/LicenseExpiredForm.cs +++ b/src/NServiceBus.Core/Licensing/LicenseExpiredForm.cs @@ -41,18 +41,18 @@ void browseButton_Click(object sender, EventArgs e) string downgradeReason; if (LicenseDowngrader.ShouldLicenseDowngrade(license, out downgradeReason)) { - var message = string.Format("The license you provided has expired.\r\nReason:{0}\r\nClick 'Purchase' to obtain a new license. Or try a different file.\r\nThis massage has been appended to your log.", downgradeReason); + var message = string.Format("The license you provided has expired.\r\nReason:{0}\r\nClick 'Purchase' to obtain a new license. Or try a different file.\r\nThis message has been appended to your log.", downgradeReason); Logger.Warn(message); MessageBox.Show(this, message, "License expired", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } - MessageBox.Show(this, "The new license has bee been verified. It will now be stored in the Registry for future use.", "License applied", MessageBoxButtons.OK, MessageBoxIcon.Information); + MessageBox.Show(this, "The new license has been verified. It will now be stored in the Registry for future use.", "License applied", MessageBoxButtons.OK, MessageBoxIcon.Information); ResultingLicenseText = licenseText; Close(); } catch (Exception exception) { - var message = string.Format("An error occurred parsing the license.\r\nMessage: {0}\r\nThe exception details have appended to your log.", exception.Message); + var message = string.Format("An error occurred when parsing the license.\r\nMessage: {0}\r\nThe exception details have been appended to your log.", exception.Message); Logger.Warn("Error parsing license", exception); MessageBox.Show(this, message, "Error parsing license", MessageBoxButtons.OK, MessageBoxIcon.Error); } diff --git a/src/NServiceBus.Core/Licensing/LicenseManager.cs b/src/NServiceBus.Core/Licensing/LicenseManager.cs index 31f478cd5c5..fbea09a54c1 100644 --- a/src/NServiceBus.Core/Licensing/LicenseManager.cs +++ b/src/NServiceBus.Core/Licensing/LicenseManager.cs @@ -21,7 +21,7 @@ internal static void PromptUserForLicenseIfTrialHasExpired() } bool createdNew; - using (new Mutex(true, string.Format("NServiceBus-{0}", NServiceBusVersion.MajorAndMinor), out createdNew)) + using (new Mutex(true, string.Format("NServiceBus-{0}", GitFlowVersion.MajorMinor), out createdNew)) { if (!createdNew) { @@ -42,10 +42,26 @@ static void WriteLicenseInfo() Logger.InfoFormat("Expires on {0}", License.ExpirationDate); if (License.UpgradeProtectionExpiration != null) { - Logger.InfoFormat("UpgradeProtectionExpiration {0}", License.UpgradeProtectionExpiration); + Logger.InfoFormat("UpgradeProtectionExpiration: {0}", License.UpgradeProtectionExpiration); + } + + if (License.MaxThroughputPerSecond == LicenseDeserializer.MaxThroughputPerSecond) + { + Logger.Info("MaxThroughputPerSecond: unlimited"); + } + else + { + Logger.InfoFormat("MaxThroughputPerSecond: {0}", License.MaxThroughputPerSecond); + } + + if (License.AllowedNumberOfWorkerNodes == LicenseDeserializer.MaxWorkerNodes) + { + Logger.Info("AllowedNumberOfWorkerNodes: unlimited"); + } + else + { + Logger.InfoFormat("AllowedNumberOfWorkerNodes: {0}", License.AllowedNumberOfWorkerNodes); } - Logger.InfoFormat("MaxThroughputPerSecond {0}", License.MaxThroughputPerSecond); - Logger.InfoFormat("AllowedNumberOfWorkerNodes {0}", License.AllowedNumberOfWorkerNodes); } static void ConfigureNServiceBusToRunInTrialMode() @@ -56,13 +72,13 @@ static void ConfigureNServiceBusToRunInTrialMode() //Check trial is still valid if (ExpiryChecker.IsExpired(trialExpirationDate)) { - Logger.WarnFormat("Trial for NServiceBus v{0} has expired. Falling back to run in Basic1 license mode.", NServiceBusVersion.MajorAndMinor); + Logger.WarnFormat("Trial for NServiceBus v{0} has expired. Falling back to run in Basic1 license mode.", GitFlowVersion.MajorMinor); license = LicenseDeserializer.GetBasicLicense(); } else { - var message = string.Format("Trial for NServiceBus v{0} is still active, trial expires on {1}. Configuring NServiceBus to run in trial mode.", NServiceBusVersion.MajorAndMinor, trialExpirationDate.ToLocalTime().ToShortDateString()); + var message = string.Format("Trial for NServiceBus v{0} is still active, trial expires on {1}. Configuring NServiceBus to run in trial mode.", GitFlowVersion.MajorMinor, trialExpirationDate.ToLocalTime().ToShortDateString()); Logger.Info(message); //Run in unlimited mode during trial period diff --git a/src/NServiceBus.Core/Licensing/NServiceBusVersion.cs b/src/NServiceBus.Core/Licensing/NServiceBusVersion.cs deleted file mode 100644 index 5071b0bfacf..00000000000 --- a/src/NServiceBus.Core/Licensing/NServiceBusVersion.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace NServiceBus.Licensing -{ - using System; - using System.Reflection; - - static class NServiceBusVersion - { - static NServiceBusVersion() - { - - var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version; - - MajorAndMinor = new Version(assemblyVersion.Major, assemblyVersion.Minor).ToString(2); - } - - public static string MajorAndMinor; - } -} \ No newline at end of file diff --git a/src/NServiceBus.Core/Licensing/TrialLicenseReader.cs b/src/NServiceBus.Core/Licensing/TrialLicenseReader.cs index e9c9ea7c576..14c6097ea1e 100644 --- a/src/NServiceBus.Core/Licensing/TrialLicenseReader.cs +++ b/src/NServiceBus.Core/Licensing/TrialLicenseReader.cs @@ -15,7 +15,7 @@ public static DateTime GetTrialExpirationFromRegistry() //If first time run, configure expire date try { - var subKeyPath = String.Format(@"SOFTWARE\NServiceBus\{0}", NServiceBusVersion.MajorAndMinor); + var subKeyPath = String.Format(@"SOFTWARE\NServiceBus\{0}", GitFlowVersion.MajorMinor); using (var registryKey = Registry.CurrentUser.CreateSubKey(subKeyPath)) { //CreateSubKey does not return null http://stackoverflow.com/questions/19849870/under-what-circumstances-will-registrykey-createsubkeystring-return-null @@ -27,7 +27,7 @@ public static DateTime GetTrialExpirationFromRegistry() trialStartDateString = trialStart.ToString("yyyy-MM-dd"); registryKey.SetValue("TrialStart", trialStartDateString, RegistryValueKind.String); - Logger.DebugFormat("First time running NServiceBus v{0}, setting trial license start.", NServiceBusVersion.MajorAndMinor); + Logger.DebugFormat("First time running NServiceBus v{0}, setting trial license start.", GitFlowVersion.MajorMinor); return trialStart.AddDays(TRIAL_DAYS); } else diff --git a/src/NServiceBus.Core/MessageHeaders/HeaderBootstrapper.cs b/src/NServiceBus.Core/MessageHeaders/HeaderBootstrapper.cs index d61df13e2fb..450f3780b1c 100644 --- a/src/NServiceBus.Core/MessageHeaders/HeaderBootstrapper.cs +++ b/src/NServiceBus.Core/MessageHeaders/HeaderBootstrapper.cs @@ -15,18 +15,18 @@ public void SetupHeaderActions() { ExtensionMethods.GetHeaderAction = (message, key) => { - var pipelineFactory = Builder.Build(); + var pipelineFactory = Builder.Build(); if (message == ExtensionMethods.CurrentMessageBeingHandled) { - LogicalMessage messageBeeingReceived; + LogicalMessage messageBeingReceived; //first try to get the header from the current logical message - if (pipelineFactory.CurrentContext.TryGet(out messageBeeingReceived)) + if (pipelineFactory.CurrentContext.TryGet(out messageBeingReceived)) { string value; - messageBeeingReceived.Headers.TryGetValue(key, out value); + messageBeingReceived.Headers.TryGetValue(key, out value); return value; } @@ -35,14 +35,15 @@ public void SetupHeaderActions() // when we remove the multi message feature we can remove this and instead // share the same header collection btw physical and logical message var bus = Builder.Build(); - if (bus.CurrentMessageContext != null && bus.CurrentMessageContext.Headers.ContainsKey(key)) + if (bus.CurrentMessageContext != null) { - return bus.CurrentMessageContext.Headers[key]; - } - else - { - return null; + string value; + if (bus.CurrentMessageContext.Headers.TryGetValue(key, out value)) + { + return value; + } } + return null; } Dictionary> outgoingHeaders; @@ -67,7 +68,7 @@ public void SetupHeaderActions() ExtensionMethods.SetHeaderAction = (message, key, value) => { - var pipelineFactory = Builder.Build(); + var pipelineFactory = Builder.Build(); //are we in the process of sending a logical message var outgoingLogicalMessageContext = pipelineFactory.CurrentContext as SendLogicalMessageContext; diff --git a/src/NServiceBus.Core/MessageInterfaces/MessageMapper/Reflection/MessageMapper.cs b/src/NServiceBus.Core/MessageInterfaces/MessageMapper/Reflection/MessageMapper.cs index 6277acd4e39..625be3960c6 100644 --- a/src/NServiceBus.Core/MessageInterfaces/MessageMapper/Reflection/MessageMapper.cs +++ b/src/NServiceBus.Core/MessageInterfaces/MessageMapper/Reflection/MessageMapper.cs @@ -363,9 +363,10 @@ public Type GetMappedTypeFor(string typeName) name = typeName.Substring(0, typeName.Length - SUFFIX.Length); } - if (nameToType.ContainsKey(name)) + Type type; + if (nameToType.TryGetValue(name, out type)) { - return nameToType[name]; + return type; } return Type.GetType(name); @@ -409,7 +410,7 @@ public object CreateInstance(Type t) } } - ConstructorInfo constructor = null; + ConstructorInfo constructor; typeToConstructor.TryGetValue(mapped, out constructor); if (constructor != null) { diff --git a/src/NServiceBus.Core/MessageMutator/ApplyIncomingMessageMutatorsBehavior.cs b/src/NServiceBus.Core/MessageMutator/ApplyIncomingMessageMutatorsBehavior.cs index 3fcd3c2453b..9d485f49bd8 100644 --- a/src/NServiceBus.Core/MessageMutator/ApplyIncomingMessageMutatorsBehavior.cs +++ b/src/NServiceBus.Core/MessageMutator/ApplyIncomingMessageMutatorsBehavior.cs @@ -1,10 +1,14 @@ namespace NServiceBus.Pipeline.MessageMutator { using System; + using System.ComponentModel; using Contexts; using NServiceBus.MessageMutator; - class ApplyIncomingMessageMutatorsBehavior : IBehavior + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class ApplyIncomingMessageMutatorsBehavior : IBehavior { public void Invoke(ReceiveLogicalMessageContext context, Action next) { diff --git a/src/NServiceBus.Core/MessageMutator/ApplyIncomingTransportMessageMutatorsBehavior.cs b/src/NServiceBus.Core/MessageMutator/ApplyIncomingTransportMessageMutatorsBehavior.cs index d9e81d6a0b8..d52533b0125 100644 --- a/src/NServiceBus.Core/MessageMutator/ApplyIncomingTransportMessageMutatorsBehavior.cs +++ b/src/NServiceBus.Core/MessageMutator/ApplyIncomingTransportMessageMutatorsBehavior.cs @@ -1,10 +1,14 @@ namespace NServiceBus.MessageMutator { using System; + using System.ComponentModel; using Pipeline; using Pipeline.Contexts; - class ApplyIncomingTransportMessageMutatorsBehavior : IBehavior + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class ApplyIncomingTransportMessageMutatorsBehavior : IBehavior { public void Invoke(ReceivePhysicalMessageContext context, Action next) { diff --git a/src/NServiceBus.Core/MessageMutator/MutateOutgoingMessageBehavior.cs b/src/NServiceBus.Core/MessageMutator/MutateOutgoingMessageBehavior.cs index 706f181e6f1..d4c0aecc59b 100644 --- a/src/NServiceBus.Core/MessageMutator/MutateOutgoingMessageBehavior.cs +++ b/src/NServiceBus.Core/MessageMutator/MutateOutgoingMessageBehavior.cs @@ -1,10 +1,14 @@ namespace NServiceBus.MessageMutator { using System; + using System.ComponentModel; using Pipeline; using Pipeline.Contexts; - class MutateOutgoingMessageBehavior : IBehavior + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class MutateOutgoingMessageBehavior : IBehavior { public void Invoke(SendLogicalMessageContext context, Action next) { diff --git a/src/NServiceBus.Core/MessageMutator/MutateOutgoingPhysicalMessageBehavior.cs b/src/NServiceBus.Core/MessageMutator/MutateOutgoingPhysicalMessageBehavior.cs index e043e27ac49..dbbb3bed321 100644 --- a/src/NServiceBus.Core/MessageMutator/MutateOutgoingPhysicalMessageBehavior.cs +++ b/src/NServiceBus.Core/MessageMutator/MutateOutgoingPhysicalMessageBehavior.cs @@ -1,11 +1,15 @@ namespace NServiceBus.MessageMutator { using System; + using System.ComponentModel; using System.Linq; using Pipeline; using Pipeline.Contexts; - class MutateOutgoingPhysicalMessageBehavior : IBehavior + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class MutateOutgoingPhysicalMessageBehavior : IBehavior { public void Invoke(SendPhysicalMessageContext context, Action next) { diff --git a/src/NServiceBus.Core/NServiceBus.Core.csproj b/src/NServiceBus.Core/NServiceBus.Core.csproj index f0df10729c2..8285ea61427 100644 --- a/src/NServiceBus.Core/NServiceBus.Core.csproj +++ b/src/NServiceBus.Core/NServiceBus.Core.csproj @@ -14,6 +14,7 @@ true ..\NServiceBus.snk ..\packages\Fody + ..\ true @@ -99,6 +100,7 @@ + @@ -115,10 +117,16 @@ + + + + + + @@ -127,7 +135,6 @@ - @@ -148,6 +155,13 @@ + + + + + + + @@ -171,7 +185,7 @@ - + @@ -584,6 +598,7 @@ + @@ -624,7 +639,7 @@ {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus diff --git a/src/NServiceBus.Core/Persistence/InMemory/Gateway/InMemoryDeduplication.cs b/src/NServiceBus.Core/Persistence/InMemory/Gateway/InMemoryDeduplication.cs index 3aa3728e7f8..7e79c26c844 100644 --- a/src/NServiceBus.Core/Persistence/InMemory/Gateway/InMemoryDeduplication.cs +++ b/src/NServiceBus.Core/Persistence/InMemory/Gateway/InMemoryDeduplication.cs @@ -35,7 +35,7 @@ public int GetHashCode(GatewayMessage obj) public int DeleteDeliveredMessages(DateTime until) { - var count = 0; + int count; lock (persistence) { var items = persistence.Where(msg => msg.TimeReceived <= until).ToList(); diff --git a/src/NServiceBus.Core/Persistence/InMemory/SagaPersister/InMemorySagaPersister.cs b/src/NServiceBus.Core/Persistence/InMemory/SagaPersister/InMemorySagaPersister.cs index e7f1f7e3931..fd1be48f53c 100644 --- a/src/NServiceBus.Core/Persistence/InMemory/SagaPersister/InMemorySagaPersister.cs +++ b/src/NServiceBus.Core/Persistence/InMemory/SagaPersister/InMemorySagaPersister.cs @@ -60,9 +60,10 @@ public void Save(IContainSagaData saga) { ValidateUniqueProperties(saga); - if (data.ContainsKey(saga.Id)) + VersionedSagaEntity sagaEntity; + if (data.TryGetValue(saga.Id, out sagaEntity)) { - data[saga.Id].ConcurrencyCheck(); + sagaEntity.ConcurrencyCheck(); } data[saga.Id] = new VersionedSagaEntity { SagaEntity = DeepClone(saga) }; diff --git a/src/NServiceBus.Core/Persistence/InMemory/SubscriptionStorage/InMemorySubscriptionStorage.cs b/src/NServiceBus.Core/Persistence/InMemory/SubscriptionStorage/InMemorySubscriptionStorage.cs index d9b4ff4131b..d609275395c 100644 --- a/src/NServiceBus.Core/Persistence/InMemory/SubscriptionStorage/InMemorySubscriptionStorage.cs +++ b/src/NServiceBus.Core/Persistence/InMemory/SubscriptionStorage/InMemorySubscriptionStorage.cs @@ -15,11 +15,16 @@ void ISubscriptionStorage.Subscribe(Address address, IEnumerable me { messageTypes.ToList().ForEach(m => { - if (!storage.ContainsKey(m)) - storage[m] = new List
(); + List
list; + if (!storage.TryGetValue(m, out list)) + { + storage[m] = list = new List
(); + } - if (!storage[m].Contains(address)) - storage[m].Add(address); + if (!list.Contains(address)) + { + list.Add(address); + } }); } @@ -27,8 +32,11 @@ void ISubscriptionStorage.Unsubscribe(Address address, IEnumerable { messageTypes.ToList().ForEach(m => { - if (storage.ContainsKey(m)) - storage[m].Remove(address); + List
list; + if (storage.TryGetValue(m, out list)) + { + list.Remove(address); + } }); } @@ -38,8 +46,11 @@ IEnumerable
ISubscriptionStorage.GetSubscriberAddressesForMessage(IEnum var result = new List
(); messageTypes.ToList().ForEach(m => { - if (storage.ContainsKey(m)) - result.AddRange(storage[m]); + List
list; + if (storage.TryGetValue(m, out list)) + { + result.AddRange(list); + } }); return result.Distinct(); diff --git a/src/NServiceBus.Core/Persistence/Msmq/SubscriptionStorage/MsmqSubscriptionStorage.cs b/src/NServiceBus.Core/Persistence/Msmq/SubscriptionStorage/MsmqSubscriptionStorage.cs index a88f8517e54..a8a1aa4c95a 100644 --- a/src/NServiceBus.Core/Persistence/Msmq/SubscriptionStorage/MsmqSubscriptionStorage.cs +++ b/src/NServiceBus.Core/Persistence/Msmq/SubscriptionStorage/MsmqSubscriptionStorage.cs @@ -194,14 +194,19 @@ public Address Queue ///
private void AddToLookup(Address subscriber, MessageType typeName, string messageId) { - lock (lookup) - { - if (!lookup.ContainsKey(subscriber)) - lookup.Add(subscriber, new Dictionary()); - - if (!lookup[subscriber].ContainsKey(typeName)) - lookup[subscriber].Add(typeName, messageId); - } + lock (lookup) + { + Dictionary dictionary; + if (!lookup.TryGetValue(subscriber, out dictionary)) + { + lookup[subscriber] = dictionary = new Dictionary(); + } + + if (!dictionary.ContainsKey(typeName)) + { + dictionary.Add(typeName, messageId); + } + } } string RemoveFromLookup(Address subscriber, MessageType typeName) diff --git a/src/NServiceBus.Core/Persistence/Raven/RavenPersistenceConstants.cs b/src/NServiceBus.Core/Persistence/Raven/RavenPersistenceConstants.cs index 9ac73dd2163..16cf67b9be0 100644 --- a/src/NServiceBus.Core/Persistence/Raven/RavenPersistenceConstants.cs +++ b/src/NServiceBus.Core/Persistence/Raven/RavenPersistenceConstants.cs @@ -1,8 +1,6 @@ namespace NServiceBus.Persistence.Raven { using System; - using System.Security.Cryptography; - using System.Text; using Utils; public static class RavenPersistenceConstants @@ -33,21 +31,7 @@ public static Guid DefaultResourceManagerId { get { - var resourceManagerId = Address.Local + "-" + Configure.DefineEndpointVersionRetriever() ; - - return DeterministicGuidBuilder(resourceManagerId); - } - } - - static Guid DeterministicGuidBuilder(string input) - { - // use MD5 hash to get a 16-byte hash of the string - using (var provider = new MD5CryptoServiceProvider()) - { - var inputBytes = Encoding.Default.GetBytes(input); - var hashBytes = provider.ComputeHash(inputBytes); - // generate a guid from the hash: - return new Guid(hashBytes); + return DeterministicGuid.Create(Address.Local, "-", Configure.DefineEndpointVersionRetriever()); } } } diff --git a/src/NServiceBus.Core/Persistence/Raven/RavenUserInstaller.cs b/src/NServiceBus.Core/Persistence/Raven/RavenUserInstaller.cs index 19853da37e2..af4bb61f504 100644 --- a/src/NServiceBus.Core/Persistence/Raven/RavenUserInstaller.cs +++ b/src/NServiceBus.Core/Persistence/Raven/RavenUserInstaller.cs @@ -157,6 +157,7 @@ class WindowsAuthDocument public List RequiredUsers = new List(); } + // ReSharper disable NotAccessedField.Local class WindowsAuthData { public string Name; @@ -170,6 +171,7 @@ class DatabaseAccess public bool ReadOnly; public string TenantId; } + // ReSharper restore NotAccessedField.Local } } \ No newline at end of file diff --git a/src/NServiceBus.Core/Persistence/Raven/SagaPersister/RavenSagaPersister.cs b/src/NServiceBus.Core/Persistence/Raven/SagaPersister/RavenSagaPersister.cs index e6f66b1ea4e..ff86235529c 100644 --- a/src/NServiceBus.Core/Persistence/Raven/SagaPersister/RavenSagaPersister.cs +++ b/src/NServiceBus.Core/Persistence/Raven/SagaPersister/RavenSagaPersister.cs @@ -4,8 +4,6 @@ namespace NServiceBus.Persistence.Raven.SagaPersister using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; - using System.Security.Cryptography; - using System.Text; using global::Raven.Abstractions.Commands; using global::Raven.Client; using Saga; @@ -174,32 +172,24 @@ public class SagaUniqueIdentity public static string FormatId(Type sagaType, KeyValuePair uniqueProperty) { if (uniqueProperty.Value == null) - throw new ArgumentNullException("uniqueProperty", string.Format("Property {0} is marked with the [Unique] attribute on {1} but contains a null value. Please make sure that all unique properties are set on your SagaData and/or that you have marked the correct properties as unique.", uniqueProperty.Key, sagaType.Name)); - - // use MD5 hash to get a 16-byte hash of the string - using (var provider = new MD5CryptoServiceProvider()) { - var inputBytes = Encoding.Default.GetBytes(uniqueProperty.Value.ToString()); - var hashBytes = provider.ComputeHash(inputBytes); - - // generate a guid from the hash: - var value = new Guid(hashBytes); - - var id = string.Format("{0}/{1}/{2}", sagaType.FullName.Replace('+', '-'), uniqueProperty.Key, value); + throw new ArgumentNullException("uniqueProperty", string.Format("Property {0} is marked with the [Unique] attribute on {1} but contains a null value. Please make sure that all unique properties are set on your SagaData and/or that you have marked the correct properties as unique.", uniqueProperty.Key, sagaType.Name)); + } - // raven has a size limit of 255 bytes == 127 unicode chars - if (id.Length > 127) - { - // generate a guid from the hash: - var key = - new Guid( - provider.ComputeHash(Encoding.Default.GetBytes(sagaType.FullName + uniqueProperty.Key))); + var value = Utils.DeterministicGuid.Create(uniqueProperty.Value.ToString()); - id = string.Format("MoreThan127/{0}/{1}", key, value); - } + var id = string.Format("{0}/{1}/{2}", sagaType.FullName.Replace('+', '-'), uniqueProperty.Key, value); - return id; + // raven has a size limit of 255 bytes == 127 unicode chars + if (id.Length > 127) + { + // generate a guid from the hash: + var key = Utils.DeterministicGuid.Create(sagaType.FullName, uniqueProperty.Key); + + id = string.Format("MoreThan127/{0}/{1}", key, value); } + + return id; } } } \ No newline at end of file diff --git a/src/NServiceBus.Core/Persistence/Raven/SubscriptionStorage/Subscription.cs b/src/NServiceBus.Core/Persistence/Raven/SubscriptionStorage/Subscription.cs index c116b9a5a52..221bfdb84cc 100644 --- a/src/NServiceBus.Core/Persistence/Raven/SubscriptionStorage/Subscription.cs +++ b/src/NServiceBus.Core/Persistence/Raven/SubscriptionStorage/Subscription.cs @@ -2,10 +2,9 @@ namespace NServiceBus.Persistence.Raven.SubscriptionStorage { using System; using System.Collections.Generic; - using System.Security.Cryptography; - using System.Text; using global::Raven.Imports.Newtonsoft.Json; using Unicast.Subscriptions; + using Utils; public class Subscription { @@ -18,16 +17,9 @@ public class Subscription public static string FormatId(MessageType messageType) { - // use MD5 hash to get a 16-byte hash of the string - using (var provider = new MD5CryptoServiceProvider()) - { - var inputBytes = Encoding.Default.GetBytes(messageType.TypeName + "/" + messageType.Version.Major); - var hashBytes = provider.ComputeHash(inputBytes); - // generate a guid from the hash: - var id = new Guid(hashBytes); - - return string.Format("Subscriptions/{0}", id); - } + var id = DeterministicGuid.Create(messageType.TypeName, "/", messageType.Version.Major); + + return string.Format("Subscriptions/{0}", id); } } diff --git a/src/NServiceBus.Core/Pipeline/BehaviorChain.cs b/src/NServiceBus.Core/Pipeline/BehaviorChain.cs index 1527ac76fcb..57055ae7924 100644 --- a/src/NServiceBus.Core/Pipeline/BehaviorChain.cs +++ b/src/NServiceBus.Core/Pipeline/BehaviorChain.cs @@ -2,13 +2,22 @@ { using System; using System.Collections.Generic; + using Logging; class BehaviorChain where T : BehaviorContext { - public void Add() where TBehavior : IBehavior + // ReSharper disable once StaticFieldInGenericType + // The number of T's is small and they willa all log to the same point due to the typeof(BehaviorChain<>) + static ILog Log = LogManager.GetLogger(typeof(BehaviorChain<>)); + Queue itemDescriptors = new Queue(); + + public BehaviorChain(IEnumerable behaviorList) { - itemDescriptors.Enqueue(typeof(TBehavior)); - } + foreach (var behaviorType in behaviorList) + { + itemDescriptors.Enqueue(behaviorType); + } + } public void Invoke(T context) { @@ -23,12 +32,12 @@ void InvokeNext(T context) } var behaviorType = itemDescriptors.Dequeue(); + Log.Debug(behaviorType.Name); var instance = (IBehavior)context.Builder.Build(behaviorType); instance.Invoke(context, () => InvokeNext(context)); } - Queue itemDescriptors = new Queue(); } } \ No newline at end of file diff --git a/src/NServiceBus.Core/Pipeline/BehaviorContext.cs b/src/NServiceBus.Core/Pipeline/BehaviorContext.cs index f896eee19c6..a57af35640b 100644 --- a/src/NServiceBus.Core/Pipeline/BehaviorContext.cs +++ b/src/NServiceBus.Core/Pipeline/BehaviorContext.cs @@ -1,9 +1,14 @@ namespace NServiceBus.Pipeline { + using System; using System.Collections.Generic; + using System.ComponentModel; using ObjectBuilder; - abstract class BehaviorContext + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public abstract class BehaviorContext { protected BehaviorContext(BehaviorContext parentContext) { @@ -37,9 +42,10 @@ public bool TryGet(out T result) public bool TryGet(string key,out T result) { - if (stash.ContainsKey(key)) + object value; + if (stash.TryGetValue(key, out value)) { - result = (T)stash[key]; + result = (T)value; return true; } diff --git a/src/NServiceBus.Core/Pipeline/BehaviorList.cs b/src/NServiceBus.Core/Pipeline/BehaviorList.cs new file mode 100644 index 00000000000..1ed2f3409c8 --- /dev/null +++ b/src/NServiceBus.Core/Pipeline/BehaviorList.cs @@ -0,0 +1,74 @@ +namespace NServiceBus.Pipeline +{ + using System; + using System.Collections.Generic; + using System.ComponentModel; + + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class BehaviorList where TContext : BehaviorContext + { + public List InnerList { get; set; } + + public BehaviorList() + { + InnerList = new List(); + } + + public void Add() where T : IBehavior + { + InnerList.Add(typeof(T)); + } + + public bool Remove() where T : IBehavior + { + return InnerList.Remove(typeof(T)); + } + + public void Replace() + where TExisting : IBehavior + where TToReplace : IBehavior + { + var indexOf = InnerList.IndexOf(typeof(TExisting)); + if (indexOf > -1) + { + InnerList[indexOf] = typeof(TToReplace); + return; + } + throw new Exception(string.Format("Could not replace since '{0}' does not exist.", typeof(TExisting).Name)); + } + + public void InsertAfter() + where TExisting : IBehavior + where TToAdd : IBehavior + { + for (var index = 0; index < InnerList.Count; index++) + { + var type = InnerList[index]; + if (type == typeof(TExisting)) + { + InnerList.Insert(index + 1, typeof(TToAdd)); + return; + } + } + throw new Exception(string.Format("Could not InsertAfter since '{0}' does not exist.", typeof(TExisting).Name)); + } + + public void InsertBefore() + where TExisting : IBehavior + where TToAdd : IBehavior + { + for (var index = 0; index < InnerList.Count; index++) + { + var type = InnerList[index]; + if (type == typeof(TExisting)) + { + InnerList.Insert(index, typeof(TToAdd)); + return; + } + } + throw new Exception(string.Format("Could not InsertBefore since '{0}' does not exist.", typeof(TExisting).Name)); + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core/Pipeline/Contexts/HandlerInvocationContext.cs b/src/NServiceBus.Core/Pipeline/Contexts/HandlerInvocationContext.cs index b0e4673234f..1b9ed74f758 100644 --- a/src/NServiceBus.Core/Pipeline/Contexts/HandlerInvocationContext.cs +++ b/src/NServiceBus.Core/Pipeline/Contexts/HandlerInvocationContext.cs @@ -1,9 +1,14 @@ namespace NServiceBus.Pipeline.Contexts { + using System; + using System.ComponentModel; using Unicast.Behaviors; using Unicast.Messages; - class HandlerInvocationContext : BehaviorContext + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class HandlerInvocationContext : BehaviorContext { public HandlerInvocationContext(BehaviorContext parentContext, MessageHandler messageHandler) : base(parentContext) @@ -20,10 +25,5 @@ public LogicalMessage LogicalMessage { get { return Get(); } } - - public TransportMessage PhysicalMessage - { - get { return Get(ReceivePhysicalMessageContext.IncomingPhysicalMessageKey); } - } } } \ No newline at end of file diff --git a/src/NServiceBus.Core/Pipeline/Contexts/ReceiveLogicalMessageContext.cs b/src/NServiceBus.Core/Pipeline/Contexts/ReceiveLogicalMessageContext.cs index 9c58b56495b..0295b4034f1 100644 --- a/src/NServiceBus.Core/Pipeline/Contexts/ReceiveLogicalMessageContext.cs +++ b/src/NServiceBus.Core/Pipeline/Contexts/ReceiveLogicalMessageContext.cs @@ -1,8 +1,13 @@ namespace NServiceBus.Pipeline.Contexts { + using System; + using System.ComponentModel; using Unicast.Messages; - class ReceiveLogicalMessageContext : BehaviorContext + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class ReceiveLogicalMessageContext : BehaviorContext { public ReceiveLogicalMessageContext(BehaviorContext parentContext, LogicalMessage message) : base(parentContext) diff --git a/src/NServiceBus.Core/Pipeline/Contexts/ReceivePhysicalMessageContext.cs b/src/NServiceBus.Core/Pipeline/Contexts/ReceivePhysicalMessageContext.cs index 3f25890b76f..c47db6f4985 100644 --- a/src/NServiceBus.Core/Pipeline/Contexts/ReceivePhysicalMessageContext.cs +++ b/src/NServiceBus.Core/Pipeline/Contexts/ReceivePhysicalMessageContext.cs @@ -1,9 +1,14 @@ namespace NServiceBus.Pipeline.Contexts { + using System; using System.Collections.Generic; + using System.ComponentModel; using Unicast.Messages; - class ReceivePhysicalMessageContext : BehaviorContext + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class ReceivePhysicalMessageContext : BehaviorContext { public ReceivePhysicalMessageContext(BehaviorContext parentContext, TransportMessage transportMessage, bool messageHandlingDisabled) : base(parentContext) diff --git a/src/NServiceBus.Core/Pipeline/Contexts/RootContext.cs b/src/NServiceBus.Core/Pipeline/Contexts/RootContext.cs index 270418879c9..d8267b9ca67 100644 --- a/src/NServiceBus.Core/Pipeline/Contexts/RootContext.cs +++ b/src/NServiceBus.Core/Pipeline/Contexts/RootContext.cs @@ -1,8 +1,13 @@ namespace NServiceBus.Pipeline.Contexts { + using System; + using System.ComponentModel; using ObjectBuilder; - class RootContext : BehaviorContext + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class RootContext : BehaviorContext { public RootContext(IBuilder builder) : base(null) { diff --git a/src/NServiceBus.Core/Pipeline/Contexts/SendLogicalMessageContext.cs b/src/NServiceBus.Core/Pipeline/Contexts/SendLogicalMessageContext.cs index d5b7caeb9ba..aa392f72312 100644 --- a/src/NServiceBus.Core/Pipeline/Contexts/SendLogicalMessageContext.cs +++ b/src/NServiceBus.Core/Pipeline/Contexts/SendLogicalMessageContext.cs @@ -1,9 +1,14 @@ namespace NServiceBus.Pipeline.Contexts { + using System; + using System.ComponentModel; using Unicast; using Unicast.Messages; - class SendLogicalMessageContext : BehaviorContext + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class SendLogicalMessageContext : BehaviorContext { public SendLogicalMessageContext(BehaviorContext parentContext, SendOptions sendOptions, LogicalMessage message) : base(parentContext) diff --git a/src/NServiceBus.Core/Pipeline/Contexts/SendLogicalMessagesContext.cs b/src/NServiceBus.Core/Pipeline/Contexts/SendLogicalMessagesContext.cs index da8e73bfdae..1b708198b32 100644 --- a/src/NServiceBus.Core/Pipeline/Contexts/SendLogicalMessagesContext.cs +++ b/src/NServiceBus.Core/Pipeline/Contexts/SendLogicalMessagesContext.cs @@ -1,10 +1,15 @@ namespace NServiceBus.Pipeline.Contexts { + using System; using System.Collections.Generic; + using System.ComponentModel; using Unicast; using Unicast.Messages; - class SendLogicalMessagesContext : BehaviorContext + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class SendLogicalMessagesContext : BehaviorContext { public SendLogicalMessagesContext(BehaviorContext parentContext, SendOptions sendOptions,IEnumerable messages) : base(parentContext) diff --git a/src/NServiceBus.Core/Pipeline/Contexts/SendPhysicalMessageContext.cs b/src/NServiceBus.Core/Pipeline/Contexts/SendPhysicalMessageContext.cs index 75b95eaf2ea..789d3609f6d 100644 --- a/src/NServiceBus.Core/Pipeline/Contexts/SendPhysicalMessageContext.cs +++ b/src/NServiceBus.Core/Pipeline/Contexts/SendPhysicalMessageContext.cs @@ -1,10 +1,15 @@ namespace NServiceBus.Pipeline.Contexts { + using System; using System.Collections.Generic; + using System.ComponentModel; using Unicast; using Unicast.Messages; - class SendPhysicalMessageContext : BehaviorContext + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class SendPhysicalMessageContext : BehaviorContext { public SendPhysicalMessageContext(BehaviorContext parentContext, SendOptions sendOptions, TransportMessage message) : base(parentContext) diff --git a/src/NServiceBus.Core/Pipeline/IBehavior.cs b/src/NServiceBus.Core/Pipeline/IBehavior.cs index 5a823e2f30a..1a5245aff56 100644 --- a/src/NServiceBus.Core/Pipeline/IBehavior.cs +++ b/src/NServiceBus.Core/Pipeline/IBehavior.cs @@ -1,8 +1,11 @@ namespace NServiceBus.Pipeline { using System; + using System.ComponentModel; - interface IBehavior where T : BehaviorContext + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public interface IBehavior where T : BehaviorContext { void Invoke(T context, Action next); } diff --git a/src/NServiceBus.Core/Pipeline/IPipelineOverride.cs b/src/NServiceBus.Core/Pipeline/IPipelineOverride.cs new file mode 100644 index 00000000000..b62feb8309f --- /dev/null +++ b/src/NServiceBus.Core/Pipeline/IPipelineOverride.cs @@ -0,0 +1,18 @@ +namespace NServiceBus.Pipeline +{ + using System; + using System.ComponentModel; + using Contexts; + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public interface IPipelineOverride + { + void Override(BehaviorList behaviorList); + void Override(BehaviorList behaviorList); + void Override(BehaviorList behaviorList); + void Override(BehaviorList behaviorList); + void Override(BehaviorList behaviorList); + void Override(BehaviorList behaviorList); + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core/Pipeline/PipelineBuilder.cs b/src/NServiceBus.Core/Pipeline/PipelineBuilder.cs new file mode 100644 index 00000000000..3e4bf6bec80 --- /dev/null +++ b/src/NServiceBus.Core/Pipeline/PipelineBuilder.cs @@ -0,0 +1,146 @@ +namespace NServiceBus.Pipeline +{ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Linq; + using Audit; + using Contexts; + using DataBus; + using MessageMutator; + using NServiceBus.MessageMutator; + using ObjectBuilder; + using Sagas; + using Unicast.Behaviors; + using Unicast.Messages; + using UnitOfWork; + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class PipelineBuilder + { + List pipelineOverrides; + public List sendPhysicalMessageBehaviorList { get; private set; } + public List receivePhysicalMessageBehaviorList { get; private set; } + public List receiveLogicalMessageBehaviorList { get; private set; } + public List handlerInvocationBehaviorList { get; private set; } + public List sendLogicalMessagesBehaviorList { get; private set; } + public List sendLogicalMessageBehaviorList { get; private set; } + + public PipelineBuilder(IBuilder builder) + { + pipelineOverrides = builder.BuildAll().ToList(); + CreateSendPhysicalMessageList(); + CreateReceivePhysicalMessageList(); + CreateReceiveLogicalMessageList(); + CreateHandlerInvocationList(); + CreateSendLogicalMessagesList(); + CreateSendLogicalMessageList(); + } + + void CreateSendPhysicalMessageList() + { + var behaviorList = new BehaviorList(); + + behaviorList.Add(); + behaviorList.Add(); + behaviorList.Add(); + + foreach (var pipelineOverride in pipelineOverrides) + { + pipelineOverride.Override(behaviorList); + } + + sendPhysicalMessageBehaviorList = behaviorList.InnerList; + } + + void CreateReceivePhysicalMessageList() + { + var behaviorList = new BehaviorList(); + + behaviorList.Add(); + behaviorList.Add(); + behaviorList.Add(); + behaviorList.Add(); + behaviorList.Add(); + behaviorList.Add(); + behaviorList.Add(); + behaviorList.Add(); + behaviorList.Add(); + behaviorList.Add(); + behaviorList.Add(); + behaviorList.Add(); + + foreach (var pipelineOverride in pipelineOverrides) + { + pipelineOverride.Override(behaviorList); + } + receivePhysicalMessageBehaviorList = behaviorList.InnerList; + } + + void CreateReceiveLogicalMessageList() + { + var behaviorList = new BehaviorList(); + behaviorList.Add(); + //todo: we'll make this optional as soon as we have a way to manipulate the pipeline + behaviorList.Add(); + behaviorList.Add(); + + foreach (var pipelineOverride in pipelineOverrides) + { + pipelineOverride.Override(behaviorList); + } + receiveLogicalMessageBehaviorList = behaviorList.InnerList; + } + + void CreateHandlerInvocationList() + { + var behaviorList = new BehaviorList(); + + behaviorList.Add(); + behaviorList.Add(); + behaviorList.Add(); + behaviorList.Add(); + + foreach (var pipelineOverride in pipelineOverrides) + { + pipelineOverride.Override(behaviorList); + } + handlerInvocationBehaviorList = behaviorList.InnerList; + } + + void CreateSendLogicalMessagesList() + { + var behaviorList = new BehaviorList(); + + behaviorList.Add(); + behaviorList.Add(); + behaviorList.Add(); + + foreach (var pipelineOverride in pipelineOverrides) + { + pipelineOverride.Override(behaviorList); + } + sendLogicalMessagesBehaviorList = behaviorList.InnerList; + } + + void CreateSendLogicalMessageList() + { + var behaviorList = new BehaviorList(); + + behaviorList.Add(); + behaviorList.Add(); + behaviorList.Add(); + //todo: we'll make this optional as soon as we have a way to manipulate the pipeline + behaviorList.Add(); + + foreach (var pipelineOverride in pipelineOverrides) + { + pipelineOverride.Override(behaviorList); + } + sendLogicalMessageBehaviorList = behaviorList.InnerList; + } + + + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core/Pipeline/PipelineFactory.cs b/src/NServiceBus.Core/Pipeline/PipelineExecutor.cs similarity index 63% rename from src/NServiceBus.Core/Pipeline/PipelineFactory.cs rename to src/NServiceBus.Core/Pipeline/PipelineExecutor.cs index 2804f0bd951..74906e0ca71 100644 --- a/src/NServiceBus.Core/Pipeline/PipelineFactory.cs +++ b/src/NServiceBus.Core/Pipeline/PipelineExecutor.cs @@ -2,21 +2,26 @@ { using System; using System.Collections.Generic; - using Audit; + using System.ComponentModel; using Contexts; - using DataBus; - using MessageMutator; - using NServiceBus.MessageMutator; using ObjectBuilder; - using Sagas; using Unicast; using Unicast.Behaviors; using Unicast.Messages; - using UnitOfWork; - class PipelineFactory : IDisposable + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class PipelineExecutor : IDisposable { - public IBuilder RootBuilder { get; set; } + IBuilder rootBuilder; + PipelineBuilder pipelineBuilder; + BehaviorContextStacker contextStacker = new BehaviorContextStacker(); + + public PipelineExecutor(IBuilder builder, PipelineBuilder pipelineBuilder) + { + rootBuilder = builder; + this.pipelineBuilder = pipelineBuilder; + } public void PreparePhysicalMessagePipelineContext(TransportMessage message, bool messageHandlingDisabled) { @@ -32,19 +37,9 @@ public void InvokeReceivePhysicalMessagePipeline() throw new InvalidOperationException("Can't invoke the receive pipeline when the current context is: " + contextStacker.Current.GetType().Name); } - var pipeline = new BehaviorChain(); - pipeline.Add(); - pipeline.Add(); - pipeline.Add(); - pipeline.Add(); - pipeline.Add(); - pipeline.Add(); - pipeline.Add(); - pipeline.Add(); - pipeline.Add(); - pipeline.Add(); - pipeline.Add(); + var pipeline = new BehaviorChain(pipelineBuilder.receivePhysicalMessageBehaviorList); + pipeline.Invoke(context); } @@ -56,12 +51,8 @@ public void CompletePhysicalMessagePipelineContext() public void InvokeLogicalMessagePipeline(LogicalMessage message) { - var pipeline = new BehaviorChain(); + var pipeline = new BehaviorChain(pipelineBuilder.receiveLogicalMessageBehaviorList); - pipeline.Add(); - //todo: we'll make this optional as soon as we have a way to manipulate the pipeline - pipeline.Add(); - pipeline.Add(); var context = new ReceiveLogicalMessageContext(CurrentContext, message); @@ -71,11 +62,7 @@ public void InvokeLogicalMessagePipeline(LogicalMessage message) public HandlerInvocationContext InvokeHandlerPipeline(MessageHandler handler) { - var pipeline = new BehaviorChain(); - - pipeline.Add(); - pipeline.Add(); - pipeline.Add(); + var pipeline = new BehaviorChain(pipelineBuilder.handlerInvocationBehaviorList); var context = new HandlerInvocationContext(CurrentContext, handler); @@ -86,12 +73,7 @@ public HandlerInvocationContext InvokeHandlerPipeline(MessageHandler handler) public SendLogicalMessagesContext InvokeSendPipeline(SendOptions sendOptions, IEnumerable messages) { - var pipeline = new BehaviorChain(); - - pipeline.Add(); - pipeline.Add(); - pipeline.Add(); - + var pipeline = new BehaviorChain(pipelineBuilder.sendLogicalMessagesBehaviorList); var context = new SendLogicalMessagesContext(CurrentContext, sendOptions, messages); Execute(pipeline, context); @@ -101,14 +83,7 @@ public SendLogicalMessagesContext InvokeSendPipeline(SendOptions sendOptions, IE public SendLogicalMessageContext InvokeSendPipeline(SendOptions sendOptions, LogicalMessage message) { - var pipeline = new BehaviorChain(); - - pipeline.Add(); - pipeline.Add(); - pipeline.Add(); - - //todo: we'll make this optional as soon as we have a way to manipulate the pipeline - pipeline.Add(); + var pipeline = new BehaviorChain(pipelineBuilder.sendLogicalMessageBehaviorList); var context = new SendLogicalMessageContext(CurrentContext, sendOptions, message); @@ -119,11 +94,7 @@ public SendLogicalMessageContext InvokeSendPipeline(SendOptions sendOptions, Log public void InvokeSendPipeline(SendOptions sendOptions, TransportMessage physicalMessage) { - var pipeline = new BehaviorChain(); - - pipeline.Add(); - pipeline.Add(); - pipeline.Add(); + var pipeline = new BehaviorChain(pipelineBuilder.sendPhysicalMessageBehaviorList); var context = new SendPhysicalMessageContext(CurrentContext, sendOptions, physicalMessage); @@ -141,7 +112,7 @@ public BehaviorContext CurrentContext return current; } - contextStacker.Push(new RootContext(RootBuilder)); + contextStacker.Push(new RootContext(rootBuilder)); return contextStacker.Current; } @@ -172,6 +143,5 @@ void Execute(BehaviorChain pipelineAction, T context) where T : BehaviorCo } } - BehaviorContextStacker contextStacker = new BehaviorContextStacker(); } } \ No newline at end of file diff --git a/src/NServiceBus.Core/Pipeline/PipelineOverride.cs b/src/NServiceBus.Core/Pipeline/PipelineOverride.cs new file mode 100644 index 00000000000..874f2ffa765 --- /dev/null +++ b/src/NServiceBus.Core/Pipeline/PipelineOverride.cs @@ -0,0 +1,31 @@ +namespace NServiceBus.Pipeline +{ + using System; + using System.ComponentModel; + using Contexts; + + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public abstract class PipelineOverride : IPipelineOverride + { + public virtual void Override(BehaviorList behaviorList) + { + } + public virtual void Override(BehaviorList behaviorList) + { + } + public virtual void Override(BehaviorList behaviorList) + { + } + public virtual void Override(BehaviorList behaviorList) + { + } + public virtual void Override(BehaviorList behaviorList) + { + } + public virtual void Override(BehaviorList behaviorList) + { + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core/Pipeline/PipelineOverrideConfigurer.cs b/src/NServiceBus.Core/Pipeline/PipelineOverrideConfigurer.cs new file mode 100644 index 00000000000..6cadcd8c2a4 --- /dev/null +++ b/src/NServiceBus.Core/Pipeline/PipelineOverrideConfigurer.cs @@ -0,0 +1,10 @@ +namespace NServiceBus.Pipeline +{ + class PipelineOverrideConfigurer : INeedInitialization + { + public void Init() + { + Configure.Instance.ForAllTypes(s => Configure.Instance.Configurer.ConfigureComponent(s, DependencyLifecycle.InstancePerCall)); + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core/Properties/AssemblyInfo.cs b/src/NServiceBus.Core/Properties/AssemblyInfo.cs index 8cd9d2dca5e..608d7a90cbc 100644 --- a/src/NServiceBus.Core/Properties/AssemblyInfo.cs +++ b/src/NServiceBus.Core/Properties/AssemblyInfo.cs @@ -4,9 +4,8 @@ [assembly: AssemblyTitle("NServiceBus.Core")] [assembly: AssemblyDescription("")] -[assembly: AssemblyCopyright("Copyright 2010-2013 NServiceBus. All rights reserved")] +[assembly: AssemblyCopyright("Copyright 2010-2014 NServiceBus. All rights reserved")] [assembly: AssemblyProduct("NServiceBus.Core")] [assembly: AssemblyCompany("NServiceBus Ltd.")] -[assembly: AssemblyConfiguration("release")] [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] \ No newline at end of file diff --git a/src/NServiceBus.Core/Sagas/ActiveSagaInstance.cs b/src/NServiceBus.Core/Sagas/ActiveSagaInstance.cs index a25672e9a64..f34252240e5 100644 --- a/src/NServiceBus.Core/Sagas/ActiveSagaInstance.cs +++ b/src/NServiceBus.Core/Sagas/ActiveSagaInstance.cs @@ -1,9 +1,13 @@ namespace NServiceBus.Sagas { using System; + using System.ComponentModel; using Saga; - class ActiveSagaInstance + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class ActiveSagaInstance { public ActiveSagaInstance(ISaga saga) { diff --git a/src/NServiceBus.Core/Sagas/AuditInvokedSagaBehavior.cs b/src/NServiceBus.Core/Sagas/AuditInvokedSagaBehavior.cs new file mode 100644 index 00000000000..12e9f350518 --- /dev/null +++ b/src/NServiceBus.Core/Sagas/AuditInvokedSagaBehavior.cs @@ -0,0 +1,37 @@ +namespace NServiceBus.Sagas +{ + using System; + using System.ComponentModel; + using Pipeline; + using Pipeline.Contexts; + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class AuditInvokedSagaBehavior : IBehavior + { + public void Invoke(HandlerInvocationContext context, Action next) + { + next(); + + ActiveSagaInstance saga; + + if (!context.TryGet(out saga) || saga.NotFound) + { + return; + } + + var audit = string.Format("{0}:{1}",saga.SagaType.FullName,saga.Instance.Entity.Id); + + string header; + + if (context.LogicalMessage.Headers.TryGetValue(Headers.InvokedSagas, out header)) + { + context.LogicalMessage.Headers[Headers.InvokedSagas] += ";" + audit; + } + else + { + context.LogicalMessage.Headers[Headers.InvokedSagas] = audit; + } + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core/Sagas/ConfigureTimeoutAsSystemMessages.cs b/src/NServiceBus.Core/Sagas/ConfigureTimeoutAsSystemMessages.cs index 77c9e33d27c..79658e43a05 100644 --- a/src/NServiceBus.Core/Sagas/ConfigureTimeoutAsSystemMessages.cs +++ b/src/NServiceBus.Core/Sagas/ConfigureTimeoutAsSystemMessages.cs @@ -17,7 +17,7 @@ public void Init() { var sagas = Configure.TypesToScan.Where(Features.Sagas.IsSagaType).ToList(); - Configure.Instance.AddSystemMessagesAs(t => IsTypeATimeoutHandledByAnySaga(t, sagas)); + MessageConventionExtensions.AddSystemMessagesConventions(t => IsTypeATimeoutHandledByAnySaga(t, sagas)); } static bool IsTypeATimeoutHandledByAnySaga(Type type, IEnumerable sagas) diff --git a/src/NServiceBus.Core/Sagas/RemoveIncomingHeadersBehavior.cs b/src/NServiceBus.Core/Sagas/RemoveIncomingHeadersBehavior.cs new file mode 100644 index 00000000000..caa2e250ccd --- /dev/null +++ b/src/NServiceBus.Core/Sagas/RemoveIncomingHeadersBehavior.cs @@ -0,0 +1,26 @@ +namespace NServiceBus.Sagas +{ + using System; + using System.ComponentModel; + using Pipeline; + using Pipeline.Contexts; + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class RemoveIncomingHeadersBehavior : IBehavior + { + [ObsoleteEx(RemoveInVersion = "5.0")] + public void Invoke(ReceivePhysicalMessageContext context, Action next) + { + + // We need this for backwards compatibility because in v4.0.0 we still have this headers being sent as part of the message even if MessageIntent == MessageIntentEnum.Publish + if (context.PhysicalMessage.MessageIntent == MessageIntentEnum.Publish) + { + context.PhysicalMessage.Headers.Remove(Headers.SagaId); + context.PhysicalMessage.Headers.Remove(Headers.SagaType); + } + + next(); + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core/Sagas/SagaPersistenceBehavior.cs b/src/NServiceBus.Core/Sagas/SagaPersistenceBehavior.cs index 7bcf6a83d35..fcafc33d0cd 100644 --- a/src/NServiceBus.Core/Sagas/SagaPersistenceBehavior.cs +++ b/src/NServiceBus.Core/Sagas/SagaPersistenceBehavior.cs @@ -2,6 +2,7 @@ { using System; using System.Collections.Generic; + using System.ComponentModel; using System.Linq; using IdGeneration; using Logging; @@ -13,7 +14,10 @@ using Unicast; using Unicast.Messages; - class SagaPersistenceBehavior : IBehavior + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class SagaPersistenceBehavior : IBehavior { public ISagaPersister SagaPersister { get; set; } @@ -29,17 +33,12 @@ public void Invoke(HandlerInvocationContext context, Action next) } currentContext = context; - physicalMessage = context.PhysicalMessage; - - // We need this for backwards compatibility because in v4.0.0 we still have this headers being sent as part of the message even if MessageIntent == MessageIntentEnum.Publish - if (physicalMessage.MessageIntent == MessageIntentEnum.Publish) - { - physicalMessage.Headers.Remove(Headers.SagaId); - physicalMessage.Headers.Remove(Headers.SagaType); - } var sagaInstanceState = new ActiveSagaInstance(saga); + //so that other behaviors can access the saga + context.Set(sagaInstanceState); + var loadedEntity = TryLoadSagaEntity(saga, context.LogicalMessage); if (loadedEntity == null) @@ -66,8 +65,6 @@ public void Invoke(HandlerInvocationContext context, Action next) context.MessageHandler.Invocation = HandlerInvocationCache.InvokeTimeout; } - //so that other behaviors can access the saga - context.Set(sagaInstanceState); next(); @@ -105,7 +102,7 @@ public void Invoke(HandlerInvocationContext context, Action next) void InvokeSagaNotFoundHandlers() { - logger.WarnFormat("Could not find a saga for the message type {0} with id {1}. Going to invoke SagaNotFoundHandlers.", currentContext.LogicalMessage.MessageType.FullName, physicalMessage.Id); + logger.WarnFormat("Could not find a saga for the message type {0}. Going to invoke SagaNotFoundHandlers.", currentContext.LogicalMessage.MessageType.FullName); foreach (var handler in currentContext.Builder.BuildAll()) { @@ -161,7 +158,8 @@ IEnumerable GetFindersFor(Type messageType, Type sagaEntityType) { string sagaId; - physicalMessage.Headers.TryGetValue(Headers.SagaId, out sagaId); + + currentContext.LogicalMessage.Headers.TryGetValue(Headers.SagaId, out sagaId); if (sagaEntityType == null || string.IsNullOrEmpty(sagaId)) { @@ -193,18 +191,22 @@ IContainSagaData CreateNewSagaEntity(Type sagaType) sagaEntity.Id = CombGuid.Generate(); - if (physicalMessage.ReplyToAddress != null) + TransportMessage physicalMessage; + + if (currentContext.TryGet(ReceivePhysicalMessageContext.IncomingPhysicalMessageKey, out physicalMessage)) { - sagaEntity.Originator = physicalMessage.ReplyToAddress.ToString(); - } + sagaEntity.OriginalMessageId = physicalMessage.Id; - sagaEntity.OriginalMessageId = physicalMessage.Id; + if (physicalMessage.ReplyToAddress != null) + { + sagaEntity.Originator = physicalMessage.ReplyToAddress.ToString(); + } + } return sagaEntity; } HandlerInvocationContext currentContext; - TransportMessage physicalMessage; readonly ILog logger = LogManager.GetLogger(typeof(SagaPersistenceBehavior)); } diff --git a/src/NServiceBus.Core/Sagas/SagaSendBehavior.cs b/src/NServiceBus.Core/Sagas/SagaSendBehavior.cs index 66f157a6f27..8e62c78e2ca 100644 --- a/src/NServiceBus.Core/Sagas/SagaSendBehavior.cs +++ b/src/NServiceBus.Core/Sagas/SagaSendBehavior.cs @@ -1,10 +1,14 @@ namespace NServiceBus.Sagas { using System; + using System.ComponentModel; using Pipeline; using Pipeline.Contexts; - class SagaSendBehavior : IBehavior + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class SagaSendBehavior : IBehavior { public void Invoke(SendLogicalMessageContext context, Action next) { diff --git a/src/NServiceBus.Core/Sagas/Sagas.cs b/src/NServiceBus.Core/Sagas/Sagas.cs index 342121bd04c..95cd54f9198 100644 --- a/src/NServiceBus.Core/Sagas/Sagas.cs +++ b/src/NServiceBus.Core/Sagas/Sagas.cs @@ -83,17 +83,17 @@ internal static void ConfigureHowToFindSagaWithMessage(Type sagaType, PropertyIn void CreateAdditionalFindersAsNecessary() { - foreach (var sagaEntityType in SagaEntityToMessageToPropertyLookup.Keys) - foreach (var messageType in SagaEntityToMessageToPropertyLookup[sagaEntityType].Keys) + foreach (var sagaEntityPair in SagaEntityToMessageToPropertyLookup) + { + foreach (var messageType in sagaEntityPair.Value.Keys) { - var pair = SagaEntityToMessageToPropertyLookup[sagaEntityType][messageType]; - CreatePropertyFinder(sagaEntityType, messageType, pair.Key, pair.Value); + var pair = sagaEntityPair.Value[messageType]; + CreatePropertyFinder(sagaEntityPair.Key, messageType, pair.Key, pair.Value); } + } - foreach (var sagaType in SagaTypeToSagaEntityTypeLookup.Keys) + foreach (var sagaEntityType in SagaTypeToSagaEntityTypeLookup.Values) { - var sagaEntityType = SagaTypeToSagaEntityTypeLookup[sagaType]; - var sagaHeaderIdFinder = typeof(HeaderSagaIdFinder<>).MakeGenericType(sagaEntityType); Configure.Component(sagaHeaderIdFinder, DependencyLifecycle.InstancePerCall); ConfigureFinder(sagaHeaderIdFinder); @@ -201,9 +201,15 @@ public static MethodInfo GetFindByMethodForFinder(IFinder finder, object message methods.TryGetValue(message.GetType(), out result); if (result == null) - foreach (var messageType in methods.Keys) - if (messageType.IsInstanceOfType(message)) - result = methods[messageType]; + { + foreach (var messageTypePair in methods) + { + if (messageTypePair.Key.IsInstanceOfType(message)) + { + result = messageTypePair.Value; + } + } + } } return result; @@ -215,18 +221,18 @@ public static MethodInfo GetFindByMethodForFinder(IFinder finder, object message [ObsoleteEx(Replacement = "GetFindersForMessageAndEntity", TreatAsErrorFromVersion = "4.3")] public static IEnumerable GetFindersFor(object m) { - foreach (var finderType in FinderTypeToMessageToMethodInfoLookup.Keys) + foreach (var finderPair in FinderTypeToMessageToMethodInfoLookup) { - var messageToMethodInfo = FinderTypeToMessageToMethodInfoLookup[finderType]; + var messageToMethodInfo = finderPair.Value; if (messageToMethodInfo.ContainsKey(m.GetType())) { - yield return finderType; + yield return finderPair.Key; continue; } foreach (var messageType in messageToMethodInfo.Keys) if (messageType.IsInstanceOfType(m)) - yield return finderType; + yield return finderPair.Key; } } @@ -238,23 +244,23 @@ public static IEnumerable GetFindersForMessageAndEntity(Type messageType, var findersWithExactMatch = new List(); var findersMatchingBaseTypes = new List(); - foreach (var finderType in FinderTypeToMessageToMethodInfoLookup.Keys) + foreach (var finderPair in FinderTypeToMessageToMethodInfoLookup) { - var messageToMethodInfo = FinderTypeToMessageToMethodInfoLookup[finderType]; + var messageToMethodInfo = finderPair.Value; MethodInfo methodInfo; if (messageToMethodInfo.TryGetValue(messageType, out methodInfo) && methodInfo.ReturnType == entityType) { - findersWithExactMatch.Add(finderType); + findersWithExactMatch.Add(finderPair.Key); } else { - foreach (var otherMessage in messageToMethodInfo.Keys) + foreach (var otherMessagePair in messageToMethodInfo) { - if (otherMessage.IsAssignableFrom(messageType) && messageToMethodInfo[otherMessage].ReturnType == entityType) + if (otherMessagePair.Key.IsAssignableFrom(messageType) && otherMessagePair.Value.ReturnType == entityType) { - findersMatchingBaseTypes.Add(finderType); + findersMatchingBaseTypes.Add(finderPair.Key); } } } diff --git a/src/NServiceBus.Core/Satellites/SatelliteLauncher.cs b/src/NServiceBus.Core/Satellites/SatelliteLauncher.cs index 43479c966cc..6be83b01fbd 100644 --- a/src/NServiceBus.Core/Satellites/SatelliteLauncher.cs +++ b/src/NServiceBus.Core/Satellites/SatelliteLauncher.cs @@ -35,7 +35,7 @@ public void Start() { var satellite = satellitesList[index]; - Logger.DebugFormat("Starting {1}/{2} '{0}' satellite", satellite.GetType().AssemblyQualifiedName, + Logger.DebugFormat("Starting {1}/{2} {0} satellite", satellite.GetType().AssemblyQualifiedName, index + 1, satellitesList.Count); var satelliteContext = new SatelliteContext @@ -60,7 +60,7 @@ public void Start() satelliteContexts[index] = satelliteContext; - Logger.InfoFormat("Started {1}/{2} '{0}' satellite", satellite.GetType().AssemblyQualifiedName, + Logger.InfoFormat("Started {1}/{2} {0} satellite", satellite.GetType().AssemblyQualifiedName, index + 1, satellitesList.Count); }); @@ -72,7 +72,7 @@ public void Stop() { Parallel.ForEach(satellites, (context, state, index) => { - Logger.DebugFormat("Stopping {1}/{2} '{0}' satellite", context.Instance.GetType().AssemblyQualifiedName, + Logger.DebugFormat("Stopping {1}/{2} {0} satellite", context.Instance.GetType().AssemblyQualifiedName, index + 1, satellites.Count); if (context.Transport != null) @@ -82,7 +82,7 @@ public void Stop() context.Instance.Stop(); - Logger.InfoFormat("Stopped {1}/{2} '{0}' satellite", context.Instance.GetType().AssemblyQualifiedName, + Logger.InfoFormat("Stopped {1}/{2} {0} satellite", context.Instance.GetType().AssemblyQualifiedName, index + 1, satellites.Count); }); } diff --git a/src/NServiceBus.Core/Scheduling/Configuration/ConfigureScheduledTaskAsSystemMessages.cs b/src/NServiceBus.Core/Scheduling/Configuration/ConfigureScheduledTaskAsSystemMessages.cs index fae8a9c6120..9851b1eb03d 100644 --- a/src/NServiceBus.Core/Scheduling/Configuration/ConfigureScheduledTaskAsSystemMessages.cs +++ b/src/NServiceBus.Core/Scheduling/Configuration/ConfigureScheduledTaskAsSystemMessages.cs @@ -4,7 +4,7 @@ public class ConfigureScheduledTaskAsSystemMessages : IWantToRunBeforeConfigurat { public void Init() { - Configure.Instance.AddSystemMessagesAs(t => typeof(Messages.ScheduledTask).IsAssignableFrom(t)); + MessageConventionExtensions.AddSystemMessagesConventions(t => typeof(Messages.ScheduledTask).IsAssignableFrom(t)); } } } \ No newline at end of file diff --git a/src/NServiceBus.Core/Scheduling/InMemoryScheduledTaskStorage.cs b/src/NServiceBus.Core/Scheduling/InMemoryScheduledTaskStorage.cs index 08e10994c7b..7f0d09442c4 100644 --- a/src/NServiceBus.Core/Scheduling/InMemoryScheduledTaskStorage.cs +++ b/src/NServiceBus.Core/Scheduling/InMemoryScheduledTaskStorage.cs @@ -15,10 +15,9 @@ public void Add(ScheduledTask scheduledTask) public ScheduledTask Get(Guid taskId) { - if (scheduledTasks.ContainsKey(taskId)) - return scheduledTasks[taskId]; - - return null; + ScheduledTask task; + scheduledTasks.TryGetValue(taskId, out task); + return task; } public IDictionary Tasks diff --git a/src/NServiceBus.Core/SecondLevelRetries/DefaultRetryPolicy.cs b/src/NServiceBus.Core/SecondLevelRetries/DefaultRetryPolicy.cs index eb0fbb5a7c9..bdb55b4a360 100644 --- a/src/NServiceBus.Core/SecondLevelRetries/DefaultRetryPolicy.cs +++ b/src/NServiceBus.Core/SecondLevelRetries/DefaultRetryPolicy.cs @@ -3,6 +3,8 @@ namespace NServiceBus.SecondLevelRetries using System; using Helpers; + + [ObsoleteEx(RemoveInVersion = "5.0", TreatAsErrorFromVersion = "5.0", Message = "Should not be public")] public static class DefaultRetryPolicy { public static int NumberOfRetries = 3; @@ -13,7 +15,9 @@ public static class DefaultRetryPolicy static TimeSpan Validate(TransportMessage message) { if (HasReachedMaxTime(message)) + { return TimeSpan.MinValue; + } var numberOfRetries = TransportMessageHelpers.GetNumberOfRetries(message); @@ -41,6 +45,10 @@ static bool HasReachedMaxTime(TransportMessage message) return true; } } + // ReSharper disable once EmptyGeneralCatchClause + // this code won't usually throw but in case a user has decided to hack a message/headers and for some bizarre reason + // they changed the date and that parse fails, we want to make sure that doesn't prevent the message from being + // forwarded to the error queue. catch (Exception) { } diff --git a/src/NServiceBus.Core/SecondLevelRetries/Helpers/TransportMessageHelpers.cs b/src/NServiceBus.Core/SecondLevelRetries/Helpers/TransportMessageHelpers.cs index d80690b3166..300c1eda410 100644 --- a/src/NServiceBus.Core/SecondLevelRetries/Helpers/TransportMessageHelpers.cs +++ b/src/NServiceBus.Core/SecondLevelRetries/Helpers/TransportMessageHelpers.cs @@ -26,7 +26,9 @@ public static Address GetAddressOfFaultingEndpoint(TransportMessage message) public static string GetHeader(TransportMessage message, string key) { - return message.Headers.ContainsKey(key) ? message.Headers[key] : null; + string value; + message.Headers.TryGetValue(key, out value); + return value; } public static bool HeaderExists(TransportMessage message, string key) diff --git a/src/NServiceBus.Core/Serializers/Json/Internal/MessageSerializationBinder.cs b/src/NServiceBus.Core/Serializers/Json/Internal/MessageSerializationBinder.cs index fce77c51afc..3b5774408bb 100644 --- a/src/NServiceBus.Core/Serializers/Json/Internal/MessageSerializationBinder.cs +++ b/src/NServiceBus.Core/Serializers/Json/Internal/MessageSerializationBinder.cs @@ -1,16 +1,20 @@ namespace NServiceBus.Serializers.Json.Internal { using System; + using System.Collections.Generic; + using System.Linq; using System.Runtime.Serialization; using MessageInterfaces; public class MessageSerializationBinder : SerializationBinder { private readonly IMessageMapper _messageMapper; + private readonly IList messageTypes; - public MessageSerializationBinder(IMessageMapper messageMapper) + public MessageSerializationBinder(IMessageMapper messageMapper, IList messageTypes = null) { _messageMapper = messageMapper; + this.messageTypes = messageTypes; } public override void BindToName(Type serializedType, out string assemblyName, out string typeName) @@ -23,9 +27,22 @@ public override void BindToName(Type serializedType, out string assemblyName, ou public override Type BindToType(string assemblyName, string typeName) { - throw new NotImplementedException(); - //string resolvedTypeName = typeName + ", " + assemblyName; - //return Type.GetType(resolvedTypeName, true); + Type resolved = null; + if (messageTypes != null) // usually the requested message types are provided, so this should be fast + { + resolved = messageTypes.FirstOrDefault(t => t.Name.Contains(typeName)); + } + if (resolved == null) // if the type has been used before it should be resolvable like this + { + resolved = Type.GetType(typeName); + } + if (resolved == null) // if the type has not been used before, we need to find it brute force + { + resolved = AppDomain.CurrentDomain.GetAssemblies() + .Select(a => a.GetType(typeName)) + .FirstOrDefault(t => t != null); + } + return resolved; } } } \ No newline at end of file diff --git a/src/NServiceBus.Core/Serializers/Json/JsonMessageSerializerBase.cs b/src/NServiceBus.Core/Serializers/Json/JsonMessageSerializerBase.cs index 222a9b5fb89..ace298e0865 100644 --- a/src/NServiceBus.Core/Serializers/Json/JsonMessageSerializerBase.cs +++ b/src/NServiceBus.Core/Serializers/Json/JsonMessageSerializerBase.cs @@ -80,6 +80,7 @@ public object[] Deserialize(Stream stream, IList messageTypes = null) var jsonSerializer = JsonSerializer.Create(settings); jsonSerializer.ContractResolver = new MessageContractResolver(messageMapper); + jsonSerializer.Binder = new MessageSerializationBinder(messageMapper, messageTypes); var reader = CreateJsonReader(stream); reader.Read(); diff --git a/src/NServiceBus.Core/Serializers/XML/XmlMessageSerializer.cs b/src/NServiceBus.Core/Serializers/XML/XmlMessageSerializer.cs index 0b358cf0195..6238df926c4 100644 --- a/src/NServiceBus.Core/Serializers/XML/XmlMessageSerializer.cs +++ b/src/NServiceBus.Core/Serializers/XML/XmlMessageSerializer.cs @@ -32,10 +32,10 @@ public class XmlMessageSerializer : IMessageSerializer public string Namespace { get { return nameSpace; } - set { nameSpace = TrimPotentialTralingForwardSlashes(value); } + set { nameSpace = TrimPotentialTrailingForwardSlashes(value); } } - string TrimPotentialTralingForwardSlashes(string value) + string TrimPotentialTrailingForwardSlashes(string value) { if (value == null) { @@ -779,9 +779,10 @@ object GetPropertyValue(Type type, XmlNode n) typeToCreate = typesToCreateForArrays[type]; } - if (typesToCreateForEnumerables.ContainsKey(type)) //handle IEnumerable + Type typeToCreateForEnumerables; + if (typesToCreateForEnumerables.TryGetValue(type, out typeToCreateForEnumerables)) //handle IEnumerable { - typeToCreate = typesToCreateForEnumerables[type]; + typeToCreate = typeToCreateForEnumerables; } if (typeof(IList).IsAssignableFrom(typeToCreate)) @@ -907,12 +908,13 @@ void Write(StringBuilder builder, Type t, object obj) return; } - if (!typeToProperties.ContainsKey(t)) + IEnumerable properties; + if (!typeToProperties.TryGetValue(t, out properties)) { throw new InvalidOperationException(string.Format("Type {0} was not registered in the serializer. Check that it appears in the list of configured assemblies/types to scan.", t.FullName)); } - foreach (var prop in typeToProperties[t]) + foreach (var prop in properties) { if (IsIndexedProperty(prop)) { diff --git a/src/NServiceBus.Core/Settings/SettingsHolder.cs b/src/NServiceBus.Core/Settings/SettingsHolder.cs index 9bbb3d0df45..bec610229c9 100644 --- a/src/NServiceBus.Core/Settings/SettingsHolder.cs +++ b/src/NServiceBus.Core/Settings/SettingsHolder.cs @@ -80,7 +80,6 @@ public static void SetProperty(Expression> property, object v Set(typeof(T).FullName + "." + prop.Name, value); } - /// /// Sets the default value of the given property /// @@ -91,7 +90,6 @@ public static void SetPropertyDefault(Expression> property, o SetDefault(typeof(T).FullName + "." + prop.Name, value); } - /// /// Sets the default setting value. /// diff --git a/src/NServiceBus.Core/Timeout/Core/TimeoutData.cs b/src/NServiceBus.Core/Timeout/Core/TimeoutData.cs index ac98f3bb27f..7252ae7fc4a 100644 --- a/src/NServiceBus.Core/Timeout/Core/TimeoutData.cs +++ b/src/NServiceBus.Core/Timeout/Core/TimeoutData.cs @@ -67,10 +67,14 @@ public override string ToString() public TransportMessage ToTransportMessage() { var replyToAddress = Address.Local; - if (Headers != null && Headers.ContainsKey(OriginalReplyToAddress)) + if (Headers != null) { - replyToAddress = Address.Parse(Headers[OriginalReplyToAddress]); - Headers.Remove(OriginalReplyToAddress); + string originalReplyToAddressValue; + if (Headers.TryGetValue(OriginalReplyToAddress, out originalReplyToAddressValue)) + { + replyToAddress = Address.Parse(originalReplyToAddressValue); + Headers.Remove(OriginalReplyToAddress); + } } var transportMessage = new TransportMessage(Id,Headers) diff --git a/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutMessageProcessor.cs b/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutMessageProcessor.cs index 818e501b8b8..ba0a92f9e60 100644 --- a/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutMessageProcessor.cs +++ b/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutMessageProcessor.cs @@ -45,9 +45,13 @@ public bool Handle(TransportMessage message) { //dispatch request will arrive at the same input so we need to make sure to call the correct handler if (message.Headers.ContainsKey(TimeoutIdToDispatchHeader)) + { HandleBackwardsCompatibility(message); + } else + { HandleInternal(message); + } return true; } @@ -62,9 +66,10 @@ void HandleBackwardsCompatibility(TransportMessage message) message.Headers.Remove(TimeoutIdToDispatchHeader); message.Headers.Remove(TimeoutDestinationHeader); - if (message.Headers.ContainsKey(TimeoutManagerHeaders.RouteExpiredTimeoutTo)) + string routeExpiredTimeoutTo; + if (message.Headers.TryGetValue(TimeoutManagerHeaders.RouteExpiredTimeoutTo, out routeExpiredTimeoutTo)) { - destination = Address.Parse(message.Headers[TimeoutManagerHeaders.RouteExpiredTimeoutTo]); + destination = Address.Parse(routeExpiredTimeoutTo); } TimeoutManager.RemoveTimeout(timeoutId); @@ -75,9 +80,10 @@ void HandleInternal(TransportMessage message) { var sagaId = Guid.Empty; - if (message.Headers.ContainsKey(Headers.SagaId)) + string sagaIdString; + if (message.Headers.TryGetValue(Headers.SagaId, out sagaIdString)) { - sagaId = Guid.Parse(message.Headers[Headers.SagaId]); + sagaId = Guid.Parse(sagaIdString); } if (message.Headers.ContainsKey(TimeoutManagerHeaders.ClearTimeouts)) @@ -89,14 +95,18 @@ void HandleInternal(TransportMessage message) } else { - if (!message.Headers.ContainsKey(TimeoutManagerHeaders.Expire)) + string expire; + if (!message.Headers.TryGetValue(TimeoutManagerHeaders.Expire, out expire)) + { throw new InvalidOperationException("Non timeout message arrived at the timeout manager, id:" + message.Id); + } var destination = message.ReplyToAddress; - if (message.Headers.ContainsKey(TimeoutManagerHeaders.RouteExpiredTimeoutTo)) + string routeExpiredTimeoutTo; + if (message.Headers.TryGetValue(TimeoutManagerHeaders.RouteExpiredTimeoutTo, out routeExpiredTimeoutTo)) { - destination = Address.Parse(message.Headers[TimeoutManagerHeaders.RouteExpiredTimeoutTo]); + destination = Address.Parse(routeExpiredTimeoutTo); } var data = new TimeoutData @@ -104,7 +114,7 @@ void HandleInternal(TransportMessage message) Destination = destination, SagaId = sagaId, State = message.Body, - Time = DateTimeExtensions.ToUtcDateTime(message.Headers[TimeoutManagerHeaders.Expire]), + Time = DateTimeExtensions.ToUtcDateTime(expire), CorrelationId = GetCorrelationIdToStore(message), Headers = message.Headers, OwningTimeoutManager = Configure.EndpointName diff --git a/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutPersisterReceiver.cs b/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutPersisterReceiver.cs index 53c43c6efd2..7e419886704 100644 --- a/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutPersisterReceiver.cs +++ b/src/NServiceBus.Core/Timeout/Hosting/Windows/TimeoutPersisterReceiver.cs @@ -34,6 +34,7 @@ public void Start() public void Stop() { + TimeoutManager.TimeoutPushed -= TimeoutsManagerOnTimeoutPushed; tokenSource.Cancel(); resetEvent.WaitOne(); } @@ -146,14 +147,14 @@ void TimeoutsManagerOnTimeoutPushed(object sender, TimeoutData timeoutData) static readonly ILog Logger = LogManager.GetLogger(typeof(TimeoutPersisterReceiver)); - readonly RepeatedFailuresOverTimeCircuitBreaker circuitBreaker = + RepeatedFailuresOverTimeCircuitBreaker circuitBreaker = new RepeatedFailuresOverTimeCircuitBreaker("TimeoutStorageConnectivity", TimeSpan.FromMinutes(2), ex => Configure.Instance.RaiseCriticalError( "Repeated failures when fetching timeouts from storage, endpoint will be terminated.", ex)); readonly object lockObject = new object(); - readonly ManualResetEvent resetEvent = new ManualResetEvent(true); + ManualResetEvent resetEvent = new ManualResetEvent(true); DateTime nextRetrieval = DateTime.UtcNow; volatile bool timeoutPushed; CancellationTokenSource tokenSource; diff --git a/src/NServiceBus.Core/TransportMessage.cs b/src/NServiceBus.Core/TransportMessage.cs index 75e73ecaf1b..c8485d055d8 100644 --- a/src/NServiceBus.Core/TransportMessage.cs +++ b/src/NServiceBus.Core/TransportMessage.cs @@ -4,6 +4,7 @@ namespace NServiceBus using System.Collections.Generic; using IdGeneration; using Support; + using Unicast; /// /// An envelope used by NServiceBus to package messages for transmission. @@ -25,10 +26,18 @@ public TransportMessage() Headers[NServiceBus.Headers.MessageId] = id; CorrelationId = id; Headers.Add(NServiceBus.Headers.OriginatingEndpoint, Configure.EndpointName); - Headers.Add(NServiceBus.Headers.OriginatingMachine, RuntimeEnvironment.MachineName); + Headers.Add(NServiceBus.Headers.OriginatingHostId, UnicastBus.HostIdForTransportMessageBecauseEverythingIsStaticsInTheConstructor.ToString("N")); MessageIntent = MessageIntentEnum.Send; - Headers[NServiceBus.Headers.NServiceBusVersion] = NServiceBusVersion.Version; + Headers[NServiceBus.Headers.NServiceBusVersion] = GitFlowVersion.MajorMinorPatch; Headers[NServiceBus.Headers.TimeSent] = DateTimeExtensions.ToWireFormattedString(DateTime.UtcNow); + + AddBackwardsCompatibilityHeaders(); + } + + [ObsoleteEx(RemoveInVersion = "5.0")] + void AddBackwardsCompatibilityHeaders() + { + Headers.Add("NServiceBus.OriginatingMachine", RuntimeEnvironment.MachineName); } /// @@ -58,12 +67,12 @@ public string Id { get { - if (!Headers.ContainsKey(NServiceBus.Headers.MessageId)) + string headerId; + if (Headers.TryGetValue(NServiceBus.Headers.MessageId, out headerId)) { - return id; + return headerId; } - - return Headers[NServiceBus.Headers.MessageId]; + return id; } } @@ -116,9 +125,10 @@ public MessageIntentEnum MessageIntent { var messageIntent = default(MessageIntentEnum); - if (Headers.ContainsKey(NServiceBus.Headers.MessageIntent)) + string messageIntentString; + if (Headers.TryGetValue(NServiceBus.Headers.MessageIntent, out messageIntentString)) { - Enum.TryParse(Headers[NServiceBus.Headers.MessageIntent], true, out messageIntent); + Enum.TryParse(messageIntentString, true, out messageIntent); } return messageIntent; diff --git a/src/NServiceBus.Core/Transports/Msmq/MsmqDequeueStrategy.cs b/src/NServiceBus.Core/Transports/Msmq/MsmqDequeueStrategy.cs index 665d099fe6b..0aa592a9713 100644 --- a/src/NServiceBus.Core/Transports/Msmq/MsmqDequeueStrategy.cs +++ b/src/NServiceBus.Core/Transports/Msmq/MsmqDequeueStrategy.cs @@ -96,6 +96,8 @@ public void Init(Address address, TransactionSettings settings, FuncThe maximum concurrency level supported. public void Start(int maximumConcurrencyLevel) { + MessageQueue.ClearConnectionCache(); + this.maximumConcurrencyLevel = maximumConcurrencyLevel; throttlingSemaphore = new SemaphoreSlim(maximumConcurrencyLevel, maximumConcurrencyLevel); @@ -361,10 +363,10 @@ static string GetUserName() } static readonly ILog Logger = LogManager.GetLogger(typeof(MsmqDequeueStrategy)); - readonly CircuitBreaker circuitBreaker = new CircuitBreaker(100, TimeSpan.FromSeconds(30)); - readonly AutoResetEvent peekResetEvent = new AutoResetEvent(false); + CircuitBreaker circuitBreaker = new CircuitBreaker(100, TimeSpan.FromSeconds(30)); + AutoResetEvent peekResetEvent = new AutoResetEvent(false); readonly TimeSpan receiveTimeout = TimeSpan.FromSeconds(1); - readonly ManualResetEvent stopResetEvent = new ManualResetEvent(true); + ManualResetEvent stopResetEvent = new ManualResetEvent(true); Action endProcessMessage; int maximumConcurrencyLevel; MessageQueue queue; diff --git a/src/NServiceBus.Core/Transports/Msmq/MsmqQueueCreator.cs b/src/NServiceBus.Core/Transports/Msmq/MsmqQueueCreator.cs index dc0afb0fac1..17e2e4f4eb5 100644 --- a/src/NServiceBus.Core/Transports/Msmq/MsmqQueueCreator.cs +++ b/src/NServiceBus.Core/Transports/Msmq/MsmqQueueCreator.cs @@ -104,9 +104,16 @@ private static void SetPermissionsForQueue(string queue, string account) /// public static string GetFullPathWithoutPrefix(Address address) { - return address.Machine + MsmqUtilities.PRIVATE + address.Queue; + var queueName = address.Queue; + var msmqTotalQueueName = address.Machine + MsmqUtilities.PRIVATE + queueName; + + if (msmqTotalQueueName.Length >= 114) //Setpermission is limiting us here, docs say it should be 380 + 124 + { + msmqTotalQueueName = address.Machine + MsmqUtilities.PRIVATE + Utils.DeterministicGuid.Create(queueName); + } + + return msmqTotalQueueName; } - } -} \ No newline at end of file +} diff --git a/src/NServiceBus.Core/Transports/Msmq/MsmqUnitOfWork.cs b/src/NServiceBus.Core/Transports/Msmq/MsmqUnitOfWork.cs index 231f5b7eb76..cd1e4883147 100644 --- a/src/NServiceBus.Core/Transports/Msmq/MsmqUnitOfWork.cs +++ b/src/NServiceBus.Core/Transports/Msmq/MsmqUnitOfWork.cs @@ -31,6 +31,6 @@ public void ClearTransaction() currentTransaction.Value = null; } - readonly ThreadLocal currentTransaction = new ThreadLocal(); + ThreadLocal currentTransaction = new ThreadLocal(); } } \ No newline at end of file diff --git a/src/NServiceBus.Core/Transports/TransportDefinition.cs b/src/NServiceBus.Core/Transports/TransportDefinition.cs index 4cccaec79d4..16a8a9b718e 100644 --- a/src/NServiceBus.Core/Transports/TransportDefinition.cs +++ b/src/NServiceBus.Core/Transports/TransportDefinition.cs @@ -14,5 +14,10 @@ public abstract class TransportDefinition /// Indicates that the transport has a central store for subscriptions /// public bool HasSupportForCentralizedPubSub { get; protected set; } + + /// + /// Indicates that the transport has support for distributed transactions + /// + public bool? HasSupportForDistributedTransactions { get; protected set; } } } \ No newline at end of file diff --git a/src/NServiceBus.Core/Unicast/Behaviors/CallbackInvocationBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/CallbackInvocationBehavior.cs index 8ec05d94b5a..40243d4c931 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/CallbackInvocationBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/CallbackInvocationBehavior.cs @@ -1,15 +1,16 @@ namespace NServiceBus.Unicast.Behaviors { using System; - using System.Collections.Generic; + using System.ComponentModel; using System.Linq; - using Messages; using Pipeline; using Pipeline.Contexts; using Unicast; using Transport; - class CallbackInvocationBehavior : IBehavior + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class CallbackInvocationBehavior : IBehavior { public const string CallbackInvokedKey = "NServiceBus.CallbackInvocationBehavior.CallbackWasInvoked"; diff --git a/src/NServiceBus.Core/Unicast/Behaviors/ChildContainerBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/ChildContainerBehavior.cs index be10e3126d7..c56549a8351 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/ChildContainerBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/ChildContainerBehavior.cs @@ -1,10 +1,13 @@ namespace NServiceBus.Unicast.Behaviors { using System; + using System.ComponentModel; using Pipeline; using Pipeline.Contexts; - class ChildContainerBehavior:IBehavior + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class ChildContainerBehavior : IBehavior { public void Invoke(ReceivePhysicalMessageContext context, Action next) { diff --git a/src/NServiceBus.Core/Unicast/Behaviors/CreatePhysicalMessageBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/CreatePhysicalMessageBehavior.cs index 23053260edb..79a5b1e4bef 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/CreatePhysicalMessageBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/CreatePhysicalMessageBehavior.cs @@ -1,19 +1,22 @@ namespace NServiceBus.Unicast.Behaviors { using System; + using System.ComponentModel; using System.Linq; using Pipeline; using Pipeline.Contexts; using Unicast; using Messages; - class CreatePhysicalMessageBehavior:IBehavior + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class CreatePhysicalMessageBehavior : IBehavior { public MessageMetadataRegistry MessageMetadataRegistry { get; set; } public UnicastBus UnicastBus { get; set; } - public PipelineFactory PipelineFactory { get; set; } + public PipelineExecutor PipelineExecutor { get; set; } public void Invoke(SendLogicalMessagesContext context, Action next) { @@ -49,7 +52,7 @@ public void Invoke(SendLogicalMessagesContext context, Action next) context.Set(toSend); - PipelineFactory.InvokeSendPipeline(sendOptions,toSend); + PipelineExecutor.InvokeSendPipeline(sendOptions,toSend); next(); } diff --git a/src/NServiceBus.Core/Unicast/Behaviors/DispatchMessageToTransportBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/DispatchMessageToTransportBehavior.cs index d54e4875cf2..c701778d790 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/DispatchMessageToTransportBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/DispatchMessageToTransportBehavior.cs @@ -1,6 +1,7 @@ namespace NServiceBus.Unicast.Behaviors { using System; + using System.ComponentModel; using System.Configuration; using System.Linq; using Logging; @@ -9,7 +10,9 @@ using Transports; using Queuing; - class DispatchMessageToTransportBehavior : IBehavior + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class DispatchMessageToTransportBehavior : IBehavior { public ISendMessages MessageSender { get; set; } @@ -77,7 +80,7 @@ public void Invoke(SendPhysicalMessageContext context, Action next) } catch (QueueNotFoundException ex) { - throw new ConfigurationErrorsException("The destination queue '" + sendOptions.Destination + + throw new ConfigurationErrorsException("The destination queue '" + ex.Queue + "' could not be found. You may have misconfigured the destination for this kind of message (" + messageDescription + ") in the MessageEndpointMappings of the UnicastBusConfig section in your configuration file. " + diff --git a/src/NServiceBus.Core/Unicast/Behaviors/ForwardBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/ForwardBehavior.cs index 7636745a1e3..f928dc7f958 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/ForwardBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/ForwardBehavior.cs @@ -1,12 +1,15 @@ namespace NServiceBus.Unicast.Behaviors { using System; + using System.ComponentModel; using Pipeline; using Pipeline.Contexts; using Transports; using Unicast; - class ForwardBehavior : IBehavior + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class ForwardBehavior : IBehavior { public ISendMessages MessageSender { get; set; } diff --git a/src/NServiceBus.Core/Unicast/Behaviors/ImpersonateSenderBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/ImpersonateSenderBehavior.cs index 71cf4a07f6a..45ad1cf8c15 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/ImpersonateSenderBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/ImpersonateSenderBehavior.cs @@ -1,12 +1,16 @@ namespace NServiceBus.Unicast.Behaviors { using System; + using System.ComponentModel; using System.Threading; using Impersonation; using Pipeline; using Pipeline.Contexts; - class ImpersonateSenderBehavior : IBehavior + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class ImpersonateSenderBehavior : IBehavior { public ExtractIncomingPrincipal ExtractIncomingPrincipal { get; set; } diff --git a/src/NServiceBus.Core/Unicast/Behaviors/InvokeHandlersBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/InvokeHandlersBehavior.cs index df934013f01..ccad3253278 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/InvokeHandlersBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/InvokeHandlersBehavior.cs @@ -2,6 +2,7 @@ { using System; using System.Collections.Generic; + using System.ComponentModel; using System.Linq; using System.Reflection; using Logging; @@ -12,7 +13,10 @@ using Unicast; using Transport; - class InvokeHandlersBehavior : IBehavior + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class InvokeHandlersBehavior : IBehavior { public IDictionary MessageDispatcherMappings { get; set; } diff --git a/src/NServiceBus.Core/Unicast/Behaviors/LoadHandlersBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/LoadHandlersBehavior.cs index ba2d7391f72..9379fcce4cc 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/LoadHandlersBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/LoadHandlersBehavior.cs @@ -1,19 +1,23 @@ namespace NServiceBus.Unicast.Behaviors { using System; + using System.ComponentModel; using System.Linq; using MessageInterfaces; using Pipeline; using Pipeline.Contexts; using Unicast; - class LoadHandlersBehavior : IBehavior + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class LoadHandlersBehavior : IBehavior { public IMessageHandlerRegistry HandlerRegistry { get; set; } public IMessageMapper MessageMapper { get; set; } - public PipelineFactory PipelineFactory { get; set; } + public PipelineExecutor PipelineFactory { get; set; } public void Invoke(ReceiveLogicalMessageContext context, Action next) { diff --git a/src/NServiceBus.Core/Unicast/Behaviors/MessageHandler.cs b/src/NServiceBus.Core/Unicast/Behaviors/MessageHandler.cs index 42730d023e3..a5ae4e8434b 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/MessageHandler.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/MessageHandler.cs @@ -1,8 +1,12 @@ namespace NServiceBus.Unicast.Behaviors { using System; + using System.ComponentModel; - class MessageHandler + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class MessageHandler { public object Instance { get; set; } public Action Invocation { get; set; } diff --git a/src/NServiceBus.Core/Unicast/Behaviors/MessageHandlingLoggingBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/MessageHandlingLoggingBehavior.cs index 9c1b2c4ca51..63796d0c9c2 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/MessageHandlingLoggingBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/MessageHandlingLoggingBehavior.cs @@ -1,15 +1,15 @@ namespace NServiceBus.Unicast.Behaviors { using System; + using System.ComponentModel; using System.Reflection; using Logging; using Pipeline; using Pipeline.Contexts; - - /// - /// Arguably not the most interesting behavior, but let's just handle logging like this too - /// - class MessageHandlingLoggingBehavior : IBehavior + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class MessageHandlingLoggingBehavior : IBehavior { static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); diff --git a/src/NServiceBus.Core/Unicast/Behaviors/MultiMessageBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/MultiMessageBehavior.cs index 399b8742a41..1c3359b2a2c 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/MultiMessageBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/MultiMessageBehavior.cs @@ -1,20 +1,22 @@ namespace NServiceBus.Unicast.Behaviors { using System; + using System.ComponentModel; using Pipeline; using Pipeline.Contexts; - - [ObsoleteEx(RemoveInVersion = "5.0", TreatAsErrorFromVersion = "5.0")] - class MultiMessageBehavior:IBehavior + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class MultiMessageBehavior : IBehavior { - public PipelineFactory PipelineFactory { get; set; } + public PipelineExecutor PipelineExecutor { get; set; } + [ObsoleteEx(RemoveInVersion = "5.0", TreatAsErrorFromVersion = "5.0")] public void Invoke(SendLogicalMessagesContext context, Action next) { foreach (var logicalMessage in context.LogicalMessages) { - PipelineFactory.InvokeSendPipeline(context.SendOptions,logicalMessage); + PipelineExecutor.InvokeSendPipeline(context.SendOptions, logicalMessage); } next(); } diff --git a/src/NServiceBus.Core/Unicast/Behaviors/MultiSendValidatorBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/MultiSendValidatorBehavior.cs index 0dc63b1a943..0720409adfe 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/MultiSendValidatorBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/MultiSendValidatorBehavior.cs @@ -1,11 +1,14 @@ namespace NServiceBus.Unicast.Behaviors { using System; + using System.ComponentModel; using System.Linq; using Pipeline; using Pipeline.Contexts; - class MultiSendValidatorBehavior : IBehavior + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class MultiSendValidatorBehavior : IBehavior { public void Invoke(SendLogicalMessagesContext context, Action next) { diff --git a/src/NServiceBus.Core/Unicast/Behaviors/RaiseMessageReceivedBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/RaiseMessageReceivedBehavior.cs index 0ee4df3d841..f2e39f98ab9 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/RaiseMessageReceivedBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/RaiseMessageReceivedBehavior.cs @@ -1,11 +1,14 @@ namespace NServiceBus.Unicast.Behaviors { using System; + using System.ComponentModel; using Pipeline; using Pipeline.Contexts; using Unicast; - class RaiseMessageReceivedBehavior : IBehavior + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class RaiseMessageReceivedBehavior : IBehavior { public UnicastBus UnicastBus { get; set; } diff --git a/src/NServiceBus.Core/Unicast/Behaviors/SendValidatorBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/SendValidatorBehavior.cs index 4d6357cdfda..0cb8a6f210a 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/SendValidatorBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/SendValidatorBehavior.cs @@ -1,11 +1,14 @@ namespace NServiceBus.Unicast.Behaviors { using System; + using System.ComponentModel; using Pipeline; using Pipeline.Contexts; using Unicast; - class SendValidatorBehavior : IBehavior + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class SendValidatorBehavior : IBehavior { public void Invoke(SendLogicalMessageContext context, Action next) { diff --git a/src/NServiceBus.Core/Unicast/Behaviors/SerializeMessagesBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/SerializeMessagesBehavior.cs index b7eba67891c..d5167474e7a 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/SerializeMessagesBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/SerializeMessagesBehavior.cs @@ -2,6 +2,7 @@ { using System; using System.Collections.Generic; + using System.ComponentModel; using System.IO; using System.Linq; using Messages; @@ -9,7 +10,9 @@ using Pipeline.Contexts; using Serialization; - class SerializeMessagesBehavior : IBehavior + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class SerializeMessagesBehavior : IBehavior { public IMessageSerializer MessageSerializer { get; set; } diff --git a/src/NServiceBus.Core/Unicast/Behaviors/SetCurrentMessageBeingHandledBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/SetCurrentMessageBeingHandledBehavior.cs index c7bf084f151..45539d6fd75 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/SetCurrentMessageBeingHandledBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/SetCurrentMessageBeingHandledBehavior.cs @@ -1,11 +1,14 @@ namespace NServiceBus.Unicast.Behaviors { using System; + using System.ComponentModel; using Messages; using Pipeline; using Pipeline.Contexts; - class SetCurrentMessageBeingHandledBehavior : IBehavior + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class SetCurrentMessageBeingHandledBehavior : IBehavior { public void Invoke(HandlerInvocationContext context, Action next) { diff --git a/src/NServiceBus.Core/Unicast/Config/ConfigUnicastBus.cs b/src/NServiceBus.Core/Unicast/Config/ConfigUnicastBus.cs index 12ef4560b9d..cb2f3c90eab 100644 --- a/src/NServiceBus.Core/Unicast/Config/ConfigUnicastBus.cs +++ b/src/NServiceBus.Core/Unicast/Config/ConfigUnicastBus.cs @@ -31,7 +31,8 @@ public void Configure(Configure config) ConfigureSubscriptionAuthorization(); RegisterMessageModules(); - Configurer.ConfigureComponent(DependencyLifecycle.SingleInstance); + Configurer.ConfigureComponent(DependencyLifecycle.SingleInstance); + Configurer.ConfigureComponent(DependencyLifecycle.SingleInstance); ConfigureBehaviors(); } diff --git a/src/NServiceBus.Core/Unicast/MessageContext.cs b/src/NServiceBus.Core/Unicast/MessageContext.cs index cb5cb42f4b6..92f342c0f02 100644 --- a/src/NServiceBus.Core/Unicast/MessageContext.cs +++ b/src/NServiceBus.Core/Unicast/MessageContext.cs @@ -27,9 +27,10 @@ public DateTime TimeSent { get { - if (transportMessage.Headers.ContainsKey(Headers.TimeSent)) + string timeSent; + if (transportMessage.Headers.TryGetValue(Headers.TimeSent, out timeSent)) { - return DateTimeExtensions.ToUtcDateTime(transportMessage.Headers[Headers.TimeSent]); + return DateTimeExtensions.ToUtcDateTime(timeSent); } return DateTime.MinValue; diff --git a/src/NServiceBus.Core/Unicast/MessageHandlerRegistry.cs b/src/NServiceBus.Core/Unicast/MessageHandlerRegistry.cs index 21a8bbdd3f2..5c11cc3a3fd 100644 --- a/src/NServiceBus.Core/Unicast/MessageHandlerRegistry.cs +++ b/src/NServiceBus.Core/Unicast/MessageHandlerRegistry.cs @@ -47,14 +47,15 @@ public void RegisterHandler(Type handlerType) foreach (var messageType in messageTypesThisHandlerHandles) { - if (!handlerList.ContainsKey(handlerType)) + List typeList; + if (!handlerList.TryGetValue(handlerType, out typeList)) { - handlerList.Add(handlerType, new List()); + handlerList[handlerType] = typeList = new List(); } - if (!(handlerList[handlerType].Contains(messageType))) + if (!typeList.Contains(messageType)) { - handlerList[handlerType].Add(messageType); + typeList.Add(messageType); Log.DebugFormat("Associated '{0}' message with '{1}' handler", messageType, handlerType); } diff --git a/src/NServiceBus.Core/Unicast/Messages/ExecuteLogicalMessagesBehavior.cs b/src/NServiceBus.Core/Unicast/Messages/ExecuteLogicalMessagesBehavior.cs index 89717fc734d..bd8c003ef52 100644 --- a/src/NServiceBus.Core/Unicast/Messages/ExecuteLogicalMessagesBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Messages/ExecuteLogicalMessagesBehavior.cs @@ -1,6 +1,7 @@ namespace NServiceBus.Unicast.Messages { using System; + using System.ComponentModel; using System.Linq; using System.Reflection; using Logging; @@ -8,9 +9,12 @@ using Pipeline.Contexts; using Transport; - class ExecuteLogicalMessagesBehavior : IBehavior + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class ExecuteLogicalMessagesBehavior : IBehavior { - public PipelineFactory PipelineFactory { get; set; } + public PipelineExecutor PipelineExecutor { get; set; } public void Invoke(ReceivePhysicalMessageContext context, Action next) { @@ -23,7 +27,7 @@ public void Invoke(ReceivePhysicalMessageContext context, Action next) var logicalMessages = context.LogicalMessages; foreach (var message in logicalMessages) { - PipelineFactory.InvokeLogicalMessagePipeline(message); + PipelineExecutor.InvokeLogicalMessagePipeline(message); } diff --git a/src/NServiceBus.Core/Unicast/Messages/ExtractLogicalMessagesBehavior.cs b/src/NServiceBus.Core/Unicast/Messages/ExtractLogicalMessagesBehavior.cs index 81ac38bcc62..704a716d015 100644 --- a/src/NServiceBus.Core/Unicast/Messages/ExtractLogicalMessagesBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Messages/ExtractLogicalMessagesBehavior.cs @@ -2,6 +2,7 @@ { using System; using System.Collections.Generic; + using System.ComponentModel; using System.IO; using System.Linq; using System.Reflection; @@ -13,7 +14,10 @@ using Transport; using Unicast; - class ExtractLogicalMessagesBehavior : IBehavior + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class ExtractLogicalMessagesBehavior : IBehavior { public IMessageSerializer MessageSerializer { get; set; } diff --git a/src/NServiceBus.Core/Unicast/Messages/LogicalMessage.cs b/src/NServiceBus.Core/Unicast/Messages/LogicalMessage.cs index 92354fae905..274033e424c 100644 --- a/src/NServiceBus.Core/Unicast/Messages/LogicalMessage.cs +++ b/src/NServiceBus.Core/Unicast/Messages/LogicalMessage.cs @@ -2,8 +2,12 @@ { using System; using System.Collections.Generic; + using System.ComponentModel; - class LogicalMessage + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class LogicalMessage { public LogicalMessage(MessageMetadata metadata, object message,Dictionary headers) { diff --git a/src/NServiceBus.Core/Unicast/Messages/LogicalMessageFactory.cs b/src/NServiceBus.Core/Unicast/Messages/LogicalMessageFactory.cs index df01d4e3208..01f62e1b3b1 100644 --- a/src/NServiceBus.Core/Unicast/Messages/LogicalMessageFactory.cs +++ b/src/NServiceBus.Core/Unicast/Messages/LogicalMessageFactory.cs @@ -2,17 +2,21 @@ namespace NServiceBus.Unicast.Messages { using System; using System.Collections.Generic; + using System.ComponentModel; using System.Linq; using MessageInterfaces; using Pipeline; - class LogicalMessageFactory + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class LogicalMessageFactory { public MessageMetadataRegistry MessageMetadataRegistry { get; set; } public IMessageMapper MessageMapper { get; set; } - public PipelineFactory PipelineFactory { get; set; } + public PipelineExecutor PipelineExecutor { get; set; } public List Create(T message) { @@ -59,7 +63,7 @@ Dictionary GetMessageHeaders(object message) { Dictionary> outgoingHeaders; - if (!PipelineFactory.CurrentContext.TryGet("NServiceBus.OutgoingHeaders", out outgoingHeaders)) + if (!PipelineExecutor.CurrentContext.TryGet("NServiceBus.OutgoingHeaders", out outgoingHeaders)) { return new Dictionary(); } diff --git a/src/NServiceBus.Core/Unicast/Messages/MessageMetadataRegistry.cs b/src/NServiceBus.Core/Unicast/Messages/MessageMetadataRegistry.cs index 12c907ed992..1cba42cca85 100644 --- a/src/NServiceBus.Core/Unicast/Messages/MessageMetadataRegistry.cs +++ b/src/NServiceBus.Core/Unicast/Messages/MessageMetadataRegistry.cs @@ -43,7 +43,7 @@ public IEnumerable GetMessageTypes(TransportMessage message) if (messageType == null) { - Logger.InfoFormat("Message type: '{0}' could not be determined by a 'Type.GetType', scanning known messages for a match.MessageId: {1}", messageTypeString, message.Id); + Logger.DebugFormat("Message type: '{0}' could not be determined by a 'Type.GetType', scanning known messages for a match.MessageId: {1}", messageTypeString, message.Id); var messageMetadata = messages.Values.FirstOrDefault(m => m.MessageType.FullName == messageTypeString); if (messageMetadata == null) diff --git a/src/NServiceBus.Core/Unicast/Monitoring/CausationMutator.cs b/src/NServiceBus.Core/Unicast/Monitoring/CausationMutator.cs index 88870ffd467..d4e29bb6c32 100644 --- a/src/NServiceBus.Core/Unicast/Monitoring/CausationMutator.cs +++ b/src/NServiceBus.Core/Unicast/Monitoring/CausationMutator.cs @@ -27,8 +27,11 @@ public void MutateOutgoing(object[] messages, TransportMessage transportMessage) { transportMessage.Headers[Headers.RelatedTo] = Bus.CurrentMessageContext.Id; - if (Bus.CurrentMessageContext.Headers.ContainsKey(Headers.ConversationId)) - conversationId = Bus.CurrentMessageContext.Headers[Headers.ConversationId]; + string conversationIdFromCurrentMessageContext; + if (Bus.CurrentMessageContext.Headers.TryGetValue(Headers.ConversationId, out conversationIdFromCurrentMessageContext)) + { + conversationId = conversationIdFromCurrentMessageContext; + } } transportMessage.Headers[Headers.ConversationId] = conversationId; diff --git a/src/NServiceBus.Core/Unicast/Monitoring/ProcessingStatistics.cs b/src/NServiceBus.Core/Unicast/Monitoring/ProcessingStatistics.cs index f953470b585..03017d05ddc 100644 --- a/src/NServiceBus.Core/Unicast/Monitoring/ProcessingStatistics.cs +++ b/src/NServiceBus.Core/Unicast/Monitoring/ProcessingStatistics.cs @@ -35,20 +35,25 @@ public void End(Exception ex = null) Bus.CurrentMessageContext.Headers[Headers.ProcessingEnded] = DateTimeExtensions.ToWireFormattedString(now); - if (Bus.CurrentMessageContext.Headers.ContainsKey(Headers.TimeSent)) + string timeSent; + if (Bus.CurrentMessageContext.Headers.TryGetValue(Headers.TimeSent, out timeSent)) { - UpdateCounters(DateTimeExtensions.ToUtcDateTime(Bus.CurrentMessageContext.Headers[Headers.TimeSent]), DateTimeExtensions.ToUtcDateTime(Bus.CurrentMessageContext.Headers[Headers.ProcessingStarted]), now); + UpdateCounters(DateTimeExtensions.ToUtcDateTime(timeSent), DateTimeExtensions.ToUtcDateTime(Bus.CurrentMessageContext.Headers[Headers.ProcessingStarted]), now); } } void UpdateCounters(DateTime timeSent, DateTime processingStarted, DateTime processingEnded) { - if(CriticalTimeCounter != null) + if (CriticalTimeCounter != null) + { CriticalTimeCounter.Update(timeSent, processingStarted,processingEnded); + } if (EstimatedTimeToSLABreachCalculator != null) + { EstimatedTimeToSLABreachCalculator.Update(timeSent, processingStarted, processingEnded); + } } public void Init() diff --git a/src/NServiceBus.Core/Unicast/Publishing/StorageDrivenPublisher.cs b/src/NServiceBus.Core/Unicast/Publishing/StorageDrivenPublisher.cs index 99bddffb0af..0953a287771 100644 --- a/src/NServiceBus.Core/Unicast/Publishing/StorageDrivenPublisher.cs +++ b/src/NServiceBus.Core/Unicast/Publishing/StorageDrivenPublisher.cs @@ -32,7 +32,7 @@ public bool Publish(TransportMessage message, IEnumerable eventTypes) if (SubscriptionStorage == null) throw new InvalidOperationException("Cannot publish on this endpoint - no subscription storage has been configured. Add either 'MsmqSubscriptionStorage()' or 'DbSubscriptionStorage()' after 'NServiceBus.Configure.With()'."); - var subscribers = Enumerable.ToList
(SubscriptionStorage.GetSubscriberAddressesForMessage(eventTypes.Select(t => new MessageType(t)))); + var subscribers = SubscriptionStorage.GetSubscriberAddressesForMessage(eventTypes.Select(t => new MessageType(t))).ToList(); if (!subscribers.Any()) return false; diff --git a/src/NServiceBus.Core/Unicast/SendOptions.cs b/src/NServiceBus.Core/Unicast/SendOptions.cs index f900fcabefa..b92f95c8694 100644 --- a/src/NServiceBus.Core/Unicast/SendOptions.cs +++ b/src/NServiceBus.Core/Unicast/SendOptions.cs @@ -1,8 +1,12 @@ namespace NServiceBus.Unicast { using System; + using System.ComponentModel; - class SendOptions + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class SendOptions { public SendOptions() { diff --git a/src/NServiceBus.Core/Unicast/Subscriptions/MessageDrivenSubscriptions/SubcriberSideFiltering/SubscriptionPredicatesEvaluator.cs b/src/NServiceBus.Core/Unicast/Subscriptions/MessageDrivenSubscriptions/SubcriberSideFiltering/SubscriptionPredicatesEvaluator.cs index 119e4aeffc0..31e74af3289 100644 --- a/src/NServiceBus.Core/Unicast/Subscriptions/MessageDrivenSubscriptions/SubcriberSideFiltering/SubscriptionPredicatesEvaluator.cs +++ b/src/NServiceBus.Core/Unicast/Subscriptions/MessageDrivenSubscriptions/SubcriberSideFiltering/SubscriptionPredicatesEvaluator.cs @@ -22,11 +22,18 @@ public IList> GetConditionsForMessage(object message) var result = new List>(); lock (locker) - if (messageTypeToConditionLookup.ContainsKey(message.GetType())) - foreach (var condition in messageTypeToConditionLookup[message.GetType()]) + { + List> conditionLookup; + if (messageTypeToConditionLookup.TryGetValue(message.GetType(), out conditionLookup)) + { + foreach (var condition in conditionLookup) + { result.Add(condition); + } + } + } - return result; + return result; } /// @@ -39,17 +46,24 @@ public IList> GetConditionsForMessage(object message) /// are to be published to a subscriber. public void AddConditionForSubscriptionToMessageType(Type messageType, Predicate condition) { - if (condition == null) - return; + if (condition == null) + { + return; + } - lock (locker) - { - if (!messageTypeToConditionLookup.ContainsKey(messageType)) - messageTypeToConditionLookup.Add(messageType, new List>()); + lock (locker) + { + List> conditionLookup; + if (!messageTypeToConditionLookup.TryGetValue(messageType, out conditionLookup)) + { + messageTypeToConditionLookup[messageType] = conditionLookup = new List>(); + } - if (!messageTypeToConditionLookup[messageType].Contains(condition)) - messageTypeToConditionLookup[messageType].Add(condition); - } + if (!conditionLookup.Contains(condition)) + { + conditionLookup.Add(condition); + } + } } private readonly IDictionary>> messageTypeToConditionLookup = new Dictionary>>(); diff --git a/src/NServiceBus.Core/Unicast/Transport/TransportReceiver.cs b/src/NServiceBus.Core/Unicast/Transport/TransportReceiver.cs index eba672c84d2..a554437049e 100644 --- a/src/NServiceBus.Core/Unicast/Transport/TransportReceiver.cs +++ b/src/NServiceBus.Core/Unicast/Transport/TransportReceiver.cs @@ -368,7 +368,7 @@ void ProcessMessage(TransportMessage message) exceptionFromMessageHandling.GetBaseException() as SerializationException; if (serializationException != null) { - Logger.Error("Failed to serialize message with ID: " + message.Id, serializationException); + Logger.Error("Failed to deserialize message with ID: " + message.Id, serializationException); message.RevertToOriginalBodyIfNeeded(); diff --git a/src/NServiceBus.Core/Unicast/UnicastBus.cs b/src/NServiceBus.Core/Unicast/UnicastBus.cs index 979fa23154c..efbb739c6b0 100644 --- a/src/NServiceBus.Core/Unicast/UnicastBus.cs +++ b/src/NServiceBus.Core/Unicast/UnicastBus.cs @@ -5,9 +5,9 @@ namespace NServiceBus.Unicast using System.Collections.Generic; using System.Linq; using System.Security.Principal; - using System.Text; using System.Threading.Tasks; using Audit; + using Hosting; using Licensing; using Logging; using MessageInterfaces; @@ -29,9 +29,32 @@ namespace NServiceBus.Unicast /// public class UnicastBus : IUnicastBus, IInMemoryOperations { + bool messageHandlingDisabled; + HostInformation hostInformation = HostInformation.CreateDefault(); - bool messageHandlingDisabled; + // HACK: Statics are bad, remove + internal static Guid HostIdForTransportMessageBecauseEverythingIsStaticsInTheConstructor; + + public UnicastBus() + { + HostIdForTransportMessageBecauseEverythingIsStaticsInTheConstructor = hostInformation.HostId; + } + + public HostInformation HostInformation + { + get { return hostInformation; } + set + { + if (value == null) + { + throw new ArgumentNullException(); + } + + HostIdForTransportMessageBecauseEverythingIsStaticsInTheConstructor = value.HostId; + hostInformation = value; + } + } /// /// Should be used by programmer, not administrator. @@ -57,11 +80,6 @@ public virtual ITransport Transport set { transport = value; - - transport.StartedMessageProcessing += TransportStartedMessageProcessing; - transport.TransportMessageReceived += TransportMessageReceived; - transport.FinishedMessageProcessing += TransportFinishedMessageProcessing; - transport.FailedMessageProcessing += TransportFailedMessageProcessing; } get { return transport; } } @@ -756,14 +774,16 @@ public IBus Start(Action startupAction) LicenseManager.PromptUserForLicenseIfTrialHasExpired(); if (started) + { return this; + } lock (startLocker) { if (started) + { return this; - - starting = true; + } Address.PreventChanges(); @@ -774,9 +794,12 @@ public IBus Start(Action startupAction) AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); - if (!DoNotStartTransport) { + transport.StartedMessageProcessing += TransportStartedMessageProcessing; + transport.TransportMessageReceived += TransportMessageReceived; + transport.FinishedMessageProcessing += TransportFinishedMessageProcessing; + transport.FailedMessageProcessing += TransportFailedMessageProcessing; transport.Start(InputAddress); } @@ -799,24 +822,24 @@ public IBus Start(Action startupAction) try { - Log.DebugFormat("Starting {0}.", name); toRun.Start(); Log.DebugFormat("Started {0}.", name); } catch (Exception ex) { - Log.ErrorFormat("{0} could not be started.", ex, name); - //don't rethrow so that thread doesn't die before log message is shown. + Configure.Instance.RaiseCriticalError(String.Format("{0} could not be started.", name), ex); } }, TaskCreationOptions.LongRunning)).ToArray(); return this; } - private void ExecuteIWantToRunAtStartupStopMethods() + void ExecuteIWantToRunAtStartupStopMethods() { if (thingsToRunAtStartup == null) + { return; + } //Ensure Start has been called on all thingsToRunAtStartup Log.DebugFormat("Ensuring IWantToRunAtStartup.Start has been called."); @@ -826,50 +849,32 @@ private void ExecuteIWantToRunAtStartupStopMethods() var mapTaskToThingsToRunAtStartup = new ConcurrentDictionary(); var tasks = thingsToRunAtStartup.Select(toRun => - { - var name = toRun.GetType().AssemblyQualifiedName; - - var task = new Task(() => - { - try - { - Log.DebugFormat("Stopping {0}.", name); - toRun.Stop(); - Log.DebugFormat("Stopped {0}.", name); - } - catch (Exception ex) - { - Log.ErrorFormat("{0} could not be stopped.", ex, name); - // no need to rethrow, closing the process anyway - } - }, TaskCreationOptions.LongRunning); - - mapTaskToThingsToRunAtStartup.TryAdd(task.Id, name); - - task.Start(); - - return task; - - }).ToArray(); - - // Wait for a period here otherwise the process may be killed too early! - var timeout = TimeSpan.FromSeconds(20); - if (Task.WaitAll(tasks, timeout)) { - return; - } + var name = toRun.GetType().AssemblyQualifiedName; - Log.WarnFormat("Not all IWantToRunWhenBusStartsAndStops.Stop methods were successfully called within {0}secs", timeout.Seconds); + var task = new Task(() => + { + try + { + toRun.Stop(); + Log.DebugFormat("Stopped {0}.", name); + } + catch (Exception ex) + { + Configure.Instance.RaiseCriticalError(String.Format("{0} could not be stopped.", name), ex); + } + }, TaskCreationOptions.LongRunning); - var sb = new StringBuilder(); - foreach (var task in tasks.Where(task => !task.IsCompleted)) - { - sb.AppendLine(mapTaskToThingsToRunAtStartup[task.Id]); - } + mapTaskToThingsToRunAtStartup.TryAdd(task.Id, name); - Log.WarnFormat("List of tasks that did not finish within {0}secs:\n{1}", timeout.Seconds, sb.ToString()); - } + task.Start(); + return task; + + }).ToArray(); + + Task.WaitAll(tasks); + } /// /// Allow disabling the unicast bus. @@ -955,11 +960,14 @@ void InnerShutdown() Log.Info("Initiating shutdown."); - transport.Stop(); - transport.StartedMessageProcessing -= TransportStartedMessageProcessing; - transport.TransportMessageReceived -= TransportMessageReceived; - transport.FinishedMessageProcessing -= TransportFinishedMessageProcessing; - transport.FailedMessageProcessing -= TransportFailedMessageProcessing; + if (!DoNotStartTransport) + { + transport.Stop(); + transport.StartedMessageProcessing -= TransportStartedMessageProcessing; + transport.TransportMessageReceived -= TransportMessageReceived; + transport.FinishedMessageProcessing -= TransportFinishedMessageProcessing; + transport.FailedMessageProcessing -= TransportFailedMessageProcessing; + } ExecuteIWantToRunAtStartupStopMethods(); @@ -990,6 +998,7 @@ public void Raise(Action messageConstructor) { Raise(CreateInstance(messageConstructor)); } + public void Raise(T @event) { var messageType = typeof(T); @@ -998,7 +1007,18 @@ public void Raise(T @event) var logicalMessage = LogicalMessageFactory.Create(messageType, @event); - PipelineFactory.InvokeLogicalMessagePipeline(logicalMessage); + if (PipelineFactory.CurrentContext is RootContext) + { + using (var childBuilder = Builder.CreateChildBuilder()) + { + PipelineFactory.CurrentContext.Set(childBuilder); + PipelineFactory.InvokeLogicalMessagePipeline(logicalMessage); + } + } + else + { + PipelineFactory.InvokeLogicalMessagePipeline(logicalMessage); + } } [ObsoleteEx(RemoveInVersion = "5.0", Message = "In 5.0.0 we'll require inmemory messages to be picked up by the conventions")] @@ -1014,13 +1034,21 @@ void EnsureMessageIsRegistered(Type messageType) registry.RegisterMessageType(messageType); } + [ObsoleteEx(RemoveInVersion = "5.0")] + void AddBackwardsCompatibilityHeaders(TransportMessage incomingMessage) + { + incomingMessage.Headers["NServiceBus.ProcessingMachine"] = RuntimeEnvironment.MachineName; + } + void TransportStartedMessageProcessing(object sender, StartedMessageProcessingEventArgs e) { var incomingMessage = e.Message; incomingMessage.Headers[Headers.ProcessingEndpoint] = Configure.EndpointName; - incomingMessage.Headers[Headers.ProcessingMachine] = RuntimeEnvironment.MachineName; + incomingMessage.Headers[Headers.HostId] = HostInformation.HostId.ToString("N"); + incomingMessage.Headers[Headers.HostDisplayName] = HostInformation.DisplayName; + AddBackwardsCompatibilityHeaders(incomingMessage); PipelineFactory.PreparePhysicalMessagePipelineContext(incomingMessage, messageHandlingDisabled); #pragma warning disable 0618 @@ -1096,15 +1124,6 @@ List
GetAddressForMessageType(Type messageType) return destination; } - /// - /// Throws an exception if the bus hasn't begun the startup process. - /// - protected void AssertBusIsStarted() - { - if (starting == false) - throw new InvalidOperationException("The bus is not started yet, call Bus.Start() before attempting to use the bus."); - } - Address inputAddress; @@ -1137,7 +1156,6 @@ TransportMessage MessageBeingProcessed } volatile bool started; - volatile bool starting; object startLocker = new object(); static ILog Log = LogManager.GetLogger(typeof(UnicastBus)); @@ -1156,11 +1174,11 @@ TransportMessage MessageBeingProcessed //we need to not inject since at least Autofac doesn't seem to inject internal properties - PipelineFactory PipelineFactory + PipelineExecutor PipelineFactory { get { - return Builder.Build(); + return Builder.Build(); } } diff --git a/src/NServiceBus.Core/UnitOfWork/UnitOfWorkBehavior.cs b/src/NServiceBus.Core/UnitOfWork/UnitOfWorkBehavior.cs index 5c936523647..c39e52161b8 100644 --- a/src/NServiceBus.Core/UnitOfWork/UnitOfWorkBehavior.cs +++ b/src/NServiceBus.Core/UnitOfWork/UnitOfWorkBehavior.cs @@ -2,10 +2,14 @@ { using System; using System.Collections.Generic; + using System.ComponentModel; using Pipeline; using Pipeline.Contexts; - class UnitOfWorkBehavior : IBehavior + + [Obsolete("This is a prototype API. May change in minor version releases.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public class UnitOfWorkBehavior : IBehavior { public void Invoke(ReceivePhysicalMessageContext context, Action next) { diff --git a/src/NServiceBus.Core/Utils/DeterministicGuid.cs b/src/NServiceBus.Core/Utils/DeterministicGuid.cs new file mode 100644 index 00000000000..e062b2b9a17 --- /dev/null +++ b/src/NServiceBus.Core/Utils/DeterministicGuid.cs @@ -0,0 +1,21 @@ +namespace NServiceBus.Utils +{ + using System; + using System.Security.Cryptography; + using System.Text; + + static class DeterministicGuid + { + public static Guid Create(params object[] data) + { + // use MD5 hash to get a 16-byte hash of the string + using (var provider = new MD5CryptoServiceProvider()) + { + var inputBytes = Encoding.Default.GetBytes(String.Concat(data)); + var hashBytes = provider.ComputeHash(inputBytes); + // generate a guid from the hash: + return new Guid(hashBytes); + } + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core/Utils/Reflection/ExtensionMethods.cs b/src/NServiceBus.Core/Utils/Reflection/ExtensionMethods.cs index ae508464f08..3ea6fac012a 100644 --- a/src/NServiceBus.Core/Utils/Reflection/ExtensionMethods.cs +++ b/src/NServiceBus.Core/Utils/Reflection/ExtensionMethods.cs @@ -76,8 +76,13 @@ public static bool IsSimpleType(this Type type) public static string SerializationFriendlyName(this Type t) { lock(TypeToNameLookup) - if (TypeToNameLookup.ContainsKey(t)) - return TypeToNameLookup[t]; + { + string typeName; + if (TypeToNameLookup.TryGetValue(t, out typeName)) + { + return typeName; + } + } var index = t.Name.IndexOf('`'); if (index >= 0) diff --git a/src/NServiceBus.Distributor.MSMQ/NServiceBus.Distributor.MSMQ.csproj b/src/NServiceBus.Distributor.MSMQ/NServiceBus.Distributor.MSMQ.csproj index f62034c44ca..b5a65bc63da 100644 --- a/src/NServiceBus.Distributor.MSMQ/NServiceBus.Distributor.MSMQ.csproj +++ b/src/NServiceBus.Distributor.MSMQ/NServiceBus.Distributor.MSMQ.csproj @@ -13,6 +13,7 @@ 512 true ..\NServiceBus.snk + ..\ true diff --git a/src/NServiceBus.Distributor.MSMQ/Properties/AssemblyInfo.cs b/src/NServiceBus.Distributor.MSMQ/Properties/AssemblyInfo.cs index f707b212840..4100edc8c29 100644 --- a/src/NServiceBus.Distributor.MSMQ/Properties/AssemblyInfo.cs +++ b/src/NServiceBus.Distributor.MSMQ/Properties/AssemblyInfo.cs @@ -4,9 +4,8 @@ [assembly: AssemblyTitle("NServiceBus Distributor for MSMQ")] [assembly: AssemblyDescription("Implementation of NServiceBus Distributor for MSMQ")] -[assembly: AssemblyCopyright("Copyright 2010-2013 NServiceBus. All rights reserved")] +[assembly: AssemblyCopyright("Copyright 2010-2014 NServiceBus. All rights reserved")] [assembly: AssemblyProduct("NServiceBus")] [assembly: AssemblyCompany("NServiceBus Ltd.")] -[assembly: AssemblyConfiguration("release")] [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] \ No newline at end of file diff --git a/src/NServiceBus.Hosting.Tests/NServiceBus.Hosting.Tests.csproj b/src/NServiceBus.Hosting.Tests/NServiceBus.Hosting.Tests.csproj index c4e45ea997e..0c2669054b4 100644 --- a/src/NServiceBus.Hosting.Tests/NServiceBus.Hosting.Tests.csproj +++ b/src/NServiceBus.Hosting.Tests/NServiceBus.Hosting.Tests.csproj @@ -12,7 +12,7 @@ NServiceBus.Hosting.Tests v4.0 512 - + ..\ true ..\NServiceBus.snk @@ -73,7 +73,7 @@ {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus {85E813C0-4A94-4946-8B1F-DE1E39AA7D11} diff --git a/src/NServiceBus.Hosting.Windows/NServiceBus.Hosting.Windows.csproj b/src/NServiceBus.Hosting.Windows/NServiceBus.Hosting.Windows.csproj index 306de92a5c4..2e142ffdde0 100644 --- a/src/NServiceBus.Hosting.Windows/NServiceBus.Hosting.Windows.csproj +++ b/src/NServiceBus.Hosting.Windows/NServiceBus.Hosting.Windows.csproj @@ -14,6 +14,7 @@ true ..\NServiceBus.snk ..\packages\Fody + ..\ NServiceBus.Host @@ -112,7 +113,6 @@ - @@ -152,7 +152,7 @@ {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus @@ -167,10 +167,10 @@ - + - + diff --git a/src/NServiceBus.Hosting.Windows/Options.cs b/src/NServiceBus.Hosting.Windows/Options.cs index 77129395c3d..a74bbf0f646 100644 --- a/src/NServiceBus.Hosting.Windows/Options.cs +++ b/src/NServiceBus.Hosting.Windows/Options.cs @@ -812,10 +812,9 @@ protected virtual bool Parse(string argument, OptionContext c) if (!GetOptionParts(argument, out f, out n, out s, out v)) return false; - Option p; if (Contains(n)) { - p = this[n]; + var p = this[n]; c.OptionName = f + n; c.Option = p; switch (p.OptionValueType) @@ -864,12 +863,11 @@ private void ParseValue(string option, OptionContext c) private bool ParseBool(string option, string n, OptionContext c) { - Option p; string rn; if (n.Length >= 1 && (n[n.Length - 1] == '+' || n[n.Length - 1] == '-') && Contains((rn = n.Substring(0, n.Length - 1)))) { - p = this[rn]; + var p = this[rn]; var v = n[n.Length - 1] == '+' ? option : null; c.OptionName = option; c.Option = p; @@ -978,7 +976,7 @@ bool WriteOptionPrototype(TextWriter o, Option p, ref int written) i < names.Length; i = GetNextOptionIndex(names, i + 1)) { Write(o, ref written, ", "); - Write(o, ref written, names[i].Length == 1 ? "-" : "-"); + Write(o, ref written, names[i].Length == 1 ? "-" : "--"); Write(o, ref written, names[i]); } diff --git a/src/NServiceBus.Hosting.Windows/Profiles/Handlers/IntegrationProfileHandler.cs b/src/NServiceBus.Hosting.Windows/Profiles/Handlers/IntegrationProfileHandler.cs index c82f3800481..32f9fca403b 100644 --- a/src/NServiceBus.Hosting.Windows/Profiles/Handlers/IntegrationProfileHandler.cs +++ b/src/NServiceBus.Hosting.Windows/Profiles/Handlers/IntegrationProfileHandler.cs @@ -1,5 +1,6 @@ namespace NServiceBus.Hosting.Windows.Profiles.Handlers { + using Config; using Faults; using Hosting.Profiles; diff --git a/src/NServiceBus.Hosting.Windows/Profiles/Handlers/LiteProfileHandler.cs b/src/NServiceBus.Hosting.Windows/Profiles/Handlers/LiteProfileHandler.cs index d5e49bc7bff..43cfebaebe1 100644 --- a/src/NServiceBus.Hosting.Windows/Profiles/Handlers/LiteProfileHandler.cs +++ b/src/NServiceBus.Hosting.Windows/Profiles/Handlers/LiteProfileHandler.cs @@ -1,5 +1,6 @@ namespace NServiceBus.Hosting.Windows.Profiles.Handlers { + using Config; using Faults; using Hosting.Profiles; using Persistence.InMemory; diff --git a/src/NServiceBus.Hosting.Windows/Properties/AssemblyInfo.cs b/src/NServiceBus.Hosting.Windows/Properties/AssemblyInfo.cs index 3b0cefa9ff0..ce659333656 100644 --- a/src/NServiceBus.Hosting.Windows/Properties/AssemblyInfo.cs +++ b/src/NServiceBus.Hosting.Windows/Properties/AssemblyInfo.cs @@ -4,10 +4,9 @@ [assembly: AssemblyTitle("Generic Host Process for NServiceBus")] [assembly: AssemblyDescription("Functionality for generically hosting nServiceBus processes.")] -[assembly: AssemblyCopyright("Copyright 2010-2013 NServiceBus. All rights reserved")] +[assembly: AssemblyCopyright("Copyright 2010-2014 NServiceBus. All rights reserved")] [assembly: AssemblyProduct("NServiceBus")] [assembly: AssemblyCompany("NServiceBus Ltd.")] -[assembly: AssemblyConfiguration("release")] [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] diff --git a/src/NServiceBus.Hosting.Windows/WindowsHost.cs b/src/NServiceBus.Hosting.Windows/WindowsHost.cs index 0093d243bb3..2a42239e876 100644 --- a/src/NServiceBus.Hosting.Windows/WindowsHost.cs +++ b/src/NServiceBus.Hosting.Windows/WindowsHost.cs @@ -4,7 +4,7 @@ namespace NServiceBus.Hosting.Windows using System.Collections.Generic; using System.Diagnostics; using System.Threading; - using Profiles.Handlers; + using Config; /// /// A windows implementation of the NServiceBus hosting solution diff --git a/src/NServiceBus.Logging.Tests/NServiceBus.Logging.Tests.csproj b/src/NServiceBus.Logging.Tests/NServiceBus.Logging.Tests.csproj index 84ee9e5afc1..a62f2ea6991 100644 --- a/src/NServiceBus.Logging.Tests/NServiceBus.Logging.Tests.csproj +++ b/src/NServiceBus.Logging.Tests/NServiceBus.Logging.Tests.csproj @@ -12,6 +12,7 @@ NServiceBus.Logging.Tests v4.0 512 + ..\ true @@ -64,7 +65,7 @@ {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus {dd48b2d0-e996-412d-9157-821ed8b17a9d} diff --git a/src/NServiceBus.PerformanceTests/Encryption/EncryptionTestMessage.cs b/src/NServiceBus.PerformanceTests/Encryption/EncryptionTestMessage.cs index 5a2dc270587..4e33b02ac8a 100644 --- a/src/NServiceBus.PerformanceTests/Encryption/EncryptionTestMessage.cs +++ b/src/NServiceBus.PerformanceTests/Encryption/EncryptionTestMessage.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using NServiceBus; +// ReSharper disable UnusedAutoPropertyAccessor.Global namespace Runner.Encryption { public class EncryptionTestMessage : MessageBase @@ -17,3 +18,5 @@ public class EncryptionTestMessage : MessageBase public byte[] LargeByteArray { get; set; } } } + +// ReSharper restore UnusedAutoPropertyAccessor.Global \ No newline at end of file diff --git a/src/NServiceBus.PerformanceTests/NServiceBus.PerformanceTests.csproj b/src/NServiceBus.PerformanceTests/NServiceBus.PerformanceTests.csproj index 7e4e186545a..6dcced2fb5c 100644 --- a/src/NServiceBus.PerformanceTests/NServiceBus.PerformanceTests.csproj +++ b/src/NServiceBus.PerformanceTests/NServiceBus.PerformanceTests.csproj @@ -1,6 +1,5 @@  - Debug AnyCPU @@ -50,7 +49,6 @@ - @@ -63,6 +61,9 @@ + + + @@ -75,8 +76,10 @@ + + @@ -90,19 +93,19 @@ + + + - {dd48b2d0-e996-412d-9157-821ed8b17a9d} + {DD48B2D0-E996-412D-9157-821ED8B17A9D} NServiceBus.Core - {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + {73867D40-8CBB-48E9-BFFA-12BBDD48A341} + NServiceBus - - - \ No newline at end of file diff --git a/src/NServiceBus.PerformanceTests/Program.cs b/src/NServiceBus.PerformanceTests/Program.cs index b14c8e9ea55..383da37b973 100644 --- a/src/NServiceBus.PerformanceTests/Program.cs +++ b/src/NServiceBus.PerformanceTests/Program.cs @@ -10,14 +10,30 @@ using NServiceBus; using NServiceBus.Features; using Encryption; + using NServiceBus.Unicast.Transport; using Saga; using System; - + class Program { static void Main(string[] args) { - var numberOfThreads = int.Parse(args[0]); + TransportConnectionString.Override(() => "deadLetter=false;journal=false"); + + var testCaseToRun = args[0]; + + int numberOfThreads; + + if (!int.TryParse(testCaseToRun, out numberOfThreads)) + { + var testCase = TestCase.Load(testCaseToRun,args); + + testCase.Run(); + testCase.DumpSettings(); + + return; + } + var volatileMode = (args[4].ToLower() == "volatile"); var suppressDTC = (args[4].ToLower() == "suppressdtc"); var twoPhaseCommit = (args[4].ToLower() == "twophasecommit"); @@ -196,9 +212,9 @@ static TimeSpan SeedInputQueue(int numberOfMessages, string inputQueue, int numb } public const string EncryptedBase64Value = "encrypted value"; - public const string MySecretMessage = "A secret"; + const string MySecretMessage = "A secret"; - private static MessageBase CreateMessage(bool encryption) + static MessageBase CreateMessage(bool encryption) { if (encryption) { diff --git a/src/NServiceBus.PerformanceTests/PubSub/PubSubTestCase.cs b/src/NServiceBus.PerformanceTests/PubSub/PubSubTestCase.cs new file mode 100644 index 00000000000..61142b42ef9 --- /dev/null +++ b/src/NServiceBus.PerformanceTests/PubSub/PubSubTestCase.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using System.Transactions; +using NServiceBus; +using NServiceBus.Features; +using NServiceBus.Transports.Msmq; +using NServiceBus.Transports.Msmq.Config; +using NServiceBus.Unicast.Subscriptions; +using NServiceBus.Unicast.Subscriptions.MessageDrivenSubscriptions; +using RavenTestMessages; +using Runner; + +public class PubSubTestCase : TestCase +{ + int GetNumberOfSubscribers() + { + int value; + if (!int.TryParse(GetParameterValue("numberofsubscribers"), out value)) + { + return 10; + } + return value; + } + + string GetStorageType() + { + var value = GetParameterValue("storage"); + + if (string.IsNullOrEmpty(value)) + { + return "raven"; + } + return value.ToLower(); + } + + + public override void Run() + { + TransportConfigOverride.MaximumConcurrencyLevel = NumberOfThreads; + + Feature.Disable(); + + Configure.Transactions.Enable(); + + var config = Configure.With() + .DefineEndpointName("PubSubPerformanceTest") + .DefaultBuilder() + .UseTransport() + .InMemoryFaultManagement(); + + switch (GetStorageType()) + { + case "raven": + config.RavenSubscriptionStorage(); + break; + case "inmemory": + config.InMemorySubscriptionStorage(); + break; + case "msmq": + config.MsmqSubscriptionStorage(); + break; + } + + using (var bus = config.UnicastBus() + .CreateBus()) + { + + + Configure.Instance.ForInstallationOn().Install(); + + var subscriptionStorage = Configure.Instance.Builder.Build(); + + var testEventMessage = new MessageType(typeof(RavenTestEvent)); + + + subscriptionStorage.Init(); + + + var creator = new MsmqQueueCreator + { + Settings = new MsmqSettings { UseTransactionalQueues = true } + }; + + for (var i = 0; i < GetNumberOfSubscribers(); i++) + { + var subscriberAddress = Address.Parse("PubSubPerformanceTest.Subscriber" + i); + creator.CreateQueueIfNecessary(subscriberAddress, null); + + using (var tx = new TransactionScope()) + { + subscriptionStorage.Subscribe(subscriberAddress, new List + { + testEventMessage + }); + + tx.Complete(); + } + } + + Parallel.For( + 0, + NumberMessages, + new ParallelOptions { MaxDegreeOfParallelism = NumberOfThreads }, + x => bus.SendLocal(new PerformRavenPublish())); + + + Statistics.StartTime = DateTime.Now; + bus.Start(); + + while (Interlocked.Read(ref Statistics.NumberOfMessages) < NumberMessages) + Thread.Sleep(1000); + + + Statistics.Dump(); + } + + } +} + +class PublishRavenEventHandler : IHandleMessages +{ + public IBus Bus { get; set; } + public void Handle(PerformRavenPublish message) + { + Bus.Publish(); + } +} + +namespace RavenTestMessages +{ + public class PerformRavenPublish : IMessage + { + } + + public class RavenTestEvent : IEvent + { + } +} diff --git a/src/NServiceBus.PerformanceTests/PubSub/RavenSubscriptionStorageTestCase.cs b/src/NServiceBus.PerformanceTests/PubSub/RavenSubscriptionStorageTestCase.cs new file mode 100644 index 00000000000..42eaa32e557 --- /dev/null +++ b/src/NServiceBus.PerformanceTests/PubSub/RavenSubscriptionStorageTestCase.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; +using System.Transactions; +using NServiceBus; +using NServiceBus.Persistence.Raven; +using NServiceBus.Persistence.Raven.SubscriptionStorage; +using NServiceBus.Unicast.Subscriptions; +using NServiceBus.Unicast.Subscriptions.MessageDrivenSubscriptions; +using Raven.Client.Document; + +public class RavenSubscriptionStorageTestCase : TestCase +{ + int NumberOfSubscribers + { + get + { + return int.Parse(parameters["numberofsubscribers"]); + } + } + + + public override void Run() + { + using (var store = new DocumentStore()) + { + store.Url = "http://localhost:8080"; + store.Initialize(); + + var ravenStorage = new RavenSubscriptionStorage(new StoreAccessor(store)); + + ravenStorage.Init(); + + var subscriptionStorage = (ISubscriptionStorage) ravenStorage; + var testEventMessage = new MessageType(typeof(TestEvent)); + + for (var i = 0; i < NumberOfSubscribers; i++) + { + subscriptionStorage.Subscribe(Address.Parse("endpoint" + i), new List + { + testEventMessage + }); + } + + var sw = new Stopwatch(); + + + sw.Start(); + Parallel.For( + 0, + NumberMessages, + new ParallelOptions { MaxDegreeOfParallelism = NumberOfThreads }, + x => + { + using (var tx = new TransactionScope()) + { + subscriptionStorage.GetSubscriberAddressesForMessage(new[] { new MessageType(typeof(TestEvent)) }); + + tx.Complete(); + } + }); + sw.Stop(); + + var elapsedMS = sw.ElapsedMilliseconds; + + Console.Out.WriteLine("Average (ms): {0} - Total:{1}", NumberMessages / elapsedMS, elapsedMS); + + } + } +} + +public class TestEvent +{ +} \ No newline at end of file diff --git a/src/NServiceBus.PerformanceTests/PubSub/TestCase.cs b/src/NServiceBus.PerformanceTests/PubSub/TestCase.cs new file mode 100644 index 00000000000..91fc5532027 --- /dev/null +++ b/src/NServiceBus.PerformanceTests/PubSub/TestCase.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +public abstract class TestCase +{ + + protected int NumberOfThreads + { + get + { + int value; + + if (!int.TryParse(GetParameterValue("numberofthreads"), out value)) + { + return 10; + } + + return value; + } + } + + protected int NumberMessages + { + get + { + int value; + + if (!int.TryParse(GetParameterValue("numberofmessages"), out value)) + { + return 10000; + } + + return value; + } + } + + protected string GetParameterValue(string key) + { + string value; + + if (!parameters.TryGetValue(key, out value)) + { + return null; + } + + return value; + + } + + + protected Dictionary parameters = new Dictionary(); + + void WithParameters(Dictionary testCaseParameters) + { + parameters = testCaseParameters; + } + + + public abstract void Run(); + + public static TestCase Load(string testCaseToRun, IEnumerable args) + { + var typeName = testCaseToRun; + + if (!testCaseToRun.Contains("TestCase")) + { + typeName += "TestCase"; + } + var testCase = (TestCase)Activator.CreateInstance(Type.GetType(typeName)); + + var parameters = args.Where(arg => arg.Contains("=")).Select(arg => new KeyValuePair(arg.Split('=').First().ToLower(), arg.Split('=').Last())) + .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + + testCase.WithParameters(parameters); + + return testCase; + } + + public void DumpSettings() + { + var settings = GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance).Select(pi => new + { + Name = pi.Name, + Value = pi.GetValue(this, null) + }).ToList(); + + Console.Out.WriteLine("Settings: {0}",string.Join(" ",settings.Select(s=>string.Format("{0}={1}",s.Name,s.Value)))); + } + +} \ No newline at end of file diff --git a/src/NServiceBus.PerformanceTests/TestSuites/PubSub-Raven.ps1 b/src/NServiceBus.PerformanceTests/TestSuites/PubSub-Raven.ps1 new file mode 100644 index 00000000000..bbe260a9fca --- /dev/null +++ b/src/NServiceBus.PerformanceTests/TestSuites/PubSub-Raven.ps1 @@ -0,0 +1,27 @@ +. .\TestSupport.ps1 + +..\.\bin\debug\Runner.exe PubSub numberofsubscribers=1 numberofmessages=10000 numberofthreads=10 storage=raven + +Cleanup + +..\.\bin\debug\Runner.exe PubSub numberofsubscribers=2 numberofmessages=10000 numberofthreads=10 storage=raven + +Cleanup + +..\.\bin\debug\Runner.exe PubSub numberofsubscribers=5 numberofmessages=10000 numberofthreads=10 storage=raven + +Cleanup + +..\.\bin\debug\Runner.exe PubSub numberofsubscribers=10 numberofmessages=10000 numberofthreads=10 storage=raven + +Cleanup + +..\.\bin\debug\Runner.exe PubSub numberofsubscribers=25 numberofmessages=10000 numberofthreads=10 storage=raven + +Cleanup + +..\.\bin\debug\Runner.exe PubSub numberofsubscribers=50 numberofmessages=10000 numberofthreads=10 storage=raven + +Cleanup + +..\.\bin\debug\Runner.exe PubSub numberofsubscribers=100 numberofmessages=10000 numberofthreads=10 storage=raven \ No newline at end of file diff --git a/src/NServiceBus.PerformanceTests/TestSuites/PubSub.ps1 b/src/NServiceBus.PerformanceTests/TestSuites/PubSub.ps1 new file mode 100644 index 00000000000..7ecba26a879 --- /dev/null +++ b/src/NServiceBus.PerformanceTests/TestSuites/PubSub.ps1 @@ -0,0 +1,16 @@ +. .\TestSupport.ps1 + +Cleanup + +..\.\bin\release\Runner.exe PubSub numberofsubscribers=10 numberofmessages=10000 numberofthreads=10 storage=msmq + +Cleanup + + +..\.\bin\release\Runner.exe PubSub numberofsubscribers=10 numberofmessages=10000 numberofthreads=10 storage=inmemory + +Cleanup + +..\.\bin\release\Runner.exe PubSub numberofsubscribers=10 numberofmessages=10000 numberofthreads=10 storage=raven + +Cleanup diff --git a/src/NServiceBus.PerformanceTests/TestSuites/TestSupport.ps1 b/src/NServiceBus.PerformanceTests/TestSuites/TestSupport.ps1 index 264ebdfc7ae..a5d71b5ee8b 100644 --- a/src/NServiceBus.PerformanceTests/TestSuites/TestSupport.ps1 +++ b/src/NServiceBus.PerformanceTests/TestSuites/TestSupport.ps1 @@ -19,7 +19,7 @@ { - ..\.\bin\debug\Runner.exe $numThreads $numMessages $serializationFormat $transport $mode $messagemode $persistence $concurrency + ..\.\bin\release\Runner.exe $numThreads $numMessages $serializationFormat $transport $mode $messagemode $persistence $concurrency } diff --git a/src/NServiceBus.PerformanceTests/TransportConfigOverride.cs b/src/NServiceBus.PerformanceTests/TransportConfigOverride.cs index a36f826efcc..a1d4bbaf54e 100644 --- a/src/NServiceBus.PerformanceTests/TransportConfigOverride.cs +++ b/src/NServiceBus.PerformanceTests/TransportConfigOverride.cs @@ -16,4 +16,5 @@ public TransportConfig GetConfiguration() }; } } + } \ No newline at end of file diff --git a/src/NServiceBus.SagaPersisters.InMemory.Tests/NServiceBus.SagaPersisters.InMemory.Tests.csproj b/src/NServiceBus.SagaPersisters.InMemory.Tests/NServiceBus.SagaPersisters.InMemory.Tests.csproj index 021e93ecd79..34735f0c390 100644 --- a/src/NServiceBus.SagaPersisters.InMemory.Tests/NServiceBus.SagaPersisters.InMemory.Tests.csproj +++ b/src/NServiceBus.SagaPersisters.InMemory.Tests/NServiceBus.SagaPersisters.InMemory.Tests.csproj @@ -12,6 +12,7 @@ NServiceBus.SagaPersisters.InMemory.Tests v4.0 512 + ..\ true @@ -69,7 +70,7 @@ {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus diff --git a/src/NServiceBus.SagaPersisters.InMemory.Tests/Properties/AssemblyInfo.cs b/src/NServiceBus.SagaPersisters.InMemory.Tests/Properties/AssemblyInfo.cs index 4cc60b663f4..35d1c8d8f96 100644 --- a/src/NServiceBus.SagaPersisters.InMemory.Tests/Properties/AssemblyInfo.cs +++ b/src/NServiceBus.SagaPersisters.InMemory.Tests/Properties/AssemblyInfo.cs @@ -4,10 +4,9 @@ [assembly: AssemblyTitle("NServiceBus.SagaPersisters.InMemory.Tests")] [assembly: AssemblyDescription("")] -[assembly: AssemblyCopyright("Copyright 2010-2013 NServiceBus. All rights reserved")] +[assembly: AssemblyCopyright("Copyright 2010-2014 NServiceBus. All rights reserved")] [assembly: AssemblyProduct("NServiceBus")] [assembly: AssemblyCompany("NServiceBus Ltd.")] -[assembly: AssemblyConfiguration("release")] [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] diff --git a/src/NServiceBus.Serializers.XML.XsdGenerator/NServiceBus.Serializers.XML.XsdGenerator.csproj b/src/NServiceBus.Serializers.XML.XsdGenerator/NServiceBus.Serializers.XML.XsdGenerator.csproj index f1344b6f416..dcae3f3b1cd 100644 --- a/src/NServiceBus.Serializers.XML.XsdGenerator/NServiceBus.Serializers.XML.XsdGenerator.csproj +++ b/src/NServiceBus.Serializers.XML.XsdGenerator/NServiceBus.Serializers.XML.XsdGenerator.csproj @@ -13,6 +13,7 @@ v4.0 true ..\NServiceBus.snk + ..\ true @@ -79,7 +80,7 @@ {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus diff --git a/src/NServiceBus.Serializers.XML.XsdGenerator/Properties/AssemblyInfo.cs b/src/NServiceBus.Serializers.XML.XsdGenerator/Properties/AssemblyInfo.cs index ecbbae78181..09f318cf9bb 100644 --- a/src/NServiceBus.Serializers.XML.XsdGenerator/Properties/AssemblyInfo.cs +++ b/src/NServiceBus.Serializers.XML.XsdGenerator/Properties/AssemblyInfo.cs @@ -4,10 +4,9 @@ [assembly: AssemblyTitle("NServiceBus XSD Generator")] [assembly: AssemblyDescription("XSD file generator for interface-based message schemas.")] -[assembly: AssemblyCopyright("Copyright 2010-2013 NServiceBus. All rights reserved")] +[assembly: AssemblyCopyright("Copyright 2010-2014 NServiceBus. All rights reserved")] [assembly: AssemblyProduct("NServiceBus")] [assembly: AssemblyCompany("NServiceBus Ltd.")] -[assembly: AssemblyConfiguration("release")] [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] diff --git a/src/NServiceBus.Testing.Tests/InvocationTests.cs b/src/NServiceBus.Testing.Tests/InvocationTests.cs index dea582b18eb..42dfb709514 100644 --- a/src/NServiceBus.Testing.Tests/InvocationTests.cs +++ b/src/NServiceBus.Testing.Tests/InvocationTests.cs @@ -1,5 +1,6 @@ namespace NServiceBus.Testing.Tests { + using System; using NUnit.Framework; [TestFixture] @@ -159,6 +160,25 @@ public void NotSendToSitesBasicNegativeCheck() exp.Validate(i); } + + [Test] + public void DeferMessageBasicPositive() + { + var timespan = TimeSpan.FromMinutes(10); + var i = new DeferMessageInvocation { Messages = new object[] { new MessageA() }, Value = timespan }; + var exp = new ExpectedDeferMessageInvocation { Check = (m, v) => v == timespan }; + + exp.Validate(i); + } + + [Test] + public void DeferMessageBasicNegative() + { + var i = new DeferMessageInvocation { Messages = new object[] { new MessageA() }, Value = TimeSpan.FromMinutes(10) }; + var exp = new ExpectedNotDeferMessageInvocation { Check = (m, v) => false }; + + exp.Validate(i); + } } public class MessageA diff --git a/src/NServiceBus.Testing.Tests/NServiceBus.Testing.Tests.csproj b/src/NServiceBus.Testing.Tests/NServiceBus.Testing.Tests.csproj index 1cb1feb3dc6..51ad90c0f44 100644 --- a/src/NServiceBus.Testing.Tests/NServiceBus.Testing.Tests.csproj +++ b/src/NServiceBus.Testing.Tests/NServiceBus.Testing.Tests.csproj @@ -12,6 +12,7 @@ NServiceBus.Testing.Tests v4.0 512 + ..\ true @@ -59,7 +60,7 @@ {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus diff --git a/src/NServiceBus.Testing.Tests/TestHandlerFixture.cs b/src/NServiceBus.Testing.Tests/TestHandlerFixture.cs index 55090600ffa..5ead74d7b62 100644 --- a/src/NServiceBus.Testing.Tests/TestHandlerFixture.cs +++ b/src/NServiceBus.Testing.Tests/TestHandlerFixture.cs @@ -54,6 +54,86 @@ public void ShouldAssertSendToSitesWasNotCalled() .OnMessage(); } + [Test] + public void ShouldAssertDeferWasCalledWithTimeSpan() + { + var timespan = TimeSpan.FromMinutes(10); + Test.Handler() + .WithExternalDependencies(h => h.Defer = timespan) + .ExpectDefer((m, t) => t == timespan) + .OnMessage(); + } + + [Test] + public void ShouldAssertDeferWasCalledWithDateTime() + { + var datetime = DateTime.Now; + Test.Handler() + .WithExternalDependencies(h => h.Defer = datetime) + .ExpectDefer((m, t) => t == datetime) + .OnMessage(); + } + + [Test] + [ExpectedException] + public void ShouldFailAssertingDeferWasCalledWithTimeSpan() + { + var timespan = TimeSpan.FromMinutes(10); + Test.Handler() + .ExpectDefer((m, t) => t == timespan) + .OnMessage(); + } + + [Test] + [ExpectedException] + public void ShouldFailAssertingDeferWasCalledWithDateTime() + { + var datetime = DateTime.Now; + Test.Handler() + .ExpectDefer((m, t) => t == datetime) + .OnMessage(); + } + + [Test] + public void ShouldAssertDeferWasNotCalledWithTimeSpan() + { + var timespan = TimeSpan.FromMinutes(10); + Test.Handler() + .ExpectNotDefer((m, t) => t == timespan) + .OnMessage(); + } + + [Test] + public void ShouldAssertDeferWasNotCalledWithDateTime() + { + var datetime = DateTime.Now; + Test.Handler() + .ExpectNotDefer((m, t) => t == datetime) + .OnMessage(); + } + + [Test] + [ExpectedException] + public void ShouldFailAssertingDeferWasNotCalledWithTimeSpan() + { + var timespan = TimeSpan.FromMinutes(10); + Test.Handler() + .WithExternalDependencies(h => h.Defer = timespan) + .ExpectNotDefer((m, t) => t == timespan) + .OnMessage(); + } + + [Test] + [ExpectedException] + public void ShouldFailAssertingDeferWasNotCalledWithDateTime() + { + var datetime = DateTime.Now; + Test.Handler() + .WithExternalDependencies(h => h.Defer = datetime) + .ExpectNotDefer((m, t) => t == datetime) + .OnMessage(); + } + [Test] [ExpectedException] public void ShouldFailAssertingHandleCurrentMessageLaterWasCalled() @@ -350,6 +430,28 @@ public class Incoming : IMessage { } + public class DeferingTimeSpanHandler : IHandleMessages + { + public IBus Bus { get; set; } + public TimeSpan Defer { get; set; } + + public void Handle(TestMessage message) + { + Bus.Defer(Defer, message); + } + } + + public class DeferingDateTimeHandler : IHandleMessages + { + public IBus Bus { get; set; } + public DateTime Defer { get; set; } + + public void Handle(TestMessage message) + { + Bus.Defer(Defer, message); + } + } + public class PublishingManyHandler : IHandleMessages { public void Handle(Incoming message) diff --git a/src/NServiceBus.Testing/Handler.cs b/src/NServiceBus.Testing/Handler.cs index bb0602d07d2..f7b77b0c17a 100644 --- a/src/NServiceBus.Testing/Handler.cs +++ b/src/NServiceBus.Testing/Handler.cs @@ -192,6 +192,42 @@ public Handler ExpectNotSendToSites(Func + /// Check that the handler defers a message of the given type + /// + public Handler ExpectDefer(Func check) + { + expectedInvocations.Add(new ExpectedDeferMessageInvocation { Check = check }); + return this; + } + + /// + /// Check that the handler defers a message of the given type + /// + public Handler ExpectDefer(Func check) + { + expectedInvocations.Add(new ExpectedDeferMessageInvocation { Check = check }); + return this; + } + + /// + /// Check that the handler doesn't defer a message of the given type + /// + public Handler ExpectNotDefer(Func check) + { + expectedInvocations.Add(new ExpectedNotDeferMessageInvocation { Check = check }); + return this; + } + + /// + /// Check that the handler doesn't defer a message of the given type + /// + public Handler ExpectNotDefer(Func check) + { + expectedInvocations.Add(new ExpectedNotDeferMessageInvocation { Check = check }); + return this; + } + /// /// Activates the test that has been set up passing in the given message. /// diff --git a/src/NServiceBus.Testing/Invocations.cs b/src/NServiceBus.Testing/Invocations.cs index d3f7f7a879d..78ead619ab5 100644 --- a/src/NServiceBus.Testing/Invocations.cs +++ b/src/NServiceBus.Testing/Invocations.cs @@ -185,6 +185,14 @@ public ExpectedNotReplyInvocation() } } + public class ExpectedNotDeferMessageInvocation : ExpectedDeferMessageInvocation + { + public ExpectedNotDeferMessageInvocation() + { + Negate = true; + } + } + public class ExpectedReplyToOriginatorInvocation : ExpectedInvocation> { public Func Check { get; set; } diff --git a/src/NServiceBus.Testing/NServiceBus.Testing.csproj b/src/NServiceBus.Testing/NServiceBus.Testing.csproj index e474bf452ef..a83f8f2a19e 100644 --- a/src/NServiceBus.Testing/NServiceBus.Testing.csproj +++ b/src/NServiceBus.Testing/NServiceBus.Testing.csproj @@ -14,6 +14,7 @@ true ..\NServiceBus.snk ..\packages\Fody + ..\ true @@ -91,7 +92,7 @@ {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus diff --git a/src/NServiceBus.Testing/Properties/AssemblyInfo.cs b/src/NServiceBus.Testing/Properties/AssemblyInfo.cs index c1e41295d3e..282479d5135 100644 --- a/src/NServiceBus.Testing/Properties/AssemblyInfo.cs +++ b/src/NServiceBus.Testing/Properties/AssemblyInfo.cs @@ -4,10 +4,9 @@ [assembly: AssemblyTitle("NServiceBus Testing")] [assembly: AssemblyDescription("Unit Testing facilities for NServiceBus Sagas.")] -[assembly: AssemblyCopyright("Copyright 2010-2013 NServiceBus. All rights reserved")] +[assembly: AssemblyCopyright("Copyright 2010-2014 NServiceBus. All rights reserved")] [assembly: AssemblyProduct("NServiceBus")] [assembly: AssemblyCompany("NServiceBus Ltd.")] -[assembly: AssemblyConfiguration("release")] [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] diff --git a/src/NServiceBus.Testing/Saga.cs b/src/NServiceBus.Testing/Saga.cs index c68ec6b20f0..ddced823fe8 100644 --- a/src/NServiceBus.Testing/Saga.cs +++ b/src/NServiceBus.Testing/Saga.cs @@ -333,6 +333,15 @@ public Saga ExpectTimeoutToBeSetIn(Func c return this; } + /// + /// Verifies that the saga is not setting the specified timeout + /// + public Saga ExpectNoTimeoutToBeSetIn(Func check = null) + { + expectedInvocations.Add(new ExpectedNotDeferMessageInvocation { Check = check }); + return this; + } + /// /// Verifies that the saga is setting the specified timeout /// @@ -350,6 +359,15 @@ public Saga ExpectTimeoutToBeSetAt(Func c return this; } + /// + /// Verifies that the saga is not setting the specified timeout + /// + public Saga ExpectNoTimeoutToBeSetAt(Func check = null) + { + expectedInvocations.Add(new ExpectedNotDeferMessageInvocation { Check = check }); + return this; + } + /// /// Verifies that the saga is setting the specified timeout /// diff --git a/src/NServiceBus.Testing/StubBus.cs b/src/NServiceBus.Testing/StubBus.cs index 3075f4eed98..a94cd90dec5 100644 --- a/src/NServiceBus.Testing/StubBus.cs +++ b/src/NServiceBus.Testing/StubBus.cs @@ -31,11 +31,11 @@ public StubBus(IMessageCreator creator) public void Publish(T message) { - Publish(new []{message} ); + Publish(new []{message} ); } public void Publish() { - Publish(new T[0]); + Publish(new T[0]); } public void Publish(params T[] messages) diff --git a/src/NServiceBus.sln b/src/NServiceBus.sln index 74234f8a0c8..047d0c6df80 100644 --- a/src/NServiceBus.sln +++ b/src/NServiceBus.sln @@ -1,7 +1,5 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.21005.1 -MinimumVisualStudioVersion = 10.0.40219.1 +# Visual Studio 2012 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NServiceBus", "NServiceBus\NServiceBus.csproj", "{73867D40-8CBB-48E9-BFFA-12BBDD48A341}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObjectBuilder.CastleWindsor", "ObjectBuilder.CastleWindsor\ObjectBuilder.CastleWindsor.csproj", "{9A9A0BD5-AC37-4B90-B90F-FD1C1395FEBD}" @@ -26,7 +24,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NServiceBus.Logging.Tests", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LicenseInstaller", "licenseinstaller\LicenseInstaller.csproj", "{857C5E77-1946-4C83-BC8D-EFF8E1611A0D}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NServiceBus", "NServiceBus", "{258A3F0E-FAFA-4C13-9D5A-9E46661B22D2}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{258A3F0E-FAFA-4C13-9D5A-9E46661B22D2}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ObjectBuilders", "ObjectBuilders", "{A650DE92-3B6D-4228-A1A2-FB06E74C1BD2}" EndProject diff --git a/src/NServiceBus.sln.DotSettings b/src/NServiceBus.sln.DotSettings index a400cfe4f29..e9db2f36e14 100644 --- a/src/NServiceBus.sln.DotSettings +++ b/src/NServiceBus.sln.DotSettings @@ -16,6 +16,7 @@ ERROR WARNING ERROR + DO_NOT_SHOW ERROR ERROR ERROR @@ -29,6 +30,7 @@ DO_NOT_SHOW DO_NOT_SHOW DO_NOT_SHOW + SUGGESTION ERROR WARNING ERROR @@ -40,6 +42,7 @@ ERROR WARNING ERROR + ERROR ERROR ERROR ERROR @@ -89,6 +92,7 @@ ERROR ERROR ERROR + ERROR ERROR ERROR ERROR diff --git a/src/NServiceBus/Headers.cs b/src/NServiceBus/Headers.cs index c6cd016bcee..81afc306afd 100644 --- a/src/NServiceBus/Headers.cs +++ b/src/NServiceBus/Headers.cs @@ -54,6 +54,12 @@ public static class Headers ///
public const string SagaId = "NServiceBus.SagaId"; + /// + /// Header containing a list of saga types and ids that this message invoked, the format is "{sagatype}={sagaid};{sagatype}={sagaid}" + /// This header is considered an applicative header. + /// + public const string InvokedSagas = "NServiceBus.InvokedSagas"; + /// /// Header telling the timeout manager to clear previous timeouts /// This header is considered an applicative header. @@ -187,18 +193,35 @@ public static class Headers /// /// Machine name of the endpoint where the given message originated /// + [ObsoleteEx(Message = "The OriginatingMachine header is replaced by the OriginatingHostId to be more environment agnostic", RemoveInVersion = "5.0")] public const string OriginatingMachine = "NServiceBus.OriginatingMachine"; /// - /// Name of the endpoint where the given message was processed(success or failure) + /// HostId of the endpoint where the given message originated + /// + public const string OriginatingHostId = "$.diagnostics.originating.hostid"; + + /// + /// Name of the endpoint where the given message was processed (success or failure) /// public const string ProcessingEndpoint = "NServiceBus.ProcessingEndpoint"; /// - /// Machine name of the endpoint where the given message was processed(success or failure) + /// Machine name of the endpoint where the given message was processed (success or failure) /// + [ObsoleteEx(Message = "The ProcessingMachine header is replaced by the HostDisplayName to be more environment agnostic", RemoveInVersion = "5.0")] public const string ProcessingMachine = "NServiceBus.ProcessingMachine"; + /// + /// The display name of the host where the given message was processed (success or failure), eg the MachineName. + /// + public const string HostDisplayName = "$.diagnostics.hostdisplayname"; + + /// + /// HostId of the endpoint where the given message was processed (success or failure) + /// + public const string HostId = "$.diagnostics.hostid"; + /// /// The original reply to address for successfully processed messages /// diff --git a/src/NServiceBus/NServiceBus.csproj b/src/NServiceBus/NServiceBus.csproj index ecfda8996c1..5042772d6d7 100644 --- a/src/NServiceBus/NServiceBus.csproj +++ b/src/NServiceBus/NServiceBus.csproj @@ -14,6 +14,7 @@ true ..\NServiceBus.snk ..\packages\Fody + ..\ true diff --git a/src/NServiceBus/NServiceBusVersion.cs b/src/NServiceBus/NServiceBusVersion.cs index 864196557c2..023e2522637 100644 --- a/src/NServiceBus/NServiceBusVersion.cs +++ b/src/NServiceBus/NServiceBusVersion.cs @@ -3,11 +3,20 @@ namespace NServiceBus /// /// The semver version of NServiceBus /// + [ObsoleteEx(RemoveInVersion = "5.0", TreatAsErrorFromVersion = "5.0")] public static class NServiceBusVersion { - /// - /// The semver version of NServiceBus - /// - public const string Version = "4.3.4"; + + static NServiceBusVersion() + { + var assembly = typeof(NServiceBusVersion).Assembly; + var gitFlowVersionInformationType = assembly.GetType("NServiceBus.GitFlowVersionInformation", true); + var fieldInfo = gitFlowVersionInformationType.GetField("AssemblyFileVersion"); + var assemblyFileVersion = System.Version.Parse((string)fieldInfo.GetValue(null)); + Version = assemblyFileVersion.ToString(3); + } + + public static readonly string Version; + } } diff --git a/src/NServiceBus/Properties/AssemblyInfo.cs b/src/NServiceBus/Properties/AssemblyInfo.cs index a63b2c5207b..3b9a7782417 100644 --- a/src/NServiceBus/Properties/AssemblyInfo.cs +++ b/src/NServiceBus/Properties/AssemblyInfo.cs @@ -4,10 +4,9 @@ [assembly: AssemblyTitle("NServiceBus Core")] [assembly: AssemblyDescription("Enterprise application framework for publish/subscribe and long-running business processes.")] -[assembly: AssemblyCopyright("Copyright 2010-2013 NServiceBus. All rights reserved")] +[assembly: AssemblyCopyright("Copyright 2010-2014 NServiceBus. All rights reserved")] [assembly: AssemblyProduct("NServiceBus")] [assembly: AssemblyCompany("NServiceBus Ltd.")] -[assembly: AssemblyConfiguration("release")] [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] diff --git a/src/NServiceBus/Saga/IHandleReplyingToNullOriginator.cs b/src/NServiceBus/Saga/IHandleReplyingToNullOriginator.cs index ebb3a78914b..c7b1e8149e6 100644 --- a/src/NServiceBus/Saga/IHandleReplyingToNullOriginator.cs +++ b/src/NServiceBus/Saga/IHandleReplyingToNullOriginator.cs @@ -3,7 +3,7 @@ namespace NServiceBus.Saga /// /// Double-dispatch class. /// - [ObsoleteEx(TreatAsErrorFromVersion = "4.4",RemoveInVersion = "5.0", Message ="This hook will no longer be provided")] + [ObsoleteEx(TreatAsErrorFromVersion = "5.0",RemoveInVersion = "5.0", Message ="This hook will no longer be provided")] public interface IHandleReplyingToNullOriginator { /// diff --git a/src/ObjectBuilder.Autofac/ObjectBuilder.Autofac.csproj b/src/ObjectBuilder.Autofac/ObjectBuilder.Autofac.csproj index 9205c899942..032b484c054 100644 --- a/src/ObjectBuilder.Autofac/ObjectBuilder.Autofac.csproj +++ b/src/ObjectBuilder.Autofac/ObjectBuilder.Autofac.csproj @@ -15,6 +15,7 @@ true ..\NServiceBus.snk ..\packages\Fody + ..\ true @@ -79,7 +80,7 @@ {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus False diff --git a/src/ObjectBuilder.Autofac/Properties/AssemblyInfo.cs b/src/ObjectBuilder.Autofac/Properties/AssemblyInfo.cs index 251ee801887..37778311fd2 100644 --- a/src/ObjectBuilder.Autofac/Properties/AssemblyInfo.cs +++ b/src/ObjectBuilder.Autofac/Properties/AssemblyInfo.cs @@ -4,10 +4,9 @@ [assembly: AssemblyTitle("NServiceBus Container Autofac Implementation")] [assembly: AssemblyDescription("Implementation of container functionality on top of Autofac.")] -[assembly: AssemblyCopyright("Copyright 2010-2013 NServiceBus. All rights reserved")] +[assembly: AssemblyCopyright("Copyright 2010-2014 NServiceBus. All rights reserved")] [assembly: AssemblyProduct("NServiceBus")] [assembly: AssemblyCompany("NServiceBus Ltd.")] -[assembly: AssemblyConfiguration("release")] [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] diff --git a/src/ObjectBuilder.CastleWindsor/ObjectBuilder.CastleWindsor.csproj b/src/ObjectBuilder.CastleWindsor/ObjectBuilder.CastleWindsor.csproj index 631bf4aecb7..81668a8bd21 100644 --- a/src/ObjectBuilder.CastleWindsor/ObjectBuilder.CastleWindsor.csproj +++ b/src/ObjectBuilder.CastleWindsor/ObjectBuilder.CastleWindsor.csproj @@ -15,6 +15,7 @@ true ..\NServiceBus.snk ..\packages\Fody + ..\ true @@ -85,7 +86,7 @@ {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus False diff --git a/src/ObjectBuilder.CastleWindsor/Properties/AssemblyInfo.cs b/src/ObjectBuilder.CastleWindsor/Properties/AssemblyInfo.cs index d1e56c334a3..d85e8ed8d1d 100644 --- a/src/ObjectBuilder.CastleWindsor/Properties/AssemblyInfo.cs +++ b/src/ObjectBuilder.CastleWindsor/Properties/AssemblyInfo.cs @@ -4,10 +4,9 @@ [assembly: AssemblyTitle("NServiceBus Object Builder Castle Implementation")] [assembly: AssemblyDescription("Implementation of object building functionality on top of Castle Windsor.")] -[assembly: AssemblyCopyright("Copyright 2010-2013 NServiceBus. All rights reserved")] +[assembly: AssemblyCopyright("Copyright 2010-2014 NServiceBus. All rights reserved")] [assembly: AssemblyProduct("NServiceBus")] [assembly: AssemblyCompany("NServiceBus Ltd.")] -[assembly: AssemblyConfiguration("release")] [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] diff --git a/src/ObjectBuilder.Ninject/ObjectBuilder.Ninject.csproj b/src/ObjectBuilder.Ninject/ObjectBuilder.Ninject.csproj index cf942fce7f0..f220990f50d 100644 --- a/src/ObjectBuilder.Ninject/ObjectBuilder.Ninject.csproj +++ b/src/ObjectBuilder.Ninject/ObjectBuilder.Ninject.csproj @@ -14,6 +14,7 @@ 512 true ..\NServiceBus.snk + ..\ ..\packages\Fody @@ -75,7 +76,7 @@ {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus False diff --git a/src/ObjectBuilder.Ninject/Properties/AssemblyInfo.cs b/src/ObjectBuilder.Ninject/Properties/AssemblyInfo.cs index 35d026a049b..ef0bd373e70 100644 --- a/src/ObjectBuilder.Ninject/Properties/AssemblyInfo.cs +++ b/src/ObjectBuilder.Ninject/Properties/AssemblyInfo.cs @@ -4,10 +4,9 @@ [assembly: AssemblyTitle("NServiceBus Object Builder Ninject Implementation")] [assembly: AssemblyDescription("Implementation of object building functionality on top of the Ninject Framework.")] -[assembly: AssemblyCopyright("Copyright 2010-2013 NServiceBus. All rights reserved")] +[assembly: AssemblyCopyright("Copyright 2010-2014 NServiceBus. All rights reserved")] [assembly: AssemblyProduct("NServiceBus")] [assembly: AssemblyCompany("NServiceBus Ltd.")] -[assembly: AssemblyConfiguration("release")] [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] diff --git a/src/ObjectBuilder.Spring/ComponentConfig.cs b/src/ObjectBuilder.Spring/ComponentConfig.cs index bd5016d7c11..b2e202851f0 100644 --- a/src/ObjectBuilder.Spring/ComponentConfig.cs +++ b/src/ObjectBuilder.Spring/ComponentConfig.cs @@ -9,9 +9,9 @@ class ComponentConfig : IComponentConfig public void Configure(ObjectDefinitionBuilder builder) { - foreach (var key in properties.Keys) + foreach (var keyValue in properties) { - builder.AddPropertyValue(key, properties[key]); + builder.AddPropertyValue(keyValue.Key, keyValue.Value); } } diff --git a/src/ObjectBuilder.Spring/ObjectBuilder.Spring.csproj b/src/ObjectBuilder.Spring/ObjectBuilder.Spring.csproj index fc89abcb481..1ec3a76a819 100644 --- a/src/ObjectBuilder.Spring/ObjectBuilder.Spring.csproj +++ b/src/ObjectBuilder.Spring/ObjectBuilder.Spring.csproj @@ -15,6 +15,7 @@ true ..\NServiceBus.snk ..\packages\Fody + ..\ true @@ -69,7 +70,7 @@ {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus False diff --git a/src/ObjectBuilder.Spring/Properties/AssemblyInfo.cs b/src/ObjectBuilder.Spring/Properties/AssemblyInfo.cs index 6d1607b9b9d..80360e8039e 100644 --- a/src/ObjectBuilder.Spring/Properties/AssemblyInfo.cs +++ b/src/ObjectBuilder.Spring/Properties/AssemblyInfo.cs @@ -3,9 +3,8 @@ [assembly: AssemblyTitle("NServiceBus Object Builder Spring Implementation")] [assembly: AssemblyDescription("Implementation of object building functionality on top of the Spring Framework.")] -[assembly: AssemblyCopyright("Copyright 2010-2013 NServiceBus. All rights reserved")] +[assembly: AssemblyCopyright("Copyright 2010-2014 NServiceBus. All rights reserved")] [assembly: AssemblyProduct("NServiceBus")] [assembly: AssemblyCompany("NServiceBus Ltd.")] -[assembly: AssemblyConfiguration("release")] [assembly: ComVisible(false)] diff --git a/src/ObjectBuilder.StructureMap/ObjectBuilder.StructureMap.csproj b/src/ObjectBuilder.StructureMap/ObjectBuilder.StructureMap.csproj index dc6524da4ab..0c44623717f 100644 --- a/src/ObjectBuilder.StructureMap/ObjectBuilder.StructureMap.csproj +++ b/src/ObjectBuilder.StructureMap/ObjectBuilder.StructureMap.csproj @@ -15,6 +15,7 @@ true ..\NServiceBus.snk ..\packages\Fody + ..\ true @@ -84,7 +85,7 @@ {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus False diff --git a/src/ObjectBuilder.StructureMap/Properties/AssemblyInfo.cs b/src/ObjectBuilder.StructureMap/Properties/AssemblyInfo.cs index 92edd1f7896..c71030ded1f 100644 --- a/src/ObjectBuilder.StructureMap/Properties/AssemblyInfo.cs +++ b/src/ObjectBuilder.StructureMap/Properties/AssemblyInfo.cs @@ -4,10 +4,9 @@ [assembly: AssemblyTitle("NServiceBus Container StructureMap Implementation")] [assembly: AssemblyDescription("Implementation of container functionality on top of StructureMap.")] -[assembly: AssemblyCopyright("Copyright 2010-2013 NServiceBus. All rights reserved")] +[assembly: AssemblyCopyright("Copyright 2010-2014 NServiceBus. All rights reserved")] [assembly: AssemblyProduct("NServiceBus")] [assembly: AssemblyCompany("NServiceBus Ltd.")] -[assembly: AssemblyConfiguration("release")] [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] diff --git a/src/ObjectBuilder.Tests/ObjectBuilder.Tests.csproj b/src/ObjectBuilder.Tests/ObjectBuilder.Tests.csproj index 5a04edeaa79..5bfb484f95a 100644 --- a/src/ObjectBuilder.Tests/ObjectBuilder.Tests.csproj +++ b/src/ObjectBuilder.Tests/ObjectBuilder.Tests.csproj @@ -14,6 +14,7 @@ 512 false ..\NServiceBus.snk + ..\ true diff --git a/src/ObjectBuilder.Tests/When_releasing_components.cs b/src/ObjectBuilder.Tests/When_releasing_components.cs index c3e4aa8382a..efc952e4485 100644 --- a/src/ObjectBuilder.Tests/When_releasing_components.cs +++ b/src/ObjectBuilder.Tests/When_releasing_components.cs @@ -22,6 +22,7 @@ public void Transient_component_should_be_destructed_called() builder.Release(comp); + // ReSharper disable once RedundantAssignment comp = null; GC.Collect(); diff --git a/src/ObjectBuilder.Unity/ObjectBuilder.Unity.csproj b/src/ObjectBuilder.Unity/ObjectBuilder.Unity.csproj index 6ad1dbd6d18..df28e9ae9d7 100644 --- a/src/ObjectBuilder.Unity/ObjectBuilder.Unity.csproj +++ b/src/ObjectBuilder.Unity/ObjectBuilder.Unity.csproj @@ -15,6 +15,7 @@ true ..\NServiceBus.snk ..\packages\Fody + ..\ true @@ -92,7 +93,7 @@ {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus diff --git a/src/ObjectBuilder.Unity/Properties/AssemblyInfo.cs b/src/ObjectBuilder.Unity/Properties/AssemblyInfo.cs index afa4d744c2b..d65e37e4b4e 100644 --- a/src/ObjectBuilder.Unity/Properties/AssemblyInfo.cs +++ b/src/ObjectBuilder.Unity/Properties/AssemblyInfo.cs @@ -4,10 +4,9 @@ [assembly: AssemblyTitle("NServiceBus Container Unity Implementation")] [assembly: AssemblyDescription("Implementation of container functionality on top of Unity.")] -[assembly: AssemblyCopyright("Copyright 2010-2013 NServiceBus. All rights reserved")] +[assembly: AssemblyCopyright("Copyright 2010-2014 NServiceBus. All rights reserved")] [assembly: AssemblyProduct("NServiceBus")] [assembly: AssemblyCompany("NServiceBus Ltd.")] -[assembly: AssemblyConfiguration("release")] [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] diff --git a/src/ObjectBuilder.Unity/PropertyInjectionBuilderStrategy.cs b/src/ObjectBuilder.Unity/PropertyInjectionBuilderStrategy.cs index 8a1fe8c983c..52ff3370a59 100644 --- a/src/ObjectBuilder.Unity/PropertyInjectionBuilderStrategy.cs +++ b/src/ObjectBuilder.Unity/PropertyInjectionBuilderStrategy.cs @@ -18,12 +18,13 @@ public PropertyInjectionBuilderStrategy(IUnityContainer unityContainer) public static void SetPropertyValue(Type type, string name,object value) { - if (!configuredProperties.ContainsKey(type)) + List> properties; + if (!configuredProperties.TryGetValue(type, out properties)) { - configuredProperties.Add(type,new List>()); + configuredProperties[type] = properties = new List>(); } - configuredProperties[type].Add(new Tuple(name,value)); + properties.Add(new Tuple(name, value)); } public override void PreBuildUp(IBuilderContext context) @@ -44,9 +45,10 @@ public override void PreBuildUp(IBuilderContext context) property.SetValue(context.Existing, unityContainer.Resolve(property.PropertyType),null); } - if(configuredProperties.ContainsKey(type)) + List> configuredProperty; + if(configuredProperties.TryGetValue(type, out configuredProperty)) { - var p = configuredProperties[type].FirstOrDefault(t => t.Item1 == property.Name); + var p = configuredProperty.FirstOrDefault(t => t.Item1 == property.Name); if (p != null) { diff --git a/src/ReturnToSourceQueue/Properties/AssemblyInfo.cs b/src/ReturnToSourceQueue/Properties/AssemblyInfo.cs index 8573a3a43bf..3805ef3510b 100644 --- a/src/ReturnToSourceQueue/Properties/AssemblyInfo.cs +++ b/src/ReturnToSourceQueue/Properties/AssemblyInfo.cs @@ -4,10 +4,9 @@ [assembly: AssemblyTitle("ReturnToSourceQueue")] [assembly: AssemblyDescription("")] -[assembly: AssemblyCopyright("Copyright 2010-2013 NServiceBus. All rights reserved")] +[assembly: AssemblyCopyright("Copyright 2010-2014 NServiceBus. All rights reserved")] [assembly: AssemblyProduct("NServiceBus")] [assembly: AssemblyCompany("NServiceBus Ltd.")] -[assembly: AssemblyConfiguration("release")] [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] diff --git a/src/ReturnToSourceQueue/ReturnToSourceQueue.csproj b/src/ReturnToSourceQueue/ReturnToSourceQueue.csproj index 1c77e92b8fa..e20567e08f9 100644 --- a/src/ReturnToSourceQueue/ReturnToSourceQueue.csproj +++ b/src/ReturnToSourceQueue/ReturnToSourceQueue.csproj @@ -12,6 +12,7 @@ ReturnToSourceQueue true ..\NServiceBus.snk + ..\ true @@ -81,7 +82,7 @@ {73867d40-8cbb-48e9-bffa-12bbdd48a341} - NServiceBus %28NServiceBus\NServiceBus%29 + NServiceBus diff --git a/src/licenseinstaller/LicenseInstaller.csproj b/src/licenseinstaller/LicenseInstaller.csproj index aeca750e582..eb966f9d263 100644 --- a/src/licenseinstaller/LicenseInstaller.csproj +++ b/src/licenseinstaller/LicenseInstaller.csproj @@ -2,7 +2,7 @@ Debug - x86 + AnyCPU 8.0.30703 2.0 {857C5E77-1946-4C83-BC8D-EFF8E1611A0D} @@ -15,6 +15,7 @@ 512 true ..\NServiceBus.snk + ..\ true diff --git a/src/licenseinstaller/Options.cs b/src/licenseinstaller/Options.cs index a1a7ac74a4f..a1032930125 100644 --- a/src/licenseinstaller/Options.cs +++ b/src/licenseinstaller/Options.cs @@ -811,10 +811,9 @@ protected virtual bool Parse(string argument, OptionContext c) if (!GetOptionParts(argument, out f, out n, out s, out v)) return false; - Option p; if (Contains(n)) { - p = this[n]; + var p = this[n]; c.OptionName = f + n; c.Option = p; switch (p.OptionValueType) @@ -863,12 +862,11 @@ private void ParseValue(string option, OptionContext c) private bool ParseBool(string option, string n, OptionContext c) { - Option p; string rn; if (n.Length >= 1 && (n[n.Length - 1] == '+' || n[n.Length - 1] == '-') && Contains((rn = n.Substring(0, n.Length - 1)))) { - p = this[rn]; + var p = this[rn]; var v = n[n.Length - 1] == '+' ? option : null; c.OptionName = option; c.Option = p; diff --git a/src/licenseinstaller/Program.cs b/src/licenseinstaller/Program.cs index a3cc9f3748c..ae0998b3e8d 100644 --- a/src/licenseinstaller/Program.cs +++ b/src/licenseinstaller/Program.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.IO; - using System.Reflection; using Microsoft.Win32; using NDesk.Options; @@ -67,9 +66,7 @@ static bool TryToWriteToRegistry(string selectedLicenseText, RegistryView view) if (registryKey == null) { Console.Out.WriteLine("License file not installed."); - { - return false; - } + return false; } registryKey.SetValue("License", selectedLicenseText, RegistryValueKind.String); } @@ -152,11 +149,5 @@ static string ReadAllTextWithoutLocking(string path) } } - static Version GetNServiceBusVersion() - { - var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version; - - return new Version(assemblyVersion.Major, assemblyVersion.Minor); - } } } diff --git a/src/licenseinstaller/Properties/AssemblyInfo.cs b/src/licenseinstaller/Properties/AssemblyInfo.cs index 02add3aca1d..a8fad9dc583 100644 --- a/src/licenseinstaller/Properties/AssemblyInfo.cs +++ b/src/licenseinstaller/Properties/AssemblyInfo.cs @@ -4,10 +4,9 @@ [assembly: AssemblyTitle("NServiceBus License Installer")] [assembly: AssemblyDescription("Utility to install license file.")] -[assembly: AssemblyCopyright("Copyright 2010-2013 NServiceBus. All rights reserved")] +[assembly: AssemblyCopyright("Copyright 2010-2014 NServiceBus. All rights reserved")] [assembly: AssemblyProduct("LicenseInstaller")] [assembly: AssemblyCompany("NServiceBus Ltd.")] -[assembly: AssemblyConfiguration("release")] [assembly: ComVisible(false)] [assembly: CLSCompliant(true)]