public async Task Should_not_leak_state_when_request_canceled()
        {
            var dictionary = new ConcurrentDictionary<string, RequestResponseStateLookup.State>();
            var requestResponseStateLookup = new RequestResponseStateLookup(dictionary);

            var tcs = new TaskCompletionSource<object>();
            var adapter = new TaskCompletionSourceAdapter(tcs);
            var tokenSource = new CancellationTokenSource();
            var outgoingPhysicalMessageContext = new TestableOutgoingPhysicalMessageContext();
            outgoingPhysicalMessageContext.Extensions.Set(new RequestResponseStateLookup.State
            {
                CancellationToken = tokenSource.Token,
                TaskCompletionSource = adapter
            });

            var behavior = new UpdateRequestResponseCorrelationTableBehavior(requestResponseStateLookup);
            await behavior.Invoke(outgoingPhysicalMessageContext, () =>
            {
                tokenSource.Cancel();
                return Task.FromResult(0);
            });

            Assert.ThrowsAsync<TaskCanceledException>(async () => { await tcs.Task; });
            Assert.IsEmpty(dictionary);
        }
Exemple #2
0
        public async Task Should_start_and_log_activity()
        {
            var diagnosticListener = new DiagnosticListener("DummySource");
            var startCalled        = false;

            diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair =>
            {
                if (pair.Key == $"{ActivityNames.OutgoingPhysicalMessage}.Start")
                {
                    startCalled = true;
                    pair.Value.ShouldNotBeNull();
                    Activity.Current.ShouldNotBeNull();
                    Activity.Current.OperationName.ShouldBe(ActivityNames.OutgoingPhysicalMessage);
                    pair.Value.ShouldBeAssignableTo <IOutgoingPhysicalMessageContext>();
                }
            }));

            var context = new TestableOutgoingPhysicalMessageContext();

            var behavior = new OutgoingPhysicalMessageDiagnostics(diagnosticListener);

            await behavior.Invoke(context, () => Task.CompletedTask);

            startCalled.ShouldBeTrue();
        }
Exemple #3
0
        public async Task Should_fire_activity_start_stop_when_listener_attached()
        {
            var diagnosticListener = new DiagnosticListener("DummySource");
            var context            = new TestableOutgoingPhysicalMessageContext();
            var stopFired          = false;
            var startFired         = false;

            diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair =>
            {
                if (pair.Key == $"{ActivityNames.OutgoingPhysicalMessage}.Start")
                {
                    startFired = true;
                }

                if (pair.Key == $"{ActivityNames.OutgoingPhysicalMessage}.Stop")
                {
                    stopFired = true;
                }
            }));

            var behavior = new OutgoingPhysicalMessageDiagnostics(diagnosticListener);

            await behavior.Invoke(context, () => Task.CompletedTask);

            startFired.ShouldBeTrue();
            stopFired.ShouldBeTrue();
        }
        public async Task Should_start_and_log_activity()
        {
            var startCalled = false;

            using var listener = new ActivityListener
                  {
                      ShouldListenTo  = source => source.Name == "NServiceBus.Extensions.Diagnostics",
                      Sample          = (ref ActivityCreationOptions <ActivityContext> _) => ActivitySamplingResult.AllDataAndRecorded,
                      ActivityStarted = activity =>
                      {
                          startCalled = true;
                          activity.ShouldNotBeNull();
                          activity.OperationName.ShouldBe(ActivityNames.OutgoingPhysicalMessage);
                      },
                  };
            ActivitySource.AddActivityListener(listener);

            var context = new TestableOutgoingPhysicalMessageContext();

            var behavior = new OutgoingPhysicalMessageDiagnostics(new FakeActivityEnricher());

            await behavior.Invoke(context, () => Task.CompletedTask);

            startCalled.ShouldBeTrue();
        }
Exemple #5
0
        public async Task Should_add_headers_to_tags()
        {
            var diagnosticListener = new DiagnosticListener("DummySource");
            var startCalled        = false;

            diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair =>
            {
                if (pair.Key == $"{ActivityNames.OutgoingPhysicalMessage}.Start")
                {
                    startCalled = true;

                    var started = Activity.Current;
                    started.ShouldNotBeNull();
                    started.Tags.ShouldNotContain(kvp => kvp.Key == "foo");
                    started.Tags.ShouldContain(kvp => kvp.Key == "SomeHeader1" && kvp.Value == "SomeValue1");
                    started.Tags.ShouldContain(kvp => kvp.Key == "SomeHeader2" && kvp.Value == "SomeValue2");
                }
            }));

            var context = new TestableOutgoingPhysicalMessageContext
            {
                Headers =
                {
                    { "foo",                     "bar"        },
                    { "NServiceBus.SomeHeader1", "SomeValue1" },
                    { "NServiceBus.SomeHeader2", "SomeValue2" },
                }
            };

            var behavior = new OutgoingPhysicalMessageDiagnostics(diagnosticListener);

            await behavior.Invoke(context, () => Task.CompletedTask);

            startCalled.ShouldBeTrue();
        }
Exemple #6
0
        public async Task Should_not_leak_state_when_request_canceled()
        {
            var dictionary = new ConcurrentDictionary <string, RequestResponseStateLookup.State>();
            var requestResponseStateLookup = new RequestResponseStateLookup(dictionary);

            var tcs         = new TaskCompletionSource <object>();
            var adapter     = new TaskCompletionSourceAdapter <object>(tcs);
            var tokenSource = new CancellationTokenSource();
            var outgoingPhysicalMessageContext = new TestableOutgoingPhysicalMessageContext();

            outgoingPhysicalMessageContext.Extensions.Set(new RequestResponseStateLookup.State
            {
                CancellationToken    = tokenSource.Token,
                TaskCompletionSource = adapter
            });

            var behavior = new UpdateRequestResponseCorrelationTableBehavior(requestResponseStateLookup);
            await behavior.Invoke(outgoingPhysicalMessageContext, () =>
            {
                tokenSource.Cancel();
                return(Task.FromResult(0));
            });

            Assert.ThrowsAsync <TaskCanceledException>(async() => { await tcs.Task; });
            Assert.IsEmpty(dictionary);
        }
Exemple #7
0
        public async Task Should_set_the_conversation_id_to_new_guid_when_not_sent_from_handler()
        {
            var behavior = new AttachCausationHeadersBehavior();
            var context  = new TestableOutgoingPhysicalMessageContext();

            await behavior.Invoke(context, ctx => TaskEx.CompletedTask);

            Assert.AreNotEqual(Guid.Empty.ToString(), context.Headers[Headers.ConversationId]);
        }
Exemple #8
0
    public Task OutgoingPhysicalMessageContext()
    {
        var context = new TestableOutgoingPhysicalMessageContext
        {
            Body = new byte[] { 1 }
        };

        return(Verify(context));
    }
    public Task OutgoingPhysicalMessageContext()
    {
        var context = new TestableOutgoingPhysicalMessageContext
        {
            Body = new byte[] { 1 }
        };

        context.Extensions.Set("key", "value");
        return(Verify(context));
    }
        public void Should_throw_friendly_exception_when_IMutateOutgoingTransportMessages_MutateOutgoing_returns_null()
        {
            var behavior = new MutateOutgoingTransportMessageBehavior(hasOutgoingTransportMessageMutators: true);

            var physicalContext = new TestableOutgoingPhysicalMessageContext();
            physicalContext.Extensions.Set(new OutgoingLogicalMessage(typeof(FakeMessage), new FakeMessage()));
            physicalContext.Builder.Register<IMutateOutgoingTransportMessages>(() => new MutateOutgoingTransportMessagesReturnsNull());

            Assert.That(async () => await behavior.Invoke(physicalContext, ctx => TaskEx.CompletedTask), Throws.Exception.With.Message.EqualTo("Return a Task or mark the method as async."));
        }
        public void Should_throw_friendly_exception_when_IMutateOutgoingTransportMessages_MutateOutgoing_returns_null()
        {
            var behavior = new MutateOutgoingTransportMessageBehavior(hasOutgoingTransportMessageMutators: true);

            var physicalContext = new TestableOutgoingPhysicalMessageContext();

            physicalContext.Extensions.Set(new OutgoingLogicalMessage(typeof(FakeMessage), new FakeMessage()));
            physicalContext.Builder.Register <IMutateOutgoingTransportMessages>(() => new MutateOutgoingTransportMessagesReturnsNull());

            Assert.That(async() => await behavior.Invoke(physicalContext, ctx => TaskEx.CompletedTask), Throws.Exception.With.Message.EqualTo("Return a Task or mark the method as async."));
        }
Exemple #12
0
        public async Task Should_set_the_related_to_header_with_the_id_of_the_current_message()
        {
            var behavior = new AttachCausationHeadersBehavior();
            var context  = new TestableOutgoingPhysicalMessageContext();

            context.Extensions.Set(new IncomingMessage("the message id", new Dictionary <string, string>(), new byte[0]));

            await behavior.Invoke(context, ctx => TaskEx.CompletedTask);

            Assert.AreEqual("the message id", context.Headers[Headers.RelatedTo]);
        }
        public async Task Should_not_call_MutateOutgoing_when_hasOutgoingTransportMessageMutators_is_false()
        {
            var behavior = new MutateOutgoingTransportMessageBehavior(hasOutgoingTransportMessageMutators: false);

            var context = new TestableOutgoingPhysicalMessageContext();

            var mutator = new MutatorThatIndicatesIfItWasCalled();
            context.Builder.Register<IMutateOutgoingTransportMessages>(() => mutator);

            await behavior.Invoke(context, ctx => TaskEx.CompletedTask);

            Assert.IsFalse(mutator.MutateOutgoingCalled);
        }
        public async Task Should_not_call_MutateOutgoing_when_hasOutgoingTransportMessageMutators_is_false()
        {
            var behavior = new MutateOutgoingTransportMessageBehavior(hasOutgoingTransportMessageMutators: false);

            var context = new TestableOutgoingPhysicalMessageContext();

            var mutator = new MutatorThatIndicatesIfItWasCalled();

            context.Builder.Register <IMutateOutgoingTransportMessages>(() => mutator);

            await behavior.Invoke(context, ctx => TaskEx.CompletedTask);

            Assert.IsFalse(mutator.MutateOutgoingCalled);
        }
Exemple #15
0
        public async Task When_no_incoming_message_should_not_override_a_conversation_id_specified_by_the_user()
        {
            var userConversationId = Guid.NewGuid().ToString();

            var behavior = new AttachCausationHeadersBehavior();
            var context  = new TestableOutgoingPhysicalMessageContext
            {
                Headers =
                {
                    [Headers.ConversationId] = userConversationId
                }
            };

            await behavior.Invoke(context, ctx => TaskEx.CompletedTask);

            Assert.AreEqual(userConversationId, context.Headers[Headers.ConversationId]);
        }
        public async Task Should_not_call_MutateOutgoing_when_hasOutgoingTransportMessageMutators_is_false()
        {
            var behavior = new MutateOutgoingTransportMessageBehavior(new HashSet <IMutateOutgoingTransportMessages>());

            var physicalContext = new TestableOutgoingPhysicalMessageContext();

            physicalContext.Extensions.Set(new OutgoingLogicalMessage(typeof(FakeMessage), new FakeMessage()));

            await behavior.Invoke(physicalContext, ctx => Task.CompletedTask);

            var mutator = new MutatorThatIndicatesIfItWasCalled();

            physicalContext.Services.AddTransient <IMutateOutgoingTransportMessages>(sp => mutator);

            await behavior.Invoke(physicalContext, ctx => Task.CompletedTask);

            Assert.IsFalse(mutator.MutateOutgoingCalled);
        }
        public async Task Should_invoke_all_explicit_mutators()
        {
            var mutator      = new MutatorThatIndicatesIfItWasCalled();
            var otherMutator = new MutatorThatIndicatesIfItWasCalled();

            var behavior = new MutateOutgoingTransportMessageBehavior(new HashSet <IMutateOutgoingTransportMessages> {
                mutator, otherMutator
            });

            var physicalContext = new TestableOutgoingPhysicalMessageContext();

            physicalContext.Extensions.Set(new OutgoingLogicalMessage(typeof(FakeMessage), new FakeMessage()));

            await behavior.Invoke(physicalContext, ctx => Task.CompletedTask);

            Assert.True(mutator.MutateOutgoingCalled);
            Assert.True(otherMutator.MutateOutgoingCalled);
        }
Exemple #18
0
        public async Task Should_set_the_conversation_id_to_conversation_id_of_incoming_message()
        {
            var incomingConversationId = Guid.NewGuid().ToString();

            var behavior = new AttachCausationHeadersBehavior();
            var context  = new TestableOutgoingPhysicalMessageContext();

            var transportMessage = new IncomingMessage("xyz", new Dictionary <string, string>
            {
                { Headers.ConversationId, incomingConversationId }
            }, new byte[0]);

            context.Extensions.Set(transportMessage);

            await behavior.Invoke(context, ctx => TaskEx.CompletedTask);

            Assert.AreEqual(incomingConversationId, context.Headers[Headers.ConversationId]);
        }
        public async Task Should_invoke_both_explicit_and_container_provided_mutators()
        {
            var explicitMutator  = new MutatorThatIndicatesIfItWasCalled();
            var containerMutator = new MutatorThatIndicatesIfItWasCalled();

            var behavior = new MutateOutgoingTransportMessageBehavior(new HashSet <IMutateOutgoingTransportMessages> {
                explicitMutator
            });

            var physicalContext = new TestableOutgoingPhysicalMessageContext();

            physicalContext.Extensions.Set(new OutgoingLogicalMessage(typeof(FakeMessage), new FakeMessage()));
            physicalContext.Services.AddTransient <IMutateOutgoingTransportMessages>(sp => containerMutator);

            await behavior.Invoke(physicalContext, ctx => Task.CompletedTask);

            Assert.True(explicitMutator.MutateOutgoingCalled);
            Assert.True(containerMutator.MutateOutgoingCalled);
        }
        public async Task Should_not_fire_activity_start_stop_when_no_listener_attached()
        {
            var context    = new TestableOutgoingPhysicalMessageContext();
            var stopFired  = false;
            var startFired = false;

            using var listener = new ActivityListener
                  {
                      ShouldListenTo  = source => source.Name == "Nonsense",
                      ActivityStarted = _ => startFired = true,
                      ActivityStopped = _ => stopFired = true
                  };
            ActivitySource.AddActivityListener(listener);

            var behavior = new OutgoingPhysicalMessageDiagnostics(new FakeActivityEnricher());

            await behavior.Invoke(context, () => Task.CompletedTask);

            startFired.ShouldBeFalse();
            stopFired.ShouldBeFalse();
        }
        public async Task Should_start_activity_and_set_appropriate_headers()
        {
            // Generate an id we can use for the request id header (in the correct format)

            Activity started = null;

            using var listener = new ActivityListener
                  {
                      ShouldListenTo  = source => source.Name == "NServiceBus.Extensions.Diagnostics",
                      Sample          = (ref ActivityCreationOptions <ActivityContext> _) => ActivitySamplingResult.AllDataAndRecorded,
                      ActivityStarted = activity => started = activity,
                  };
            ActivitySource.AddActivityListener(listener);

            var context = new TestableOutgoingPhysicalMessageContext();

            var behavior = new OutgoingPhysicalMessageDiagnostics(new FakeActivityEnricher());

            var outerActivity = new Activity("Outer")
            {
                TraceStateString = "TraceStateValue",
            };

            outerActivity.AddBaggage("Key1", "Value1");
            outerActivity.AddBaggage("Key2", "Value2");
            outerActivity.Start();

            await behavior.Invoke(context, () => Task.CompletedTask);

            outerActivity.Stop();

            started.ShouldNotBeNull();
            started.ParentId.ShouldBe(outerActivity.Id);

            context.Headers.ShouldContain(kvp => kvp.Key == "traceparent" && kvp.Value == started.Id);
            context.Headers.ShouldContain(kvp => kvp.Key == "tracestate" && kvp.Value == outerActivity.TraceStateString);
            context.Headers.ShouldContain(kvp => kvp.Key == "Correlation-Context" && kvp.Value == "Key2=Value2,Key1=Value1");
            context.Headers.ShouldContain(kvp => kvp.Key == "baggage" && kvp.Value == "Key2=Value2,Key1=Value1");
        }
Exemple #22
0
        public async Task Should_start_activity_and_set_appropriate_headers()
        {
            // Generate an id we can use for the request id header (in the correct format)

            var      diagnosticListener = new DiagnosticListener("DummySource");
            Activity started            = null;

            diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair =>
            {
                if (pair.Key == $"{ActivityNames.OutgoingPhysicalMessage}.Start")
                {
                    started = Activity.Current;
                }
            }));

            var context = new TestableOutgoingPhysicalMessageContext();

            var behavior = new OutgoingPhysicalMessageDiagnostics(diagnosticListener);

            var activity = new Activity("Outer")
            {
                TraceStateString = "TraceStateValue",
            };

            activity.AddBaggage("Key1", "Value1");
            activity.AddBaggage("Key2", "Value2");
            activity.Start();

            await behavior.Invoke(context, () => Task.CompletedTask);

            activity.Stop();

            started.ShouldNotBeNull();
            started.ParentId.ShouldBe(activity.Id);

            context.Headers.ShouldContain(kvp => kvp.Key == "traceparent" && kvp.Value == started.Id);
            context.Headers.ShouldContain(kvp => kvp.Key == "tracestate" && kvp.Value == activity.TraceStateString);
            context.Headers.ShouldContain(kvp => kvp.Key == "Correlation-Context" && kvp.Value == "Key2=Value2,Key1=Value1");
        }
        public async Task Should_fire_activity_start_stop_when_listener_attached()
        {
            var context    = new TestableOutgoingPhysicalMessageContext();
            var stopFired  = false;
            var startFired = false;

            using var listener = new ActivityListener
                  {
                      ShouldListenTo  = source => source.Name == "NServiceBus.Extensions.Diagnostics",
                      Sample          = (ref ActivityCreationOptions <ActivityContext> _) => ActivitySamplingResult.AllDataAndRecorded,
                      ActivityStarted = _ => startFired = true,
                      ActivityStopped = _ => stopFired = true
                  };
            ActivitySource.AddActivityListener(listener);

            var behavior = new OutgoingPhysicalMessageDiagnostics(new FakeActivityEnricher());

            await behavior.Invoke(context, () => Task.CompletedTask);

            startFired.ShouldBeTrue();
            stopFired.ShouldBeTrue();
        }
Exemple #24
0
        public void When_user_defined_conversation_id_would_overwrite_incoming_conversation_id_should_throw()
        {
            var incomingConversationId    = Guid.NewGuid().ToString();
            var userDefinedConversationId = Guid.NewGuid().ToString();

            var behavior = new AttachCausationHeadersBehavior();
            var context  = new TestableOutgoingPhysicalMessageContext
            {
                Headers =
                {
                    [Headers.ConversationId] = userDefinedConversationId
                }
            };
            var transportMessage = new IncomingMessage("xyz", new Dictionary <string, string>
            {
                { Headers.ConversationId, incomingConversationId }
            }, new byte[0]);

            context.Extensions.Set(transportMessage);

            var exception = Assert.ThrowsAsync <Exception>(() => behavior.Invoke(context, ctx => TaskEx.CompletedTask));

            Assert.AreEqual($"Cannot set the {Headers.ConversationId} header to '{userDefinedConversationId}' as it cannot override the incoming header value ('{incomingConversationId}').", exception.Message);
        }