From 867e29838d628ad60569bd477485acded37428ed Mon Sep 17 00:00:00 2001 From: Yves Goeleven Date: Thu, 11 Jun 2015 11:20:56 +0200 Subject: [PATCH 1/3] fixes #2748 --- .../NServiceBus.AcceptanceTests.csproj | 1 + .../Sagas/When_using_ReplyToOriginator.cs | 97 +++++++++++++++++++ src/NServiceBus.Core/NServiceBus.Core.csproj | 1 + .../Pipeline/PipelineBuilder.cs | 1 + src/NServiceBus.Core/Saga/Saga.cs | 1 + .../Behaviors/FixSendIntentBehavior.cs | 23 +++++ 6 files changed, 124 insertions(+) create mode 100644 src/NServiceBus.AcceptanceTests/Sagas/When_using_ReplyToOriginator.cs create mode 100644 src/NServiceBus.Core/Unicast/Behaviors/FixSendIntentBehavior.cs diff --git a/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj b/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj index f1a4bea1f67..b4157f87638 100644 --- a/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj +++ b/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj @@ -87,6 +87,7 @@ + diff --git a/src/NServiceBus.AcceptanceTests/Sagas/When_using_ReplyToOriginator.cs b/src/NServiceBus.AcceptanceTests/Sagas/When_using_ReplyToOriginator.cs new file mode 100644 index 00000000000..922fe691c3b --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/Sagas/When_using_ReplyToOriginator.cs @@ -0,0 +1,97 @@ +namespace NServiceBus.AcceptanceTests.Sagas +{ + using System; + using EndpointTemplates; + using AcceptanceTesting; + using NUnit.Framework; + using Saga; + + public class When_using_ReplyToOriginator : NServiceBusAcceptanceTest + { + [Test] + public void Should_set_Reply_as_messageintent() + { + var context = new Context(); + + Scenario.Define(context) + .WithEndpoint(b => b.Given(bus => bus.SendLocal(new InitiateRequestingSaga()))) + .Done(c => c.Done) + .Run(); + + Assert.AreEqual(MessageIntentEnum.Reply, context.Intent); + } + + public class Context : ScenarioContext + { + public MessageIntentEnum Intent { get; set; } + public bool Done { get; set; } + } + + public class Endpoint : EndpointConfigurationBuilder + { + + public Endpoint() + { + EndpointSetup(); + } + + public class RequestingSaga : Saga, + IAmStartedByMessages, + IHandleMessages + { + public Context Context { get; set; } + + public void Handle(InitiateRequestingSaga message) + { + Data.CorrIdForResponse = Guid.NewGuid(); //wont be needed in the future + + Bus.SendLocal(new AnotherRequest + { + SomeCorrelationId = Data.CorrIdForResponse //wont be needed in the future + }); + } + + public void Handle(AnotherRequest message) + { + ReplyToOriginator(new MyReplyToOriginator()); + MarkAsComplete(); + } + + protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) + { + //if this line is un-commented the timeout and secondary handler tests will start to fail + // for more info and discussion see TBD + mapper.ConfigureMapping(m => m.SomeCorrelationId).ToSaga(s => s.CorrIdForResponse); + } + public class RequestingSagaData : ContainSagaData + { + public virtual Guid CorrIdForResponse { get; set; } //wont be needed in the future + } + } + + class MyReplyToOriginatorHandler : IHandleMessages + { + public Context Context { get; set; } + public IBus Bus { get; set; } + + public void Handle(MyReplyToOriginator message) + { + Context.Intent = (MessageIntentEnum)Enum.Parse(typeof(MessageIntentEnum), Bus.CurrentMessageContext.Headers[Headers.MessageIntent]); + Context.Done = true; + } + } + } + + public class InitiateRequestingSaga : ICommand { } + + public class AnotherRequest : ICommand + { + public Guid SomeCorrelationId { get; set; } + } + + public class MyReplyToOriginator : IMessage + { + public Guid SomeCorrelationId { get; set; } + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Core/NServiceBus.Core.csproj b/src/NServiceBus.Core/NServiceBus.Core.csproj index fc3bbbedff8..dc5b7a0bc94 100644 --- a/src/NServiceBus.Core/NServiceBus.Core.csproj +++ b/src/NServiceBus.Core/NServiceBus.Core.csproj @@ -239,6 +239,7 @@ + diff --git a/src/NServiceBus.Core/Pipeline/PipelineBuilder.cs b/src/NServiceBus.Core/Pipeline/PipelineBuilder.cs index de31cb91d35..77533507bb3 100644 --- a/src/NServiceBus.Core/Pipeline/PipelineBuilder.cs +++ b/src/NServiceBus.Core/Pipeline/PipelineBuilder.cs @@ -68,6 +68,7 @@ void RegisterOutgoingCoreBehaviors() coordinator.Register(WellKnownStep.MutateOutgoingMessages, typeof(MutateOutgoingMessageBehavior), "Executes IMutateOutgoingMessages"); coordinator.Register("PopulateAutoCorrelationHeadersForReplies", typeof(PopulateAutoCorrelationHeadersForRepliesBehavior), "Copies existing saga headers from incoming message to outgoing message to facilitate the auto correlation in the saga, when replying to a message that was sent by a saga."); coordinator.Register(WellKnownStep.CreatePhysicalMessage, typeof(CreatePhysicalMessageBehavior), "Converts a logical message into a physical message"); + coordinator.Register("FixSendIntent", typeof(FixSendIntentBehavior), "Fixes issue 2748"); coordinator.Register(WellKnownStep.SerializeMessage, typeof(SerializeMessagesBehavior), "Serializes the message to be sent out on the wire"); coordinator.Register(WellKnownStep.MutateOutgoingTransportMessage, typeof(MutateOutgoingPhysicalMessageBehavior), "Executes IMutateOutgoingTransportMessages"); if (LogManager.GetLogger("LogOutgoingMessage").IsDebugEnabled) diff --git a/src/NServiceBus.Core/Saga/Saga.cs b/src/NServiceBus.Core/Saga/Saga.cs index 413ad9860a5..ddd3e0207e6 100644 --- a/src/NServiceBus.Core/Saga/Saga.cs +++ b/src/NServiceBus.Core/Saga/Saga.cs @@ -155,6 +155,7 @@ protected virtual void ReplyToOriginator(object message) { throw new Exception("Entity.Originator cannot be null. Perhaps the sender is a SendOnly endpoint."); } + Bus.SetMessageHeader(message, "$.temporary.ReplyToOriginator", "ReplyToOriginator"); // issue 2748 Bus.Send(Entity.Originator, Entity.OriginalMessageId, message); } diff --git a/src/NServiceBus.Core/Unicast/Behaviors/FixSendIntentBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/FixSendIntentBehavior.cs new file mode 100644 index 00000000000..4dc95fceca5 --- /dev/null +++ b/src/NServiceBus.Core/Unicast/Behaviors/FixSendIntentBehavior.cs @@ -0,0 +1,23 @@ +namespace NServiceBus +{ + using System; + using NServiceBus.Pipeline; + using NServiceBus.Pipeline.Contexts; + + class FixSendIntentBehavior : IBehavior + { + public Conventions Conventions { get; set; } + + public void Invoke(OutgoingContext context, Action next) + { + if (context.OutgoingLogicalMessage.Headers.ContainsKey("$.temporary.ReplyToOriginator")) + { + context.OutgoingMessage.MessageIntent = MessageIntentEnum.Reply; + context.OutgoingMessage.Headers.Remove("$.temporary.ReplyToOriginator"); + context.OutgoingLogicalMessage.Headers.Remove("$.temporary.ReplyToOriginator"); + } + + next(); + } + } +} \ No newline at end of file From 99bfd0e90867c9f30dbfe4f6fb84426bdcd02022 Mon Sep 17 00:00:00 2001 From: Yves Goeleven Date: Thu, 11 Jun 2015 13:29:10 +0200 Subject: [PATCH 2/3] updated description & removed unneeded proprety --- src/NServiceBus.Core/Pipeline/PipelineBuilder.cs | 2 +- src/NServiceBus.Core/Unicast/Behaviors/FixSendIntentBehavior.cs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/NServiceBus.Core/Pipeline/PipelineBuilder.cs b/src/NServiceBus.Core/Pipeline/PipelineBuilder.cs index 77533507bb3..1b966b0c627 100644 --- a/src/NServiceBus.Core/Pipeline/PipelineBuilder.cs +++ b/src/NServiceBus.Core/Pipeline/PipelineBuilder.cs @@ -68,7 +68,7 @@ void RegisterOutgoingCoreBehaviors() coordinator.Register(WellKnownStep.MutateOutgoingMessages, typeof(MutateOutgoingMessageBehavior), "Executes IMutateOutgoingMessages"); coordinator.Register("PopulateAutoCorrelationHeadersForReplies", typeof(PopulateAutoCorrelationHeadersForRepliesBehavior), "Copies existing saga headers from incoming message to outgoing message to facilitate the auto correlation in the saga, when replying to a message that was sent by a saga."); coordinator.Register(WellKnownStep.CreatePhysicalMessage, typeof(CreatePhysicalMessageBehavior), "Converts a logical message into a physical message"); - coordinator.Register("FixSendIntent", typeof(FixSendIntentBehavior), "Fixes issue 2748"); + coordinator.Register("FixSendIntent", typeof(FixSendIntentBehavior), "Fixes an issue where ReplyToOriginator isn't able to set the Reply message intent"); coordinator.Register(WellKnownStep.SerializeMessage, typeof(SerializeMessagesBehavior), "Serializes the message to be sent out on the wire"); coordinator.Register(WellKnownStep.MutateOutgoingTransportMessage, typeof(MutateOutgoingPhysicalMessageBehavior), "Executes IMutateOutgoingTransportMessages"); if (LogManager.GetLogger("LogOutgoingMessage").IsDebugEnabled) diff --git a/src/NServiceBus.Core/Unicast/Behaviors/FixSendIntentBehavior.cs b/src/NServiceBus.Core/Unicast/Behaviors/FixSendIntentBehavior.cs index 4dc95fceca5..7620b57a27e 100644 --- a/src/NServiceBus.Core/Unicast/Behaviors/FixSendIntentBehavior.cs +++ b/src/NServiceBus.Core/Unicast/Behaviors/FixSendIntentBehavior.cs @@ -6,8 +6,6 @@ class FixSendIntentBehavior : IBehavior { - public Conventions Conventions { get; set; } - public void Invoke(OutgoingContext context, Action next) { if (context.OutgoingLogicalMessage.Headers.ContainsKey("$.temporary.ReplyToOriginator")) From 305e08f9b3768137a913a86b0733947de2fb5e06 Mon Sep 17 00:00:00 2001 From: Yves Goeleven Date: Thu, 11 Jun 2015 14:16:13 +0200 Subject: [PATCH 3/3] mentioned callbacks --- src/NServiceBus.Core/Pipeline/PipelineBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NServiceBus.Core/Pipeline/PipelineBuilder.cs b/src/NServiceBus.Core/Pipeline/PipelineBuilder.cs index 1b966b0c627..b6027f27ee2 100644 --- a/src/NServiceBus.Core/Pipeline/PipelineBuilder.cs +++ b/src/NServiceBus.Core/Pipeline/PipelineBuilder.cs @@ -68,7 +68,7 @@ void RegisterOutgoingCoreBehaviors() coordinator.Register(WellKnownStep.MutateOutgoingMessages, typeof(MutateOutgoingMessageBehavior), "Executes IMutateOutgoingMessages"); coordinator.Register("PopulateAutoCorrelationHeadersForReplies", typeof(PopulateAutoCorrelationHeadersForRepliesBehavior), "Copies existing saga headers from incoming message to outgoing message to facilitate the auto correlation in the saga, when replying to a message that was sent by a saga."); coordinator.Register(WellKnownStep.CreatePhysicalMessage, typeof(CreatePhysicalMessageBehavior), "Converts a logical message into a physical message"); - coordinator.Register("FixSendIntent", typeof(FixSendIntentBehavior), "Fixes an issue where ReplyToOriginator isn't able to set the Reply message intent"); + coordinator.Register("FixSendIntent", typeof(FixSendIntentBehavior), "Fixes an issue where ReplyToOriginator isn't able to set the Reply message intent, breaking callbacks"); coordinator.Register(WellKnownStep.SerializeMessage, typeof(SerializeMessagesBehavior), "Serializes the message to be sent out on the wire"); coordinator.Register(WellKnownStep.MutateOutgoingTransportMessage, typeof(MutateOutgoingPhysicalMessageBehavior), "Executes IMutateOutgoingTransportMessages"); if (LogManager.GetLogger("LogOutgoingMessage").IsDebugEnabled)